You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by il...@apache.org on 2014/04/15 13:54:32 UTC

git commit: [OLINGO-175] Contained entity update tests (V4)

Repository: olingo-odata4
Updated Branches:
  refs/heads/master d5e29b020 -> e67cbaa30


[OLINGO-175] Contained entity update tests (V4)


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/e67cbaa3
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/e67cbaa3
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/e67cbaa3

Branch: refs/heads/master
Commit: e67cbaa308ce650d9ec8a9e098c8401e596f9f37
Parents: d5e29b0
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Apr 15 13:54:23 2014 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue Apr 15 13:54:23 2014 +0200

----------------------------------------------------------------------
 .../org/apache/olingo/fit/AbstractServices.java |  41 +----
 .../java/org/apache/olingo/fit/V4Services.java  | 171 ++++++++++++++++++-
 .../olingo/fit/utils/AbstractUtilities.java     |   9 +-
 .../org/apache/olingo/fit/utils/DataBinder.java |   6 +-
 .../resources/V40/Accounts/101/entity.full.json |  34 ++++
 .../main/resources/V40/Accounts/101/entity.xml  |  46 +++++
 .../MyPaymentInstruments(101901).full.json      |  16 ++
 .../101/links/MyPaymentInstruments(101901).xml  |  40 +++++
 .../101/links/MyPaymentInstruments.full.json    |  62 +++++++
 .../Accounts/101/links/MyPaymentInstruments.xml |  95 +++++++++++
 .../olingo/client/api/CommonODataClient.java    |   3 +
 .../request/cud/CommonCUDRequestFactory.java    |   6 +-
 .../request/cud/ODataEntityUpdateRequest.java   |   6 +-
 .../request/cud/v4/CUDRequestFactory.java       |  13 --
 .../response/ODataEntityUpdateResponse.java     |   5 +-
 .../olingo/client/core/AbstractODataClient.java |   7 +
 .../request/AbstractODataBasicRequest.java      |   2 +-
 .../communication/request/ODataRequestImpl.java |   6 +-
 .../request/cud/AbstractCUDRequestFactory.java  |  20 ++-
 .../cud/ODataEntityUpdateRequestImpl.java       |  27 +--
 .../request/cud/v4/CUDRequestFactoryImpl.java   |  11 --
 .../client/core/it/v3/AbstractTestITCase.java   |   6 +-
 .../client/core/it/v3/AsyncTestITCase.java      |   6 +-
 .../core/it/v3/EntityCreateTestITCase.java      |   6 +-
 .../core/it/v3/EntityUpdateTestITCase.java      |  13 +-
 .../core/it/v4/EntityRetrieveTestITCase.java    |  48 ++++--
 .../core/it/v4/EntityUpdateTestITCase.java      |  39 ++++-
 27 files changed, 613 insertions(+), 131 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
index 01a5326..00e22f3 100644
--- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
+++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
@@ -67,7 +67,6 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
-import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.commons.api.data.Entry;
@@ -175,41 +174,6 @@ public abstract class AbstractServices {
     }
   }
 
-  /**
-   * Retrieve entity reference sample.
-   *
-   * @param accept Accept header.
-   * @param path path.
-   * @param format format query option.
-   * @return entity reference or feed of entity reference.
-   */
-  @GET
-  @Path("/{path:.*}/$ref")
-  public Response getEntityReference(
-          @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
-          @PathParam("path") String path,
-          @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) {
-
-    try {
-      final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
-
-      if (utils.getKey() == Accept.TEXT) {
-        throw new UnsupportedMediaTypeException("Unsupported media type");
-      }
-
-      final String filename = Base64.encodeBase64String(path.getBytes("UTF-8"));
-
-      return utils.getValue().createResponse(
-              FSManager.instance(version).readFile(Constants.get(version, ConstantKey.REF)
-                      + File.separatorChar + filename, utils.getKey()),
-              null,
-              utils.getKey());
-    } catch (Exception e) {
-      LOG.error("Error retrieving entity", e);
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
   @MERGE
   @Path("/{entitySetName}({entityId})")
   @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
@@ -704,11 +668,8 @@ public abstract class AbstractServices {
    * Retrieve entity with key as segment.
    *
    * @param accept Accept header.
-   * @param entitySetName Entity set name.
    * @param entityId entity id.
    * @param format format query option.
-   * @param expand expand query option.
-   * @param select select query option.
    * @return entity.
    */
   @GET
@@ -1410,7 +1371,7 @@ public abstract class AbstractServices {
     return utils;
   }
 
-  private void normalizeAtomEntry(final AtomEntryImpl entry, final String entitySetName, final String entityKey) {
+  protected void normalizeAtomEntry(final AtomEntryImpl entry, final String entitySetName, final String entityKey) {
     final EntitySet entitySet = getMetadataObj().getEntitySet(entitySetName);
     final EntityType entityType = getMetadataObj().getEntityType(entitySet.getType());
     for (Map.Entry<String, org.apache.olingo.fit.metadata.Property> property

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/fit/src/main/java/org/apache/olingo/fit/V4Services.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/V4Services.java b/fit/src/main/java/org/apache/olingo/fit/V4Services.java
index 28fbebd..651ae85 100644
--- a/fit/src/main/java/org/apache/olingo/fit/V4Services.java
+++ b/fit/src/main/java/org/apache/olingo/fit/V4Services.java
@@ -18,14 +18,40 @@
  */
 package org.apache.olingo.fit;
 
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.File;
+import java.util.Map;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
 import javax.ws.rs.NotFoundException;
 import org.apache.olingo.fit.utils.XHTTPMethodInterceptor;
 import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.cxf.interceptor.InInterceptors;
+import org.apache.olingo.commons.api.data.Container;
 import org.apache.olingo.commons.api.data.Feed;
+import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.commons.core.data.AtomEntryImpl;
+import org.apache.olingo.commons.core.data.JSONEntryImpl;
+import org.apache.olingo.commons.core.edm.EdmTypeInfo;
+import org.apache.olingo.fit.methods.PATCH;
+import org.apache.olingo.fit.serializer.FITAtomDeserializer;
+import org.apache.olingo.fit.utils.AbstractUtilities;
+import org.apache.olingo.fit.utils.Accept;
+import org.apache.olingo.fit.utils.Commons;
+import org.apache.olingo.fit.utils.ConstantKey;
+import org.apache.olingo.fit.utils.Constants;
+import org.apache.olingo.fit.utils.DataBinder;
+import org.apache.olingo.fit.utils.FSManager;
+import org.apache.olingo.fit.utils.LinkInfo;
 import org.apache.olingo.fit.utils.ResolvingReferencesInterceptor;
 import org.springframework.stereotype.Service;
 
@@ -45,6 +71,41 @@ public class V4Services extends AbstractServices {
     }
   }
 
+  /**
+   * Retrieve entity reference sample.
+   *
+   * @param accept Accept header.
+   * @param path path.
+   * @param format format query option.
+   * @return entity reference or feed of entity reference.
+   */
+  @GET
+  @Path("/{path:.*}/$ref")
+  public Response getEntityReference(
+          @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
+          @PathParam("path") String path,
+          @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) {
+
+    try {
+      final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+      if (utils.getKey() == Accept.TEXT) {
+        throw new UnsupportedMediaTypeException("Unsupported media type");
+      }
+
+      final String filename = Base64.encodeBase64String(path.getBytes("UTF-8"));
+
+      return utils.getValue().createResponse(
+              FSManager.instance(version).readFile(Constants.get(version, ConstantKey.REF)
+                      + File.separatorChar + filename, utils.getKey()),
+              null,
+              utils.getKey());
+    } catch (Exception e) {
+      LOG.error("Error retrieving entity", e);
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
   @Override
   public Response patchEntity(
           final String accept,
@@ -52,7 +113,7 @@ public class V4Services extends AbstractServices {
           final String prefer,
           final String ifMatch,
           final String entitySetName,
-          final String entityId, 
+          final String entityId,
           final String changes) {
 
     final Response response =
@@ -79,4 +140,112 @@ public class V4Services extends AbstractServices {
     }
   }
 
+  @GET
+  @Path("/{entitySetName}({entityId})/{containedEntitySetName}({containedEntityId})")
+  public Response getContainedEntity(
+          @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
+          @PathParam("entitySetName") String entitySetName,
+          @PathParam("entityId") String entityId,
+          @PathParam("containedEntitySetName") String containedEntitySetName,
+          @PathParam("containedEntityId") String containedEntityId,
+          @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format) {
+
+    try {
+      final Accept acceptType;
+      if (StringUtils.isNotBlank(format)) {
+        acceptType = Accept.valueOf(format.toUpperCase());
+      } else {
+        acceptType = Accept.parse(accept, version);
+      }
+
+      if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+        throw new UnsupportedMediaTypeException("Unsupported media type");
+      }
+
+      final LinkInfo links = xml.readLinks(
+              entitySetName, entityId, containedEntitySetName + "(" + containedEntityId + ")", acceptType);
+
+      return xml.createResponse(
+              links.getLinks(),
+              links.getEtag(),
+              acceptType);
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  @PATCH
+  @Path("/{entitySetName}({entityId})/{containedEntitySetName}({containedEntityId})")
+  public Response patchContainedEntity(
+          @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept,
+          @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) String contentType,
+          @PathParam("entitySetName") String entitySetName,
+          @PathParam("entityId") String entityId,
+          @PathParam("containedEntitySetName") String containedEntitySetName,
+          @PathParam("containedEntityId") String containedEntityId,
+          @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format,
+          final String changes) {
+
+    try {
+      final Accept acceptType;
+      if (StringUtils.isNotBlank(format)) {
+        acceptType = Accept.valueOf(format.toUpperCase());
+      } else {
+        acceptType = Accept.parse(accept, version);
+      }
+      if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+        throw new UnsupportedMediaTypeException("Unsupported media type");
+      }
+
+      final Accept contentTypeValue;
+      if (StringUtils.isBlank(contentType)) {
+        throw new IllegalArgumentException();
+      }
+      contentTypeValue = Accept.parse(contentType, version);
+
+      final LinkInfo links = xml.readLinks(
+              entitySetName, entityId, containedEntitySetName + "(" + containedEntityId + ")", Accept.ATOM);
+
+      final FITAtomDeserializer atomDeserializer = Commons.getAtomDeserializer(version);
+      Container<AtomEntryImpl> container = atomDeserializer.read(links.getLinks(), AtomEntryImpl.class);
+      final AtomEntryImpl original = container.getObject();
+
+      final AtomEntryImpl entryChanges;
+      if (Accept.ATOM == contentTypeValue) {
+        container = atomDeserializer.read(IOUtils.toInputStream(changes), AtomEntryImpl.class);
+        entryChanges = container.getObject();
+      } else {
+        final String entityType = getMetadataObj().getEntitySet(entitySetName).getType();
+        final String containedType = getMetadataObj().getEntityType(entityType).
+                getNavigationProperty(containedEntitySetName).getType();
+        final EdmTypeInfo typeInfo = new EdmTypeInfo.Builder().setTypeExpression(containedType).build();
+
+        final ObjectMapper mapper = Commons.getJsonMapper(version);
+        final DataBinder dataBinder = new DataBinder(version);
+
+        Container<JSONEntryImpl> jsonContainer = mapper.readValue(IOUtils.toInputStream(changes),
+                new TypeReference<JSONEntryImpl>() {
+                });
+        jsonContainer.getObject().setType(typeInfo.getFullQualifiedName().toString());
+        entryChanges = dataBinder.getAtomEntry(jsonContainer.getObject());
+      }
+
+      for (Property property : entryChanges.getProperties()) {
+        final Property old = original.getProperty(property.getName());
+        if (old != null) {
+          original.getProperties().remove(old);
+        }
+        original.getProperties().add(property);
+      }
+
+      FSManager.instance(version).putInMemory(new Container<AtomEntryImpl>(null, null, original),
+              xml.getLinksBasePath(entitySetName, entityId) + containedEntitySetName + "(" + containedEntityId + ")");
+
+      return xml.createResponse(null, null, acceptType, Response.Status.NO_CONTENT);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
index 154e297..9c0ef94 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
@@ -662,6 +662,11 @@ public abstract class AbstractUtilities {
     return res;
   }
 
+  public String getLinksBasePath(final String entitySetName, final String entityId) {
+            return entitySetName + File.separatorChar + Commons.getEntityKey(entityId) + File.separatorChar
+            + Constants.get(version, ConstantKey.LINKS_FILE_PATH) + File.separatorChar;    
+  }
+  
   /**
    * Retrieves entity links about the given link name.
    *
@@ -675,9 +680,7 @@ public abstract class AbstractUtilities {
           final String entitySetName, final String entityId, final String linkName, final Accept accept)
           throws Exception {
 
-    final String basePath =
-            entitySetName + File.separatorChar + Commons.getEntityKey(entityId) + File.separatorChar
-            + Constants.get(version, ConstantKey.LINKS_FILE_PATH) + File.separatorChar;
+    final String basePath = getLinksBasePath(entitySetName, entityId);
 
     final LinkInfo linkInfo = new LinkInfo(fsManager.readFile(basePath + linkName, accept));
     linkInfo.setEtag(Commons.getETag(basePath, version));

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/fit/src/main/java/org/apache/olingo/fit/utils/DataBinder.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/DataBinder.java b/fit/src/main/java/org/apache/olingo/fit/utils/DataBinder.java
index a305e04..b984c32 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/DataBinder.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/DataBinder.java
@@ -91,7 +91,6 @@ public class DataBinder {
     jsonentry.setBaseURI(atomentry.getBaseURI() == null ? null : atomentry.getBaseURI().toASCIIString());
 
     for (Link link : atomentry.getNavigationLinks()) {
-
       final Link jlink = new LinkImpl();
       jlink.setHref(link.getHref());
       jlink.setTitle(link.getTitle());
@@ -99,13 +98,12 @@ public class DataBinder {
       jlink.setRel(link.getRel());
 
       if (link.getInlineEntry() instanceof AtomEntryImpl) {
-        Entry inlineEntry = link.getInlineEntry();
+        final Entry inlineEntry = link.getInlineEntry();
         if (inlineEntry instanceof AtomEntryImpl) {
           jlink.setInlineEntry(getJsonEntry((AtomEntryImpl) link.getInlineEntry()));
         }
       } else if (link.getInlineFeed() instanceof AtomFeedImpl) {
-
-        Feed inlineFeed = link.getInlineFeed();
+        final Feed inlineFeed = link.getInlineFeed();
         if (inlineFeed instanceof AtomFeedImpl) {
           jlink.setInlineFeed(getJsonFeed((AtomFeedImpl) link.getInlineFeed()));
         }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/fit/src/main/resources/V40/Accounts/101/entity.full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/Accounts/101/entity.full.json b/fit/src/main/resources/V40/Accounts/101/entity.full.json
new file mode 100644
index 0000000..4157fa7
--- /dev/null
+++ b/fit/src/main/resources/V40/Accounts/101/entity.full.json
@@ -0,0 +1,34 @@
+{
+  "@odata.context": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/$metadata#Accounts/$entity",
+  "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.Account",
+  "@odata.id": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)",
+  "@odata.editLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)",
+  "AccountID": 101,
+  "Country": "US",
+  "AccountInfo": {
+    "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.AccountInfo",
+    "FirstName": "Alex",
+    "LastName": "Green",
+    "MiddleName": "Hood"
+  },
+  "MyGiftCard@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyGiftCard/$ref",
+  "MyGiftCard@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyGiftCard",
+  "MyPaymentInstruments@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments/$ref",
+  "MyPaymentInstruments@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments",
+  "ActiveSubscriptions@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/ActiveSubscriptions/$ref",
+  "ActiveSubscriptions@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/ActiveSubscriptions",
+  "AvailableSubscriptionTemplatess@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/AvailableSubscriptionTemplatess/$ref",
+  "AvailableSubscriptionTemplatess@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/AvailableSubscriptionTemplatess",
+  "#Microsoft.Test.OData.Services.ODataWCFService.RefreshDefaultPI": {
+    "title": "Microsoft.Test.OData.Services.ODataWCFService.RefreshDefaultPI",
+    "target": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/Microsoft.Test.OData.Services.ODataWCFService.RefreshDefaultPI"
+  },
+  "#Microsoft.Test.OData.Services.ODataWCFService.GetDefaultPI": {
+    "title": "Microsoft.Test.OData.Services.ODataWCFService.GetDefaultPI",
+    "target": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/Microsoft.Test.OData.Services.ODataWCFService.GetDefaultPI"
+  },
+  "#Microsoft.Test.OData.Services.ODataWCFService.GetAccountInfo": {
+    "title": "Microsoft.Test.OData.Services.ODataWCFService.GetAccountInfo",
+    "target": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/Microsoft.Test.OData.Services.ODataWCFService.GetAccountInfo"
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/fit/src/main/resources/V40/Accounts/101/entity.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/Accounts/101/entity.xml b/fit/src/main/resources/V40/Accounts/101/entity.xml
new file mode 100644
index 0000000..4d989e4
--- /dev/null
+++ b/fit/src/main/resources/V40/Accounts/101/entity.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<entry xml:base="http://odatae2etest.azurewebsites.net/javatest/DefaultService/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:context="http://odatae2etest.azurewebsites.net/javatest/DefaultService/$metadata#Accounts/$entity">
+  <id>http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)</id>
+  <category term="#Microsoft.Test.OData.Services.ODataWCFService.Account" scheme="http://docs.oasis-open.org/odata/ns/scheme"/>
+  <link rel="edit" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)"/>
+  <link rel="http://docs.oasis-open.org/odata/ns/related/MyGiftCard" type="application/atom+xml;type=entry" title="MyGiftCard" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyGiftCard"/>
+  <link rel="http://docs.oasis-open.org/odata/ns/related/MyPaymentInstruments" type="application/atom+xml;type=feed" title="MyPaymentInstruments" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments"/>
+  <link rel="http://docs.oasis-open.org/odata/ns/related/ActiveSubscriptions" type="application/atom+xml;type=feed" title="ActiveSubscriptions" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/ActiveSubscriptions"/>
+  <link rel="http://docs.oasis-open.org/odata/ns/related/AvailableSubscriptionTemplatess" type="application/atom+xml;type=feed" title="AvailableSubscriptionTemplatess" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/AvailableSubscriptionTemplatess"/>
+  <title/>
+  <updated>2014-04-14T12:45:00Z</updated>
+  <author>
+    <name/>
+  </author>
+  <content type="application/xml">
+    <m:properties>
+      <d:AccountID m:type="Int32">101</d:AccountID>
+      <d:Country>US</d:Country>
+      <d:AccountInfo m:type="#Microsoft.Test.OData.Services.ODataWCFService.AccountInfo">
+        <d:FirstName>Alex</d:FirstName>
+        <d:LastName>Green</d:LastName>
+        <d:MiddleName>Hood</d:MiddleName>
+      </d:AccountInfo>
+    </m:properties>
+  </content>
+</entry>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101901).full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101901).full.json b/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101901).full.json
new file mode 100644
index 0000000..602e3a9
--- /dev/null
+++ b/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101901).full.json
@@ -0,0 +1,16 @@
+{
+  "@odata.context": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/$metadata#Accounts(101)/MyPaymentInstruments/$entity",
+  "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument",
+  "@odata.id": "Accounts(101)/MyPaymentInstruments(101901)",
+  "@odata.editLink": "Accounts(101)/MyPaymentInstruments(101901)",
+  "PaymentInstrumentID": 101901,
+  "FriendlyName": "101 first PI",
+  "CreatedDate@odata.type": "#DateTimeOffset",
+  "CreatedDate": "2014-04-09T00:00:00Z",
+  "TheStoredPI@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/TheStoredPI/$ref",
+  "TheStoredPI@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/TheStoredPI",
+  "BillingStatements@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/BillingStatements/$ref",
+  "BillingStatements@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/BillingStatements",
+  "BackupStoredPI@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/BackupStoredPI/$ref",
+  "BackupStoredPI@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/BackupStoredPI"
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101901).xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101901).xml b/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101901).xml
new file mode 100644
index 0000000..f1002ba
--- /dev/null
+++ b/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments(101901).xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<entry xml:base="http://odatae2etest.azurewebsites.net/javatest/DefaultService/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:context="http://odatae2etest.azurewebsites.net/javatest/DefaultService/$metadata#Accounts(101)/MyPaymentInstruments/$entity">
+  <category term="#Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument" scheme="http://docs.oasis-open.org/odata/ns/scheme"/>
+  <link rel="http://docs.oasis-open.org/odata/ns/related/TheStoredPI" type="application/atom+xml;type=entry" title="TheStoredPI" href="potato"/>
+  <link rel="http://docs.oasis-open.org/odata/ns/related/BillingStatements" type="application/atom+xml;type=feed" title="BillingStatements" href="potato"/>
+  <link rel="http://docs.oasis-open.org/odata/ns/related/BackupStoredPI" type="application/atom+xml;type=entry" title="BackupStoredPI" href="potato"/>
+  <id/>
+  <title/>
+  <updated>2014-04-14T12:47:37Z</updated>
+  <author>
+    <name/>
+  </author>
+  <content type="application/xml">
+    <m:properties>
+      <d:PaymentInstrumentID m:type="Int32">101901</d:PaymentInstrumentID>
+      <d:FriendlyName>101 first PI</d:FriendlyName>
+      <d:CreatedDate m:type="DateTimeOffset">2014-04-09T00:00:00Z</d:CreatedDate>
+    </m:properties>
+  </content>
+</entry>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments.full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments.full.json b/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments.full.json
new file mode 100644
index 0000000..700ea69
--- /dev/null
+++ b/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments.full.json
@@ -0,0 +1,62 @@
+{
+  "@odata.context": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/$metadata#Accounts(101)/MyPaymentInstruments",
+  "value": [{
+      "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument",
+      "@odata.id": "Accounts(101)/MyPaymentInstruments(101901)",
+      "@odata.editLink": "Accounts(101)/MyPaymentInstruments(101901)",
+      "PaymentInstrumentID": 101901,
+      "FriendlyName": "101 first PI",
+      "CreatedDate@odata.type": "#DateTimeOffset",
+      "CreatedDate": "2014-04-09T00:00:00Z",
+      "TheStoredPI@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/TheStoredPI/$ref",
+      "TheStoredPI@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/TheStoredPI",
+      "BillingStatements@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/BillingStatements/$ref",
+      "BillingStatements@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/BillingStatements",
+      "BackupStoredPI@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/BackupStoredPI/$ref",
+      "BackupStoredPI@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101901)/BackupStoredPI"
+    }, {
+      "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI",
+      "@odata.id": "Accounts(101)/MyPaymentInstruments(101902)",
+      "@odata.editLink": "Accounts(101)/MyPaymentInstruments(101902)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI",
+      "PaymentInstrumentID": 101902,
+      "FriendlyName": "101 frist credit PI",
+      "CreatedDate@odata.type": "#DateTimeOffset",
+      "CreatedDate": "2012-11-01T00:00:00Z",
+      "CardNumber": "6000000000000000",
+      "CVV": "234",
+      "HolderName": "Alex",
+      "Balance": 100.0,
+      "ExperationDate@odata.type": "#DateTimeOffset",
+      "ExperationDate": "2022-11-01T00:00:00Z",
+      "TheStoredPI@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101902)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/TheStoredPI/$ref",
+      "TheStoredPI@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101902)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/TheStoredPI",
+      "BillingStatements@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101902)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/BillingStatements/$ref",
+      "BillingStatements@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101902)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/BillingStatements",
+      "BackupStoredPI@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101902)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/BackupStoredPI/$ref",
+      "BackupStoredPI@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101902)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/BackupStoredPI",
+      "CreditRecords@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101902)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/CreditRecords/$ref",
+      "CreditRecords@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101902)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/CreditRecords"
+    }, {
+      "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI",
+      "@odata.id": "Accounts(101)/MyPaymentInstruments(101903)",
+      "@odata.editLink": "Accounts(101)/MyPaymentInstruments(101903)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI",
+      "PaymentInstrumentID": 101903,
+      "FriendlyName": "101 second credit PI",
+      "CreatedDate@odata.type": "#DateTimeOffset",
+      "CreatedDate": "2012-11-01T00:00:00Z",
+      "CardNumber": "8000000000000000",
+      "CVV": "012",
+      "HolderName": "James",
+      "Balance": 300.0,
+      "ExperationDate@odata.type": "#DateTimeOffset",
+      "ExperationDate": "2022-10-02T00:00:00Z",
+      "TheStoredPI@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101903)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/TheStoredPI/$ref",
+      "TheStoredPI@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101903)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/TheStoredPI",
+      "BillingStatements@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101903)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/BillingStatements/$ref",
+      "BillingStatements@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101903)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/BillingStatements",
+      "BackupStoredPI@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101903)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/BackupStoredPI/$ref",
+      "BackupStoredPI@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101903)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/BackupStoredPI",
+      "CreditRecords@odata.associationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101903)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/CreditRecords/$ref",
+      "CreditRecords@odata.navigationLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Accounts(101)/MyPaymentInstruments(101903)/Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI/CreditRecords"
+    }]
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments.xml b/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments.xml
new file mode 100644
index 0000000..5593a7a
--- /dev/null
+++ b/fit/src/main/resources/V40/Accounts/101/links/MyPaymentInstruments.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<feed xml:base="http://odatae2etest.azurewebsites.net/javatest/DefaultService/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:context="http://odatae2etest.azurewebsites.net/javatest/DefaultService/$metadata#Accounts(101)/MyPaymentInstruments">
+  <id>http://odatae2etest.azurewebsites.net/javatest/DefaultService/MyPaymentInstruments</id>
+  <title/>
+  <updated>2014-04-14T12:45:33Z</updated>
+  <entry>
+    <category term="#Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument" scheme="http://docs.oasis-open.org/odata/ns/scheme"/>
+    <link rel="http://docs.oasis-open.org/odata/ns/related/TheStoredPI" type="application/atom+xml;type=entry" title="TheStoredPI" href="potato"/>
+    <link rel="http://docs.oasis-open.org/odata/ns/related/BillingStatements" type="application/atom+xml;type=feed" title="BillingStatements" href="potato"/>
+    <link rel="http://docs.oasis-open.org/odata/ns/related/BackupStoredPI" type="application/atom+xml;type=entry" title="BackupStoredPI" href="potato"/>
+    <id/>
+    <title/>
+    <updated>2014-04-14T12:45:33Z</updated>
+    <author>
+      <name/>
+    </author>
+    <content type="application/xml">
+      <m:properties>
+        <d:PaymentInstrumentID m:type="Int32">101901</d:PaymentInstrumentID>
+        <d:FriendlyName>101 first PI</d:FriendlyName>
+        <d:CreatedDate m:type="DateTimeOffset">2014-04-09T00:00:00Z</d:CreatedDate>
+      </m:properties>
+    </content>
+  </entry>
+  <entry>
+    <category term="#Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI" scheme="http://docs.oasis-open.org/odata/ns/scheme"/>
+    <link rel="http://docs.oasis-open.org/odata/ns/related/TheStoredPI" type="application/atom+xml;type=entry" title="TheStoredPI" href="potato"/>
+    <link rel="http://docs.oasis-open.org/odata/ns/related/BillingStatements" type="application/atom+xml;type=feed" title="BillingStatements" href="potato"/>
+    <link rel="http://docs.oasis-open.org/odata/ns/related/BackupStoredPI" type="application/atom+xml;type=entry" title="BackupStoredPI" href="potato"/>
+    <link rel="http://docs.oasis-open.org/odata/ns/related/CreditRecords" type="application/atom+xml;type=feed" title="CreditRecords" href="potato"/>
+    <id/>
+    <title/>
+    <updated>2014-04-14T12:45:33Z</updated>
+    <author>
+      <name/>
+    </author>
+    <content type="application/xml">
+      <m:properties>
+        <d:PaymentInstrumentID m:type="Int32">101902</d:PaymentInstrumentID>
+        <d:FriendlyName>101 frist credit PI</d:FriendlyName>
+        <d:CreatedDate m:type="DateTimeOffset">2012-11-01T00:00:00Z</d:CreatedDate>
+        <d:CardNumber>6000000000000000</d:CardNumber>
+        <d:CVV>234</d:CVV>
+        <d:HolderName>Alex</d:HolderName>
+        <d:Balance m:type="Double">100</d:Balance>
+        <d:ExperationDate m:type="DateTimeOffset">2022-11-01T00:00:00Z</d:ExperationDate>
+      </m:properties>
+    </content>
+  </entry>
+  <entry>
+    <category term="#Microsoft.Test.OData.Services.ODataWCFService.CreditCardPI" scheme="http://docs.oasis-open.org/odata/ns/scheme"/>
+    <link rel="http://docs.oasis-open.org/odata/ns/related/TheStoredPI" type="application/atom+xml;type=entry" title="TheStoredPI" href="potato"/>
+    <link rel="http://docs.oasis-open.org/odata/ns/related/BillingStatements" type="application/atom+xml;type=feed" title="BillingStatements" href="potato"/>
+    <link rel="http://docs.oasis-open.org/odata/ns/related/BackupStoredPI" type="application/atom+xml;type=entry" title="BackupStoredPI" href="potato"/>
+    <link rel="http://docs.oasis-open.org/odata/ns/related/CreditRecords" type="application/atom+xml;type=feed" title="CreditRecords" href="potato"/>
+    <id/>
+    <title/>
+    <updated>2014-04-14T12:45:33Z</updated>
+    <author>
+      <name/>
+    </author>
+    <content type="application/xml">
+      <m:properties>
+        <d:PaymentInstrumentID m:type="Int32">101903</d:PaymentInstrumentID>
+        <d:FriendlyName>101 second credit PI</d:FriendlyName>
+        <d:CreatedDate m:type="DateTimeOffset">2012-11-01T00:00:00Z</d:CreatedDate>
+        <d:CardNumber>8000000000000000</d:CardNumber>
+        <d:CVV>012</d:CVV>
+        <d:HolderName>James</d:HolderName>
+        <d:Balance m:type="Double">300</d:Balance>
+        <d:ExperationDate m:type="DateTimeOffset">2022-10-02T00:00:00Z</d:ExperationDate>
+      </m:properties>
+    </content>
+  </entry>
+</feed>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonODataClient.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonODataClient.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonODataClient.java
index dbc44d8..b3a4427 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonODataClient.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonODataClient.java
@@ -19,6 +19,7 @@
 package org.apache.olingo.client.api;
 
 import org.apache.olingo.client.api.communication.header.ODataHeaders;
+import org.apache.olingo.client.api.communication.header.ODataPreferences;
 import org.apache.olingo.client.api.communication.request.batch.CommonBatchRequestFactory;
 import org.apache.olingo.client.api.communication.request.cud.CommonCUDRequestFactory;
 import org.apache.olingo.client.api.communication.request.cud.CommonUpdateType;
@@ -43,6 +44,8 @@ public interface CommonODataClient<UT extends CommonUpdateType> {
 
   CommonConfiguration getConfiguration();
 
+  ODataPreferences newPreferences();
+
   CommonURIBuilder<?> getURIBuilder(String serviceRoot);
 
   CommonFilterFactory getFilterFactory();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/CommonCUDRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/CommonCUDRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/CommonCUDRequestFactory.java
index 71cf1cf..ac09277 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/CommonCUDRequestFactory.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/CommonCUDRequestFactory.java
@@ -46,21 +46,23 @@ public interface CommonCUDRequestFactory<UT extends CommonUpdateType> extends Se
   /**
    * Gets an update request object instance.
    *
+   * @param <E> concrete ODataEntity implementation
    * @param targetURI edit link of the object to be updated.
    * @param type type of update to be performed.
    * @param changes changes to be applied.
    * @return new ODataEntityUpdateRequest instance.
    */
-  ODataEntityUpdateRequest getEntityUpdateRequest(URI targetURI, UT type, CommonODataEntity changes);
+  <E extends CommonODataEntity> ODataEntityUpdateRequest<E> getEntityUpdateRequest(URI targetURI, UT type, E changes);
 
   /**
    * Gets an update request object instance; uses entity's edit link as endpoint.
    *
+   * @param <E> concrete ODataEntity implementation
    * @param type type of update to be performed.
    * @param entity changes to be applied.
    * @return new ODataEntityUpdateRequest instance.
    */
-  ODataEntityUpdateRequest getEntityUpdateRequest(UT type, CommonODataEntity entity);
+  <E extends CommonODataEntity> ODataEntityUpdateRequest<E> getEntityUpdateRequest(UT type, E entity);
 
   /**
    * Gets a create request object instance.

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataEntityUpdateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataEntityUpdateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataEntityUpdateRequest.java
index 11bc797..3f02897 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataEntityUpdateRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataEntityUpdateRequest.java
@@ -20,10 +20,14 @@ package org.apache.olingo.client.api.communication.request.cud;
 
 import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
 import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
+import org.apache.olingo.commons.api.domain.CommonODataEntity;
 import org.apache.olingo.commons.api.format.ODataPubFormat;
 
 /**
  * This class implements an OData update request.
+ *
+ * @param <E> concrete ODataEntity implementation
  */
-public interface ODataEntityUpdateRequest extends ODataBasicRequest<ODataEntityUpdateResponse, ODataPubFormat> {
+public interface ODataEntityUpdateRequest<E extends CommonODataEntity>
+        extends ODataBasicRequest<ODataEntityUpdateResponse<E>, ODataPubFormat> {
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/CUDRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/CUDRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/CUDRequestFactory.java
index d04bc9b..3e14755 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/CUDRequestFactory.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/CUDRequestFactory.java
@@ -18,20 +18,7 @@
  */
 package org.apache.olingo.client.api.communication.request.cud.v4;
 
-import java.net.URI;
 import org.apache.olingo.client.api.communication.request.cud.CommonCUDRequestFactory;
-import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
-import org.apache.olingo.commons.api.domain.v4.ODataEntity;
 
 public interface CUDRequestFactory extends CommonCUDRequestFactory<UpdateType> {
-
-  /**
-   * Gets an update request object instance; uses given URL as endpoint (for upsert).
-   *
-   * @param type type of update to be performed
-   * @param uri endpoint for upsert
-   * @param entity entity to be upserted.
-   * @return new ODataEntityUpdateRequest instance.
-   */
-  ODataEntityUpdateRequest getEntityUpsertRequest(final UpdateType type, URI uri, ODataEntity entity);
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataEntityUpdateResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataEntityUpdateResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataEntityUpdateResponse.java
index 59b0112..1208aa1 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataEntityUpdateResponse.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataEntityUpdateResponse.java
@@ -23,14 +23,15 @@ import org.apache.olingo.commons.api.domain.CommonODataEntity;
 /**
  * This class implements the response to an OData update request.
  *
+ * @param <E> concrete ODataEntity implementation
  * @see org.apache.olingo.client.core.communication.request.cud.ODataEntityUpdateRequest
  */
-public interface ODataEntityUpdateResponse extends ODataResponse {
+public interface ODataEntityUpdateResponse<E extends CommonODataEntity> extends ODataResponse {
 
   /**
    * Gets updated object.
    *
    * @return updated object.
    */
-  CommonODataEntity getBody();
+  E getBody();
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-core/src/main/java/org/apache/olingo/client/core/AbstractODataClient.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/AbstractODataClient.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/AbstractODataClient.java
index b29463a..00a7d66 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/AbstractODataClient.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/AbstractODataClient.java
@@ -19,6 +19,7 @@
 package org.apache.olingo.client.core;
 
 import org.apache.olingo.client.api.CommonODataClient;
+import org.apache.olingo.client.api.communication.header.ODataPreferences;
 import org.apache.olingo.client.api.communication.request.cud.CommonUpdateType;
 import org.apache.olingo.client.api.op.ODataWriter;
 import org.apache.olingo.client.core.op.ODataWriterImpl;
@@ -30,6 +31,12 @@ public abstract class AbstractODataClient<UT extends CommonUpdateType> implement
   private final ODataWriter writer = new ODataWriterImpl(this);
 
   @Override
+  public ODataPreferences newPreferences() {
+    return new ODataPreferences(getServiceVersion());
+
+  }
+
+  @Override
   public ODataWriter getWriter() {
     return writer;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
index 80eadf1..10e2d7d 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
@@ -52,7 +52,7 @@ public abstract class AbstractODataBasicRequest<V extends ODataResponse, T exten
    * @param method request method.
    * @param uri OData request URI.
    */
-  public AbstractODataBasicRequest(final CommonODataClient odataClient,
+  public AbstractODataBasicRequest(final CommonODataClient<?> odataClient,
           final Class<T> formatRef, final HttpMethod method, final URI uri) {
 
     super(odataClient, formatRef, method, uri);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
index 3998a59..9719e22 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
@@ -76,7 +76,7 @@ public class ODataRequestImpl<T extends Format> implements ODataRequest {
    */
   protected static final Logger LOG = LoggerFactory.getLogger(ODataRequest.class);
 
-  protected final CommonODataClient odataClient;
+  protected final CommonODataClient<?> odataClient;
 
   private final Class<T> formatRef;
 
@@ -113,7 +113,7 @@ public class ODataRequestImpl<T extends Format> implements ODataRequest {
    * @param method HTTP request method. If configured X-HTTP-METHOD header will be used.
    * @param uri OData request URI.
    */
-  protected ODataRequestImpl(final CommonODataClient odataClient,
+  protected ODataRequestImpl(final CommonODataClient<?> odataClient,
           final Class<T> formatRef, final HttpMethod method, final URI uri) {
 
     this.odataClient = odataClient;
@@ -392,7 +392,7 @@ public class ODataRequestImpl<T extends Format> implements ODataRequest {
 
       addCustomHeader(
               HeaderName.dataServiceUrlConventions.toString(),
-              new ODataPreferences(odataClient.getServiceVersion()).keyAsSegment());
+              odataClient.newPreferences().keyAsSegment());
     }
 
     // Add all available headers

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/AbstractCUDRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/AbstractCUDRequestFactory.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/AbstractCUDRequestFactory.java
index 3f67f46..73d39f9 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/AbstractCUDRequestFactory.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/AbstractCUDRequestFactory.java
@@ -50,34 +50,36 @@ public abstract class AbstractCUDRequestFactory<UT extends CommonUpdateType> imp
   }
 
   @Override
-  public ODataEntityUpdateRequest getEntityUpdateRequest(
-          final URI targetURI, final UT type, final CommonODataEntity changes) {
+  public <E extends CommonODataEntity> ODataEntityUpdateRequest<E> getEntityUpdateRequest(
+          final URI targetURI, final UT type, final E changes) {
 
-    final ODataEntityUpdateRequest req;
+    final ODataEntityUpdateRequest<E> req;
 
     if (client.getConfiguration().isUseXHTTPMethod()) {
-      req = new ODataEntityUpdateRequestImpl(client, HttpMethod.POST, targetURI, changes);
+      req = new ODataEntityUpdateRequestImpl<E>(client, HttpMethod.POST, targetURI, changes);
       req.setXHTTPMethod(type.getMethod().name());
     } else {
-      req = new ODataEntityUpdateRequestImpl(client, type.getMethod(), targetURI, changes);
+      req = new ODataEntityUpdateRequestImpl<E>(client, type.getMethod(), targetURI, changes);
     }
 
     return req;
   }
 
   @Override
-  public ODataEntityUpdateRequest getEntityUpdateRequest(final UT type, final CommonODataEntity entity) {
+  public <E extends CommonODataEntity> ODataEntityUpdateRequest<E> getEntityUpdateRequest(
+          final UT type, final E entity) {
+
     if (entity.getEditLink() == null) {
       throw new IllegalArgumentException("No edit link found");
     }
 
-    final ODataEntityUpdateRequest req;
+    final ODataEntityUpdateRequest<E> req;
 
     if (client.getConfiguration().isUseXHTTPMethod()) {
-      req = new ODataEntityUpdateRequestImpl(client, HttpMethod.POST, entity.getEditLink(), entity);
+      req = new ODataEntityUpdateRequestImpl<E>(client, HttpMethod.POST, entity.getEditLink(), entity);
       req.setXHTTPMethod(type.getMethod().name());
     } else {
-      req = new ODataEntityUpdateRequestImpl(client, type.getMethod(), entity.getEditLink(), entity);
+      req = new ODataEntityUpdateRequestImpl<E>(client, type.getMethod(), entity.getEditLink(), entity);
     }
 
     return req;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java
index ff9dc54..9a84de3 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java
@@ -39,14 +39,16 @@ import org.apache.olingo.commons.api.data.Entry;
 
 /**
  * This class implements an OData update request.
+ * @param <E> concrete ODataEntity implementation
  */
-public class ODataEntityUpdateRequestImpl extends AbstractODataBasicRequest<ODataEntityUpdateResponse, ODataPubFormat>
-        implements ODataEntityUpdateRequest, ODataBatchableRequest {
+public class ODataEntityUpdateRequestImpl<E extends CommonODataEntity>
+        extends AbstractODataBasicRequest<ODataEntityUpdateResponse<E>, ODataPubFormat>
+        implements ODataEntityUpdateRequest<E>, ODataBatchableRequest {
 
   /**
    * Changes to be applied.
    */
-  private final CommonODataEntity changes;
+  private final E changes;
 
   /**
    * Constructor.
@@ -56,8 +58,8 @@ public class ODataEntityUpdateRequestImpl extends AbstractODataBasicRequest<ODat
    * @param uri URI of the entity to be updated.
    * @param changes changes to be applied.
    */
-  public ODataEntityUpdateRequestImpl(final CommonODataClient odataClient,
-          final HttpMethod method, final URI uri, final CommonODataEntity changes) {
+  public ODataEntityUpdateRequestImpl(final CommonODataClient<?> odataClient,
+          final HttpMethod method, final URI uri, final E changes) {
 
     super(odataClient, ODataPubFormat.class, method, uri);
     this.changes = changes;
@@ -67,7 +69,7 @@ public class ODataEntityUpdateRequestImpl extends AbstractODataBasicRequest<ODat
    * {@inheritDoc }
    */
   @Override
-  public ODataEntityUpdateResponse execute() {
+  public ODataEntityUpdateResponse<E> execute() {
     final InputStream input = getPayload();
     ((HttpEntityEnclosingRequestBase) request).setEntity(URIUtils.buildInputStreamEntity(odataClient, input));
 
@@ -89,12 +91,12 @@ public class ODataEntityUpdateRequestImpl extends AbstractODataBasicRequest<ODat
   /**
    * Response class about an ODataEntityUpdateRequest.
    */
-  private class ODataEntityUpdateResponseImpl extends AbstractODataResponse implements ODataEntityUpdateResponse {
+  private class ODataEntityUpdateResponseImpl extends AbstractODataResponse implements ODataEntityUpdateResponse<E> {
 
     /**
      * Changes.
      */
-    private CommonODataEntity entity = null;
+    private E entity = null;
 
     /**
      * Constructor.
@@ -118,13 +120,14 @@ public class ODataEntityUpdateRequestImpl extends AbstractODataBasicRequest<ODat
      * {@inheritDoc ]
      */
     @Override
-    public CommonODataEntity getBody() {
+    @SuppressWarnings("unchecked")
+    public E getBody() {
       if (entity == null) {
         try {
-          final Container<Entry> container = odataClient.getDeserializer().toEntry(getRawResponse(), 
+          final Container<Entry> container = odataClient.getDeserializer().toEntry(getRawResponse(),
                   ODataPubFormat.fromString(getAccept()));
-          
-          entity = odataClient.getBinder().getODataEntity(extractFromContainer(container));
+
+          entity = (E) odataClient.getBinder().getODataEntity(extractFromContainer(container));
         } finally {
           this.close();
         }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v4/CUDRequestFactoryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v4/CUDRequestFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v4/CUDRequestFactoryImpl.java
index c0f6b40..8d4e7c7 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v4/CUDRequestFactoryImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v4/CUDRequestFactoryImpl.java
@@ -18,13 +18,10 @@
  */
 package org.apache.olingo.client.core.communication.request.cud.v4;
 
-import java.net.URI;
-import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
 import org.apache.olingo.client.api.v4.ODataClient;
 import org.apache.olingo.client.api.communication.request.cud.v4.CUDRequestFactory;
 import org.apache.olingo.client.api.communication.request.cud.v4.UpdateType;
 import org.apache.olingo.client.core.communication.request.cud.AbstractCUDRequestFactory;
-import org.apache.olingo.commons.api.domain.v4.ODataEntity;
 
 public class CUDRequestFactoryImpl extends AbstractCUDRequestFactory<UpdateType>
         implements CUDRequestFactory {
@@ -35,12 +32,4 @@ public class CUDRequestFactoryImpl extends AbstractCUDRequestFactory<UpdateType>
     super(client);
   }
 
-  @Override
-  public ODataEntityUpdateRequest getEntityUpsertRequest(
-          final UpdateType type, final URI uri, final ODataEntity entity) {
-    
-    entity.setEditLink(uri);
-    return super.getEntityUpdateRequest(type, entity);
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AbstractTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AbstractTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AbstractTestITCase.java
index 36a2264..90f0510 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AbstractTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AbstractTestITCase.java
@@ -561,7 +561,9 @@ public abstract class AbstractTestITCase {
 
   protected void update(
           final UpdateType type, final ODataEntity changes, final ODataPubFormat format, final String etag) {
-    final ODataEntityUpdateRequest req = getClient().getCUDRequestFactory().getEntityUpdateRequest(type, changes);
+
+    final ODataEntityUpdateRequest<ODataEntity> req =
+            getClient().getCUDRequestFactory().getEntityUpdateRequest(type, changes);
 
     if (getClient().getConfiguration().isUseXHTTPMethod()) {
       assertEquals(HttpMethod.POST, req.getMethod());
@@ -574,7 +576,7 @@ public abstract class AbstractTestITCase {
       req.setIfMatch(etag); // Product include ETag header into the response .....
     }
 
-    final ODataEntityUpdateResponse res = req.execute();
+    final ODataEntityUpdateResponse<ODataEntity> res = req.execute();
     assertEquals(204, res.getStatusCode());
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AsyncTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AsyncTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AsyncTestITCase.java
index 491a8e1..18dd57e 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AsyncTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/AsyncTestITCase.java
@@ -68,7 +68,7 @@ public class AsyncTestITCase extends AbstractTestITCase {
 
     final ODataRetrieveResponse<ODataEntity> entityRes = client.getRetrieveRequestFactory().
             getEntityRequest(uri).execute();
-    final CommonODataEntity entity = entityRes.getBody();
+    final ODataEntity entity = entityRes.getBody();
     entity.getAssociationLinks().clear();
     entity.getNavigationLinks().clear();
     entity.getEditMediaLinks().clear();
@@ -78,10 +78,10 @@ public class AsyncTestITCase extends AbstractTestITCase {
             client.getObjectFactory().newPrimitiveProperty("Description",
                     client.getObjectFactory().newPrimitiveValueBuilder().setText("AsyncTest#updateEntity").build()));
 
-    final ODataEntityUpdateRequest updateReq =
+    final ODataEntityUpdateRequest<ODataEntity> updateReq =
             client.getCUDRequestFactory().getEntityUpdateRequest(uri, UpdateType.MERGE, entity);
     updateReq.setIfMatch(entityRes.getEtag());
-    final Future<ODataEntityUpdateResponse> futureRes = updateReq.asyncExecute();
+    final Future<ODataEntityUpdateResponse<ODataEntity>> futureRes = updateReq.asyncExecute();
 
     while (!futureRes.isDone()) {
       Thread.sleep(1000L);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityCreateTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityCreateTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityCreateTestITCase.java
index 034d05c..0a62ecc 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityCreateTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityCreateTestITCase.java
@@ -229,11 +229,11 @@ public class EntityCreateTestITCase extends AbstractTestITCase {
 
     final ODataEntityCreateRequest<ODataEntity> createReq = client.getCUDRequestFactory().getEntityCreateRequest(
             client.getURIBuilder(getServiceRoot()).appendEntitySetSegment("Customer").build(), original);
-    createReq.setPrefer(new ODataPreferences(client.getServiceVersion()).returnNoContent());
+    createReq.setPrefer(client.newPreferences().returnNoContent());
 
     final ODataEntityCreateResponse<ODataEntity> createRes = createReq.execute();
     assertEquals(204, createRes.getStatusCode());
-    assertEquals(new ODataPreferences(client.getServiceVersion()).returnNoContent(),
+    assertEquals(client.newPreferences().returnNoContent(),
             createRes.getHeader(HeaderName.preferenceApplied).iterator().next());
 
     try {
@@ -259,7 +259,7 @@ public class EntityCreateTestITCase extends AbstractTestITCase {
             client.getCUDRequestFactory().getEntityCreateRequest(uriBuilder.build(), original);
     createReq.setFormat(ODataPubFormat.JSON_FULL_METADATA);
     createReq.setContentType(ContentType.APPLICATION_ATOM_XML.getMimeType());
-    createReq.setPrefer(new ODataPreferences(client.getServiceVersion()).returnContent());
+    createReq.setPrefer(client.newPreferences().returnContent());
 
     try {
       final ODataEntityCreateResponse createRes = createReq.execute();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityUpdateTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityUpdateTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityUpdateTestITCase.java
index 9b47c5f..10b3891 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityUpdateTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityUpdateTestITCase.java
@@ -173,7 +173,7 @@ public class EntityUpdateTestITCase extends AbstractTestITCase {
     // ---------------------------------------
   }
 
-  private ODataEntityUpdateRequest buildMultiKeyUpdateReq(final ODataPubFormat format)
+  private ODataEntityUpdateRequest<ODataEntity> buildMultiKeyUpdateReq(final ODataPubFormat format)
           throws EdmPrimitiveTypeException {
 
     final LinkedHashMap<String, Object> multiKey = new LinkedHashMap<String, Object>();
@@ -194,7 +194,7 @@ public class EntityUpdateTestITCase extends AbstractTestITCase {
   }
 
   private void mergeMultiKey(final ODataPubFormat format) throws EdmPrimitiveTypeException {
-    final ODataEntityUpdateResponse res = buildMultiKeyUpdateReq(format).execute();
+    final ODataEntityUpdateResponse<ODataEntity> res = buildMultiKeyUpdateReq(format).execute();
     assertEquals(204, res.getStatusCode());
   }
 
@@ -210,12 +210,13 @@ public class EntityUpdateTestITCase extends AbstractTestITCase {
 
   @Test
   public void updateReturnContent() throws EdmPrimitiveTypeException {
-    final ODataEntityUpdateRequest req = buildMultiKeyUpdateReq(client.getConfiguration().getDefaultPubFormat());
-    req.setPrefer(new ODataPreferences(client.getServiceVersion()).returnContent());
+    final ODataEntityUpdateRequest<ODataEntity> req =
+            buildMultiKeyUpdateReq(client.getConfiguration().getDefaultPubFormat());
+    req.setPrefer(client.newPreferences().returnContent());
 
-    final ODataEntityUpdateResponse res = req.execute();
+    final ODataEntityUpdateResponse<ODataEntity> res = req.execute();
     assertEquals(200, res.getStatusCode());
-    assertEquals(new ODataPreferences(client.getServiceVersion()).returnContent(),
+    assertEquals(client.newPreferences().returnContent(),
             res.getHeader(HeaderName.preferenceApplied).iterator().next());
     assertNotNull(res.getBody());
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityRetrieveTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityRetrieveTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityRetrieveTestITCase.java
index e2a8240..28f029e 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityRetrieveTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityRetrieveTestITCase.java
@@ -31,7 +31,7 @@ import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRe
 import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
 import org.apache.olingo.client.api.communication.response.ODataRawResponse;
 import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
-import org.apache.olingo.client.api.uri.CommonURIBuilder;
+import org.apache.olingo.client.api.uri.v4.URIBuilder;
 import org.apache.olingo.commons.api.domain.CommonODataEntity;
 import org.apache.olingo.commons.api.domain.CommonODataEntitySet;
 import org.apache.olingo.commons.api.domain.CommonODataProperty;
@@ -55,7 +55,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
   }
 
   private void withInlineEntry(final ODataPubFormat format) {
-    final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).
+    final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()).
             appendEntitySetSegment("Customers").appendKeySegment(1).expand("Company");
 
     final ODataEntityRequest<ODataEntity> req = client.getRetrieveRequestFactory().
@@ -63,7 +63,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
     req.setFormat(format);
 
     final ODataRetrieveResponse<ODataEntity> res = req.execute();
-    final CommonODataEntity entity = res.getBody();
+    final ODataEntity entity = res.getBody();
 
     assertNotNull(entity);
     assertEquals("Microsoft.Test.OData.Services.ODataWCFService.Customer", entity.getTypeName().toString());
@@ -116,7 +116,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
   }
 
   private void withInlineFeed(final ODataPubFormat format) {
-    final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).
+    final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()).
             appendEntitySetSegment("Customers").appendKeySegment(1).expand("Orders");
 
     final ODataEntityRequest<ODataEntity> req = client.getRetrieveRequestFactory().
@@ -124,7 +124,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
     req.setFormat(format);
 
     final ODataRetrieveResponse<ODataEntity> res = req.execute();
-    final CommonODataEntity entity = res.getBody();
+    final ODataEntity entity = res.getBody();
     assertNotNull(entity);
 
     boolean found = false;
@@ -153,7 +153,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
   }
 
   private void rawRequest(final ODataPubFormat format) {
-    final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).
+    final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()).
             appendEntitySetSegment("People").appendKeySegment(5);
 
     final ODataRawRequest req = client.getRetrieveRequestFactory().getRawRequest(uriBuilder.build());
@@ -185,14 +185,14 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
     multiKey.put("ProductID", "6");
     multiKey.put("ProductDetailID", 1);
 
-    final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).
+    final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()).
             appendEntitySetSegment("ProductDetails").appendKeySegment(multiKey);
 
     final ODataEntityRequest<ODataEntity> req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
     req.setFormat(format);
 
     final ODataRetrieveResponse<ODataEntity> res = req.execute();
-    final CommonODataEntity entity = res.getBody();
+    final ODataEntity entity = res.getBody();
     assertNotNull(entity);
     assertEquals(Integer.valueOf(1),
             entity.getProperty("ProductDetailID").getPrimitiveValue().toCastValue(Integer.class));
@@ -219,7 +219,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
   }
 
   private void checkForETag(final ODataPubFormat format) {
-    final CommonURIBuilder<?> uriBuilder =
+    final URIBuilder uriBuilder =
             client.getURIBuilder(getServiceRoot()).appendEntitySetSegment("Orders").appendKeySegment(8);
 
     final ODataEntityRequest<ODataEntity> req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
@@ -231,13 +231,13 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
     final String etag = res.getEtag();
     assertTrue(StringUtils.isNotBlank(etag));
 
-    final CommonODataEntity order = res.getBody();
+    final ODataEntity order = res.getBody();
     assertEquals(etag, order.getETag());
   }
 
   @Test(expected = IllegalArgumentException.class)
   public void issue99() {
-    final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).appendEntitySetSegment("Orders");
+    final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()).appendEntitySetSegment("Orders");
 
     final ODataEntityRequest<ODataEntity> req = client.getRetrieveRequestFactory().getEntityRequest(uriBuilder.build());
     req.setFormat(ODataPubFormat.JSON);
@@ -258,7 +258,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
   }
 
   private void retrieveEntityViaReference(final ODataPubFormat format) {
-    final CommonURIBuilder<?> uriBuilder = client.getURIBuilder(getServiceRoot()).
+    final URIBuilder uriBuilder = client.getURIBuilder(getServiceRoot()).
             appendEntitySetSegment("Orders").appendKeySegment(8).appendNavigationSegment("CustomerForOrder").
             appendRefSegment();
 
@@ -282,4 +282,28 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
     assertNotNull(res);
     assertNotNull(res.getBody());
   }
+
+  private void contained(final ODataPubFormat format) throws EdmPrimitiveTypeException {
+    final URI uri = getClient().getURIBuilder(getServiceRoot()).
+            appendEntitySetSegment("Accounts").appendKeySegment(101).
+            appendNavigationSegment("MyPaymentInstruments").appendKeySegment(101901).build();
+
+    final ODataEntityRequest<ODataEntity> req = getClient().getRetrieveRequestFactory().getEntityRequest(uri);
+    req.setFormat(format);
+
+    final ODataEntity contained = req.execute().getBody();
+    assertNotNull(contained);
+    assertEquals(101901,
+            contained.getProperty("PaymentInstrumentID").getPrimitiveValue().toCastValue(Integer.class), 0);
+  }
+
+  @Test
+  public void atomContained() throws EdmPrimitiveTypeException {
+    contained(ODataPubFormat.ATOM);
+  }
+
+  @Test
+  public void jsonContained() throws EdmPrimitiveTypeException {
+    contained(ODataPubFormat.JSON);
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e67cbaa3/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityUpdateTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityUpdateTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityUpdateTestITCase.java
index ca8ed99..e1e6331 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityUpdateTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntityUpdateTestITCase.java
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertNotNull;
 
 import java.net.URI;
 import java.util.Calendar;
+import java.util.UUID;
 import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
 import org.apache.olingo.client.api.communication.request.cud.v4.UpdateType;
 import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
@@ -49,11 +50,11 @@ public class EntityUpdateTestITCase extends AbstractTestITCase {
 
     final URI upsertURI = getClient().getURIBuilder(testStaticServiceRootURL).
             appendEntitySetSegment("Orders").appendKeySegment(9).build();
-    final ODataEntityUpdateRequest req = getClient().getCUDRequestFactory().
-            getEntityUpsertRequest(updateType, upsertURI, order);
+    final ODataEntityUpdateRequest<ODataEntity> req = getClient().getCUDRequestFactory().
+            getEntityUpdateRequest(upsertURI, updateType, order);
     req.setFormat(format);
 
-    final ODataEntityUpdateResponse res = req.execute();
+    req.execute();
     try {
       final ODataEntity read = read(format, upsertURI);
       assertNotNull(read);
@@ -79,4 +80,36 @@ public class EntityUpdateTestITCase extends AbstractTestITCase {
     upsert(UpdateType.REPLACE, ODataPubFormat.JSON);
   }
 
+  private void onContained(final ODataPubFormat format) {
+    final String newName = UUID.randomUUID().toString();
+    final ODataEntity changes = getClient().getObjectFactory().newEntity(
+            new FullQualifiedName("Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument"));
+    changes.getProperties().add(getClient().getObjectFactory().newPrimitiveProperty("FriendlyName",
+            getClient().getObjectFactory().newPrimitiveValueBuilder().buildString(newName)));
+
+    final URI uri = getClient().getURIBuilder(testStaticServiceRootURL).
+            appendEntitySetSegment("Accounts").appendKeySegment(101).
+            appendNavigationSegment("MyPaymentInstruments").appendKeySegment(101901).build();
+    final ODataEntityUpdateRequest<ODataEntity> req = getClient().getCUDRequestFactory().
+            getEntityUpdateRequest(uri, UpdateType.PATCH, changes);
+    req.setFormat(format);
+
+    final ODataEntityUpdateResponse<ODataEntity> res = req.execute();
+    assertEquals(204, res.getStatusCode());
+
+    final ODataEntity actual = getClient().getRetrieveRequestFactory().getEntityRequest(uri).execute().getBody();
+    assertNotNull(actual);
+    assertEquals(newName, actual.getProperty("FriendlyName").getPrimitiveValue().toString());
+  }
+
+  @Test
+  public void atomOnContained() {
+    onContained(ODataPubFormat.ATOM);
+  }
+
+  @Test
+  public void jsonOnContained() {
+    onContained(ODataPubFormat.JSON);
+  }
+
 }