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/27 07:49:16 UTC

[3/6] [OLINGO-254] Specific client (EdmEnabledODataClient) provided to work with Edm: type information is derived from contextURL, hence such client is useful in JSON with full or minimal metadata

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/EdmMetadataRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/EdmMetadataRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/EdmMetadataRequestImpl.java
index 00f9cb4..37a4220 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/EdmMetadataRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/EdmMetadataRequestImpl.java
@@ -39,7 +39,7 @@ class EdmMetadataRequestImpl extends AbstractMetadataRequestImpl<Edm> implements
    * @param odataClient client instance getting this request
    * @param uri metadata URI.
    */
-  EdmMetadataRequestImpl(final CommonODataClient odataClient, final String serviceRoot, final URI uri) {
+  EdmMetadataRequestImpl(final CommonODataClient<?> odataClient, final String serviceRoot, final URI uri) {
     super(odataClient, uri);
     this.serviceRoot = serviceRoot;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntityRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntityRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntityRequestImpl.java
index 3c01148..c51bcdc 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntityRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntityRequestImpl.java
@@ -24,7 +24,7 @@ import org.apache.http.client.HttpClient;
 import org.apache.olingo.client.api.CommonODataClient;
 import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
 import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.data.Entry;
 import org.apache.olingo.commons.api.domain.CommonODataEntity;
 import org.apache.olingo.commons.api.format.ODataPubFormat;
@@ -81,10 +81,10 @@ public class ODataEntityRequestImpl<E extends CommonODataEntity>
     public E getBody() {
       if (entity == null) {
         try {
-          final Container<Entry> container =
-                  odataClient.getDeserializer().toEntry(getRawResponse(), ODataPubFormat.fromString(getContentType()));
+          final ResWrap<Entry> resource = odataClient.getDeserializer().
+                  toEntry(getRawResponse(), ODataPubFormat.fromString(getContentType()));
 
-          entity = (E) odataClient.getBinder().getODataEntity(extractFromContainer(container));
+          entity = (E) odataClient.getBinder().getODataEntity(resource);
         } finally {
           this.close();
         }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetRequestImpl.java
index 0fc236a..a14b4a8 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetRequestImpl.java
@@ -24,7 +24,7 @@ import org.apache.http.client.HttpClient;
 import org.apache.olingo.client.api.CommonODataClient;
 import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
 import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.data.Feed;
 import org.apache.olingo.commons.api.domain.CommonODataEntitySet;
 import org.apache.olingo.commons.api.format.ODataPubFormat;
@@ -90,10 +90,10 @@ public class ODataEntitySetRequestImpl<ES extends CommonODataEntitySet>
     public ES getBody() {
       if (entitySet == null) {
         try {
-          final Container<Feed> container =
-                  odataClient.getDeserializer().toFeed(getRawResponse(), ODataPubFormat.fromString(getContentType()));
+          final ResWrap<Feed> resource = odataClient.getDeserializer().
+                  toFeed(getRawResponse(), ODataPubFormat.fromString(getContentType()));
 
-          entitySet = (ES) odataClient.getBinder().getODataEntitySet(extractFromContainer(container));
+          entitySet = (ES) odataClient.getBinder().getODataEntitySet(resource);
         } finally {
           this.close();
         }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataPropertyRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataPropertyRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataPropertyRequestImpl.java
index fb385e2..d97e7b3 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataPropertyRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataPropertyRequestImpl.java
@@ -28,7 +28,7 @@ import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse
 import org.apache.olingo.commons.api.domain.CommonODataProperty;
 import org.apache.olingo.commons.api.format.ODataFormat;
 import org.apache.olingo.client.api.http.HttpClientException;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.data.Property;
 
 /**
@@ -86,11 +86,10 @@ public class ODataPropertyRequestImpl<T extends CommonODataProperty>
     public T getBody() {
       if (property == null) {
         try {
-          final Container<Property> container =
-                  odataClient.getDeserializer().toProperty(
+          final ResWrap<Property> resource = odataClient.getDeserializer().toProperty(
                   res.getEntity().getContent(), ODataFormat.fromString(getContentType()));
 
-          property = (T) odataClient.getBinder().getODataProperty(extractFromContainer(container));
+          property = (T) odataClient.getBinder().getODataProperty(resource);
         } catch (IOException e) {
           throw new HttpClientException(e);
         } finally {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
index c7e53b2..003a013 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
@@ -31,7 +31,7 @@ import org.apache.olingo.commons.api.format.ODataPubFormat;
 import org.apache.olingo.client.api.http.HttpMethod;
 import org.apache.olingo.client.core.communication.request.AbstractODataRequest;
 import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
 
 /**
  * This class implements a generic OData request.
@@ -83,7 +83,7 @@ public class ODataRawRequestImpl extends AbstractODataRequest<ODataPubFormat>
     }
 
     @Override
-    public <T> T getBodyAs(final Class<T> reference) {
+    public <T> ResWrap<T> getBodyAs(final Class<T> reference) {
       if (obj == null) {
         try {
           this.obj = IOUtils.toByteArray(getRawResponse());
@@ -94,10 +94,8 @@ public class ODataRawRequestImpl extends AbstractODataRequest<ODataPubFormat>
         }
       }
 
-      final Container<T> container =
-              odataClient.getReader().read(new ByteArrayInputStream(obj), getContentType(), reference);
-
-      return extractFromContainer(container);
+      return odataClient.getReader().
+              read(new ByteArrayInputStream(obj), getContentType(), reference);
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataServiceDocumentRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataServiceDocumentRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataServiceDocumentRequestImpl.java
index 2b9f347..2222c0d 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataServiceDocumentRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataServiceDocumentRequestImpl.java
@@ -25,7 +25,7 @@ import org.apache.olingo.client.api.CommonODataClient;
 import org.apache.olingo.client.api.communication.request.retrieve.ODataServiceDocumentRequest;
 import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
 import org.apache.olingo.client.api.data.ServiceDocument;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.domain.ODataServiceDocument;
 import org.apache.olingo.commons.api.format.ODataFormat;
 
@@ -83,10 +83,10 @@ public class ODataServiceDocumentRequestImpl extends AbstractODataRetrieveReques
     public ODataServiceDocument getBody() {
       if (serviceDocument == null) {
         try {
-          final Container<ServiceDocument> container = odataClient.getDeserializer().toServiceDocument(
-                  getRawResponse(), ODataFormat.fromString(getContentType()));
+          final ResWrap<ServiceDocument> resource = odataClient.getDeserializer().
+                  toServiceDocument(getRawResponse(), ODataFormat.fromString(getContentType()));
 
-          serviceDocument = odataClient.getBinder().getODataServiceDocument(extractFromContainer(container));
+          serviceDocument = odataClient.getBinder().getODataServiceDocument(resource.getPayload());
         } finally {
           this.close();
         }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityCreateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityCreateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityCreateRequestImpl.java
index 188891c..0eb5037 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityCreateRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityCreateRequestImpl.java
@@ -31,7 +31,7 @@ import org.apache.olingo.commons.api.domain.CommonODataEntity;
 import org.apache.olingo.client.api.http.HttpMethod;
 import org.apache.olingo.client.core.communication.request.AbstractODataStreamManager;
 import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.data.Entry;
 
 /**
@@ -123,8 +123,9 @@ public class ODataMediaEntityCreateRequestImpl<E extends CommonODataEntity>
     public E getBody() {
       if (entity == null) {
         try {
-          final Container<Entry> container = odataClient.getDeserializer().toEntry(getRawResponse(), getFormat());
-          entity = (E) odataClient.getBinder().getODataEntity(extractFromContainer(container));
+          final ResWrap<Entry> resource = odataClient.getDeserializer().toEntry(getRawResponse(), getFormat());
+
+          entity = (E) odataClient.getBinder().getODataEntity(resource);
         } finally {
           this.close();
         }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityUpdateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityUpdateRequestImpl.java
index bb8ef64..476fb8d 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityUpdateRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityUpdateRequestImpl.java
@@ -31,7 +31,7 @@ import org.apache.olingo.commons.api.domain.CommonODataEntity;
 import org.apache.olingo.client.api.http.HttpMethod;
 import org.apache.olingo.client.core.communication.request.AbstractODataStreamManager;
 import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.data.Entry;
 
 /**
@@ -122,8 +122,9 @@ public class ODataMediaEntityUpdateRequestImpl<E extends CommonODataEntity>
     public E getBody() {
       if (entity == null) {
         try {
-          final Container<Entry> container = odataClient.getDeserializer().toEntry(getRawResponse(), getFormat());
-          entity = (E) odataClient.getBinder().getODataEntity(extractFromContainer(container));
+          final ResWrap<Entry> resource = odataClient.getDeserializer().toEntry(getRawResponse(), getFormat());
+
+          entity = (E) odataClient.getBinder().getODataEntity(resource);
         } finally {
           this.close();
         }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestWrapperImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestWrapperImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestWrapperImpl.java
index c9fb23d..57305cd 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestWrapperImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/v4/AsyncRequestWrapperImpl.java
@@ -49,9 +49,9 @@ import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 public class AsyncRequestWrapperImpl<R extends ODataResponse> extends AbstractRequest
         implements AsyncRequestWrapper<R> {
 
-  private final ODataClient odataClient;
+  private static final int MAX_RETRY = 5;
 
-  private final static int MAX_RETRY = 5;
+  private final ODataClient odataClient;
 
   /**
    * Request to be wrapped.
@@ -131,7 +131,6 @@ public class AsyncRequestWrapperImpl<R extends ODataResponse> extends AbstractRe
   }
 
   private HttpResponse doExecute() {
-
     // Add all available headers
     for (String key : odataRequest.getHeaderNames()) {
       final String value = odataRequest.getHeader(key);
@@ -159,7 +158,6 @@ public class AsyncRequestWrapperImpl<R extends ODataResponse> extends AbstractRe
      */
     @SuppressWarnings("unchecked")
     public AsyncResponseWrapperImpl(final HttpResponse res) {
-
       if (res.getStatusLine().getStatusCode() == 202) {
         retrieveMonitorDetails(res, true);
       } else {
@@ -236,9 +234,7 @@ public class AsyncRequestWrapperImpl<R extends ODataResponse> extends AbstractRe
     @SuppressWarnings("unchecked")
     private R instantiateResponse(final HttpResponse res) {
       R odataResponse;
-
       try {
-
         odataResponse = (R) ((AbstractODataRequest<?>) odataRequest).getResponseTemplate().
                 initFromEnclosedPart(res.getEntity().getContent());
 
@@ -292,7 +288,9 @@ public class AsyncRequestWrapperImpl<R extends ODataResponse> extends AbstractRe
   }
 
   private HttpResponse executeHttpRequest(final HttpClient client, final HttpUriRequest req) {
-    final HttpResponse response;
+    checkRequest(odataClient, request);
+
+    HttpResponse response;
     try {
       response = client.execute(req);
     } catch (IOException e) {
@@ -302,7 +300,7 @@ public class AsyncRequestWrapperImpl<R extends ODataResponse> extends AbstractRe
       throw new HttpClientException(e);
     }
 
-    checkForResponse(odataClient, response, odataRequest.getAccept());
+    checkResponse(odataClient, response, odataRequest.getAccept());
 
     return response;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/AbstractODataResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/AbstractODataResponse.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/AbstractODataResponse.java
index 5564bdf..d66fa20 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/AbstractODataResponse.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/AbstractODataResponse.java
@@ -24,7 +24,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.PipedInputStream;
 import java.io.PipedOutputStream;
-import java.net.URI;
 import java.nio.charset.Charset;
 import java.util.Collection;
 import java.util.HashSet;
@@ -43,7 +42,6 @@ import org.apache.olingo.client.core.communication.request.batch.ODataBatchContr
 import org.apache.olingo.client.core.communication.request.batch.ODataBatchLineIteratorImpl;
 import org.apache.olingo.client.core.communication.request.batch.ODataBatchUtilities;
 import org.apache.olingo.commons.api.Constants;
-import org.apache.olingo.commons.api.data.Container;
 import org.slf4j.LoggerFactory;
 
 /**
@@ -57,16 +55,6 @@ public abstract class AbstractODataResponse implements ODataResponse {
   protected static final org.slf4j.Logger LOG = LoggerFactory.getLogger(ODataResponse.class);
 
   /**
-   * Context URL.
-   */
-  private URI contextURL;
-
-  /**
-   * Metadata ETag.
-   */
-  private String metadataETag;
-
-  /**
    * HTTP client.
    */
   protected final HttpClient client;
@@ -127,24 +115,6 @@ public abstract class AbstractODataResponse implements ODataResponse {
     initFromHttpResponse(res);
   }
 
-  @Override
-  public URI getContextURL() {
-    return contextURL;
-  }
-
-  protected void setContextURL(final URI contextURL) {
-    this.contextURL = contextURL;
-  }
-
-  @Override
-  public String getMetadataETag() {
-    return metadataETag;
-  }
-
-  protected void setMetadataETag(final String metadataETag) {
-    this.metadataETag = metadataETag;
-  }
-
   /**
    * {@inheritDoc}
    */
@@ -173,7 +143,7 @@ public abstract class AbstractODataResponse implements ODataResponse {
    * {@inheritDoc}
    */
   @Override
-  public String getEtag() {
+  public String getETag() {
     final Collection<String> etag = getHeader(HeaderName.etag);
     return etag == null || etag.isEmpty()
             ? null
@@ -361,14 +331,4 @@ public abstract class AbstractODataResponse implements ODataResponse {
 
     return payload;
   }
-
-  protected <T> T extractFromContainer(final Container<T> container) {
-    if (container == null) {
-      return null;
-    }
-
-    setContextURL(container.getContextURL());
-    setMetadataETag(container.getMetadataETag());
-    return container.getObject();
-  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchErrorResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchErrorResponse.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchErrorResponse.java
index d2dd884..fa41b82 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchErrorResponse.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchErrorResponse.java
@@ -18,7 +18,6 @@
  */
 package org.apache.olingo.client.core.communication.response.batch;
 
-import java.net.URI;
 import java.util.Collection;
 import java.util.Map;
 import org.apache.olingo.client.api.communication.request.batch.ODataBatchLineIterator;
@@ -55,17 +54,7 @@ public class ODataBatchErrorResponse extends AbstractODataResponse {
   }
 
   @Override
-  public String getEtag() {
-    return null;
-  }
-
-  @Override
-  public URI getContextURL() {
-    return null;
-  }
-
-  @Override
-  public String getMetadataETag() {
+  public String getETag() {
     return null;
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java
index 7cff539..c7b62f4 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONServiceDocumentDeserializer.java
@@ -30,14 +30,14 @@ import java.util.Iterator;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.commons.api.Constants;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.apache.olingo.commons.core.data.ODataJacksonDeserializer;
 
-public class JSONServiceDocumentDeserializer extends ODataJacksonDeserializer<Container<AbstractServiceDocument>> {
+public class JSONServiceDocumentDeserializer extends ODataJacksonDeserializer<ResWrap<AbstractServiceDocument>> {
 
   @Override
-  protected Container<AbstractServiceDocument> doDeserialize(
+  protected ResWrap<AbstractServiceDocument> doDeserialize(
           final JsonParser parser, final DeserializationContext ctxt)
           throws IOException, JsonProcessingException {
 
@@ -90,6 +90,6 @@ public class JSONServiceDocumentDeserializer extends ODataJacksonDeserializer<Co
       }
     }
 
-    return new Container<AbstractServiceDocument>(contextURL, metadataETag, serviceDocument);
+    return new ResWrap<AbstractServiceDocument>(contextURL, metadataETag, serviceDocument);
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/XMLServiceDocumentDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/XMLServiceDocumentDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/XMLServiceDocumentDeserializer.java
index 1b18040..8edf2e7 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/XMLServiceDocumentDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/XMLServiceDocumentDeserializer.java
@@ -30,10 +30,10 @@ import java.net.URI;
 
 import org.apache.olingo.client.api.data.ServiceDocument;
 import org.apache.olingo.client.core.uri.URIUtils;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 
-public class XMLServiceDocumentDeserializer extends ODataJacksonDeserializer<Container<ServiceDocument>> {
+public class XMLServiceDocumentDeserializer extends ODataJacksonDeserializer<ResWrap<ServiceDocument>> {
 
   private String getTitle(final JsonParser jp) throws IOException {
     String title = jp.nextTextValue();
@@ -69,7 +69,7 @@ public class XMLServiceDocumentDeserializer extends ODataJacksonDeserializer<Con
   }
 
   @Override
-  protected Container<ServiceDocument> doDeserialize(final JsonParser jp, final DeserializationContext ctxt)
+  protected ResWrap<ServiceDocument> doDeserialize(final JsonParser jp, final DeserializationContext ctxt)
           throws IOException, JsonProcessingException {
 
     final AbstractServiceDocument sdoc = ODataServiceVersion.V30 == version
@@ -117,7 +117,7 @@ public class XMLServiceDocumentDeserializer extends ODataJacksonDeserializer<Con
             ? URIUtils.getURI(base, "$metadata")
             : URIUtils.getURI(base, contextURL.toASCIIString())).toASCIIString());
 
-    return new Container<ServiceDocument>(
+    return new ResWrap<ServiceDocument>(
             contextURL == null ? null : URIUtils.getURI(sdoc.getBaseURI(), contextURL),
             metadataETag, sdoc);
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmClientImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmClientImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmClientImpl.java
index 1e16adb..58e8963 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmClientImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmClientImpl.java
@@ -154,9 +154,11 @@ public class EdmClientImpl extends AbstractEdm {
     EdmEntityType result = null;
 
     final Schema schema = xmlSchemaByNamespace.get(entityTypeName.getNamespace());
-    final EntityType xmlEntityType = schema.getEntityType(entityTypeName.getName());
-    if (xmlEntityType != null) {
-      result = EdmEntityTypeImpl.getInstance(this, entityTypeName, xmlEntityType);
+    if (schema != null) {
+      final EntityType xmlEntityType = schema.getEntityType(entityTypeName.getName());
+      if (xmlEntityType != null) {
+        result = EdmEntityTypeImpl.getInstance(this, entityTypeName, xmlEntityType);
+      }
     }
 
     return result;
@@ -167,9 +169,11 @@ public class EdmClientImpl extends AbstractEdm {
     EdmComplexType result = null;
 
     final Schema schema = xmlSchemaByNamespace.get(complexTypeName.getNamespace());
-    final ComplexType xmlComplexType = schema.getComplexType(complexTypeName.getName());
-    if (xmlComplexType != null) {
-      result = EdmComplexTypeImpl.getInstance(this, complexTypeName, xmlComplexType);
+    if (schema != null) {
+      final ComplexType xmlComplexType = schema.getComplexType(complexTypeName.getName());
+      if (xmlComplexType != null) {
+        result = EdmComplexTypeImpl.getInstance(this, complexTypeName, xmlComplexType);
+      }
     }
 
     return result;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmNavigationPropertyImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmNavigationPropertyImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmNavigationPropertyImpl.java
index c2a38c4..6ea464b 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmNavigationPropertyImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/edm/EdmNavigationPropertyImpl.java
@@ -35,6 +35,7 @@ public class EdmNavigationPropertyImpl extends AbstractEdmNavigationProperty {
   private final NavigationProperty navigationProperty;
 
   private final EdmTypeInfo edmTypeInfo;
+
   private List<EdmReferentialConstraint> referentialConstraints;
 
   public EdmNavigationPropertyImpl(final Edm edm, final NavigationProperty navigationProperty) {
@@ -64,6 +65,11 @@ public class EdmNavigationPropertyImpl extends AbstractEdmNavigationProperty {
   }
 
   @Override
+  public Boolean containsTarget() {
+    return navigationProperty.isContainsTarget();
+  }
+
+  @Override
   public String getReferencingPropertyName(final String referencedPropertyName) {
     final List<? extends ReferentialConstraint> referentialConstraints = navigationProperty.getReferentialConstraints();
     if (referentialConstraints != null) {
@@ -84,7 +90,7 @@ public class EdmNavigationPropertyImpl extends AbstractEdmNavigationProperty {
       if (providerConstraints != null) {
         for (ReferentialConstraint constraint : providerConstraints) {
           referentialConstraints.add(new EdmReferentialConstraintImpl(constraint.getProperty(), constraint
-              .getReferencedProperty()));
+                  .getReferencedProperty()));
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java
index 5b74502..95efa7c 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java
@@ -21,34 +21,45 @@ package org.apache.olingo.client.core.op;
 import java.io.StringWriter;
 import java.net.URI;
 import java.util.Iterator;
-import java.util.List;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.client.api.CommonODataClient;
 import org.apache.olingo.client.api.data.ServiceDocument;
 import org.apache.olingo.client.api.data.ServiceDocumentItem;
 import org.apache.olingo.client.api.op.CommonODataBinder;
+import org.apache.olingo.client.api.v4.EdmEnabledODataClient;
 import org.apache.olingo.client.core.uri.URIUtils;
 import org.apache.olingo.commons.api.Constants;
+import org.apache.olingo.commons.api.data.ContextURL;
 import org.apache.olingo.commons.api.data.Entry;
 import org.apache.olingo.commons.api.data.Feed;
 import org.apache.olingo.commons.api.data.Link;
 import org.apache.olingo.commons.api.data.Linked;
 import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.data.Value;
-import org.apache.olingo.commons.api.domain.ODataCollectionValue;
-import org.apache.olingo.commons.api.domain.ODataComplexValue;
 import org.apache.olingo.commons.api.domain.CommonODataEntity;
 import org.apache.olingo.commons.api.domain.CommonODataEntitySet;
+import org.apache.olingo.commons.api.domain.CommonODataProperty;
+import org.apache.olingo.commons.api.domain.ODataCollectionValue;
+import org.apache.olingo.commons.api.domain.ODataComplexValue;
 import org.apache.olingo.commons.api.domain.ODataInlineEntity;
 import org.apache.olingo.commons.api.domain.ODataInlineEntitySet;
 import org.apache.olingo.commons.api.domain.ODataLink;
-import org.apache.olingo.commons.api.domain.ODataOperation;
-import org.apache.olingo.commons.api.domain.CommonODataProperty;
 import org.apache.olingo.commons.api.domain.ODataLinkType;
 import org.apache.olingo.commons.api.domain.ODataLinked;
+import org.apache.olingo.commons.api.domain.ODataOperation;
 import org.apache.olingo.commons.api.domain.ODataServiceDocument;
 import org.apache.olingo.commons.api.domain.ODataValue;
+import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.EdmBindingTarget;
+import org.apache.olingo.commons.api.edm.EdmEntityContainer;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmSchema;
+import org.apache.olingo.commons.api.edm.EdmStructuredType;
+import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.edm.geo.Geospatial;
 import org.apache.olingo.commons.api.format.ODataPubFormat;
@@ -73,9 +84,9 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
    */
   protected final Logger LOG = LoggerFactory.getLogger(AbstractODataBinder.class);
 
-  protected final CommonODataClient client;
+  protected final CommonODataClient<?> client;
 
-  protected AbstractODataBinder(final CommonODataClient client) {
+  protected AbstractODataBinder(final CommonODataClient<?> client) {
     this.client = client;
   }
 
@@ -241,55 +252,61 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
     return valueResource;
   }
 
-  @Override
-  public CommonODataEntitySet getODataEntitySet(final Feed resource) {
-    return getODataEntitySet(resource, null);
-  }
-
   protected abstract boolean add(CommonODataEntitySet entitySet, CommonODataEntity entity);
 
   @Override
-  public CommonODataEntitySet getODataEntitySet(final Feed resource, final URI defaultBaseURI) {
+  public CommonODataEntitySet getODataEntitySet(final ResWrap<Feed> resource) {
     if (LOG.isDebugEnabled()) {
       final StringWriter writer = new StringWriter();
-      client.getSerializer().feed(resource, writer);
+      client.getSerializer().feed(resource.getPayload(), writer);
       writer.flush();
       LOG.debug("Feed -> ODataEntitySet:\n{}", writer.toString());
     }
 
-    final URI base = defaultBaseURI == null ? resource.getBaseURI() : defaultBaseURI;
+    final URI base = resource.getContextURL() == null
+            ? resource.getPayload().getBaseURI() : resource.getContextURL().getServiceRoot();
 
-    final URI next = resource.getNext();
+    final URI next = resource.getPayload().getNext();
 
     final CommonODataEntitySet entitySet = next == null
             ? client.getObjectFactory().newEntitySet()
             : client.getObjectFactory().newEntitySet(URIUtils.getURI(base, next.toASCIIString()));
 
-    if (resource.getCount() != null) {
-      entitySet.setCount(resource.getCount());
+    if (resource.getPayload().getCount() != null) {
+      entitySet.setCount(resource.getPayload().getCount());
     }
 
-    for (Entry entryResource : resource.getEntries()) {
-      add(entitySet, getODataEntity(entryResource));
+    for (Entry entryResource : resource.getPayload().getEntries()) {
+      add(entitySet, getODataEntity(
+              new ResWrap<Entry>(resource.getContextURL(), resource.getMetadataETag(), entryResource)));
     }
 
     return entitySet;
   }
 
-  @Override
-  public CommonODataEntity getODataEntity(final Entry resource) {
-    return getODataEntity(resource, null);
-  }
+  protected void odataNavigationLinks(final EdmStructuredType edmType,
+          final Linked linked, final ODataLinked odataLinked, final String metadataETag, final URI base) {
 
-  protected void odataLinks(final Linked linked, final ODataLinked odataLinked, final URI base) {
     for (Link link : linked.getNavigationLinks()) {
       final Entry inlineEntry = link.getInlineEntry();
       final Feed inlineFeed = link.getInlineFeed();
 
       if (inlineEntry == null && inlineFeed == null) {
-        final ODataLinkType linkType = link.getType() == null
-                ? ODataLinkType.ENTITY_NAVIGATION
-                : ODataLinkType.fromString(client.getServiceVersion(), link.getRel(), link.getType());
+        ODataLinkType linkType = null;
+        if (edmType != null) {
+          final EdmNavigationProperty navProp = edmType.getNavigationProperty(link.getTitle());
+          if (navProp != null) {
+            linkType = navProp.isCollection()
+                    ? ODataLinkType.ENTITY_SET_NAVIGATION
+                    : ODataLinkType.ENTITY_NAVIGATION;
+          }
+        }
+        if (linkType == null) {
+          linkType = link.getType() == null
+                  ? ODataLinkType.ENTITY_NAVIGATION
+                  : ODataLinkType.fromString(client.getServiceVersion(), link.getRel(), link.getType());
+        }
+
         odataLinked.addLink(linkType == ODataLinkType.ENTITY_NAVIGATION
                 ? client.getObjectFactory().
                 newEntityNavigationLink(link.getTitle(), URIUtils.getURI(base, link.getHref()))
@@ -298,114 +315,193 @@ public abstract class AbstractODataBinder implements CommonODataBinder {
       } else if (inlineEntry != null) {
         odataLinked.addLink(new ODataInlineEntity(client.getServiceVersion(),
                 URIUtils.getURI(base, link.getHref()), ODataLinkType.ENTITY_NAVIGATION, link.getTitle(),
-                getODataEntity(inlineEntry,
-                        inlineEntry.getBaseURI() == null ? base : inlineEntry.getBaseURI())));
+                getODataEntity(new ResWrap<Entry>(
+                                inlineEntry.getBaseURI() == null ? base : inlineEntry.getBaseURI(),
+                                metadataETag,
+                                inlineEntry))));
       } else {
         odataLinked.addLink(new ODataInlineEntitySet(client.getServiceVersion(),
                 URIUtils.getURI(base, link.getHref()), ODataLinkType.ENTITY_SET_NAVIGATION, link.getTitle(),
-                getODataEntitySet(inlineFeed,
-                        inlineFeed.getBaseURI() == null ? base : inlineFeed.getBaseURI())));
+                getODataEntitySet(new ResWrap<Feed>(
+                                inlineFeed.getBaseURI() == null ? base : inlineFeed.getBaseURI(),
+                                metadataETag,
+                                inlineFeed))));
       }
     }
   }
 
-  protected abstract void copyProperties(List<Property> src, CommonODataEntity dst, final URI base);
+  /**
+   * Infer type name from various sources of information including Edm and context URL, if available.
+   *
+   * @param contextURL context URL
+   * @param metadataETag metadata ETag
+   * @return Edm type information
+   */
+  private EdmEntityType findEntityType(final ContextURL contextURL, final String metadataETag) {
+    EdmEntityType entityType = null;
+
+    if (client instanceof EdmEnabledODataClient && contextURL != null) {
+      final Edm edm = ((EdmEnabledODataClient) client).getEdm(metadataETag);
+
+      if (contextURL.getDerivedEntity() == null) {
+        for (EdmSchema schema : edm.getSchemas()) {
+          final EdmEntityContainer container = schema.getEntityContainer();
+
+          EdmBindingTarget bindingTarget =
+                  container.getEntitySet(contextURL.getEntitySetOrSingletonOrType());
+          if (bindingTarget == null) {
+            bindingTarget = container.getSingleton(contextURL.getEntitySetOrSingletonOrType());
+          }
+          if (bindingTarget != null) {
+            if (contextURL.getNavOrPropertyPath() == null) {
+              entityType = bindingTarget.getEntityType();
+            } else {
+              final EdmNavigationProperty navProp = bindingTarget.getEntityType().
+                      getNavigationProperty(contextURL.getNavOrPropertyPath());
+
+              entityType = navProp == null
+                      ? bindingTarget.getEntityType()
+                      : navProp.getType();
+            }
+          }
+        }
+      } else {
+        entityType = edm.getEntityType(new FullQualifiedName(contextURL.getDerivedEntity()));
+      }
+    }
+
+    return entityType;
+  }
 
   @Override
-  public CommonODataEntity getODataEntity(final Entry resource, final URI defaultBaseURI) {
+  public CommonODataEntity getODataEntity(final ResWrap<Entry> resource) {
     if (LOG.isDebugEnabled()) {
       final StringWriter writer = new StringWriter();
-      client.getSerializer().entry(resource, writer);
+      client.getSerializer().entry(resource.getPayload(), writer);
       writer.flush();
       LOG.debug("EntryResource -> ODataEntity:\n{}", writer.toString());
     }
 
-    final URI base = defaultBaseURI == null ? resource.getBaseURI() : defaultBaseURI;
+    final URI base = resource.getContextURL() == null
+            ? resource.getPayload().getBaseURI() : resource.getContextURL().getServiceRoot();
 
-    final FullQualifiedName entityTypeName = resource.getType() == null
-            ? null
-            : new FullQualifiedName(resource.getType());
-    final CommonODataEntity entity = resource.getSelfLink() == null
-            ? client.getObjectFactory().newEntity(entityTypeName)
-            : client.getObjectFactory().newEntity(entityTypeName,
-                    URIUtils.getURI(base, resource.getSelfLink().getHref()));
+    final EdmEntityType edmType = findEntityType(resource.getContextURL(), resource.getMetadataETag());
+    FullQualifiedName typeName = null;
+    if (resource.getPayload().getType() == null) {
+      if (edmType != null) {
+        typeName = edmType.getFullQualifiedName();
+      }
+    } else {
+      typeName = new FullQualifiedName(resource.getPayload().getType());
+    }
+
+    final CommonODataEntity entity = resource.getPayload().getSelfLink() == null
+            ? client.getObjectFactory().newEntity(typeName)
+            : client.getObjectFactory().newEntity(typeName,
+                    URIUtils.getURI(base, resource.getPayload().getSelfLink().getHref()));
 
-    if (StringUtils.isNotBlank(resource.getETag())) {
-      entity.setETag(resource.getETag());
+    if (StringUtils.isNotBlank(resource.getPayload().getETag())) {
+      entity.setETag(resource.getPayload().getETag());
     }
 
-    if (resource.getEditLink() != null) {
-      entity.setEditLink(URIUtils.getURI(base, resource.getEditLink().getHref()));
+    if (resource.getPayload().getEditLink() != null) {
+      entity.setEditLink(URIUtils.getURI(base, resource.getPayload().getEditLink().getHref()));
     }
 
-    for (Link link : resource.getAssociationLinks()) {
+    for (Link link : resource.getPayload().getAssociationLinks()) {
       entity.addLink(new ODataLink.Builder().setVersion(client.getServiceVersion()).
               setURI(URIUtils.getURI(base, link.getHref())).
               setType(ODataLinkType.ASSOCIATION).setTitle(link.getTitle()).build());
     }
 
-    odataLinks(resource, entity, base);
+    odataNavigationLinks(
+            edmType, resource.getPayload(), entity, resource.getMetadataETag(), base);
 
-    for (Link link : resource.getMediaEditLinks()) {
+    for (Link link : resource.getPayload().getMediaEditLinks()) {
       entity.addLink(new ODataLink.Builder().setVersion(client.getServiceVersion()).
               setURI(URIUtils.getURI(base, link.getHref())).
               setType(ODataLinkType.MEDIA_EDIT).setTitle(link.getTitle()).build());
     }
 
-    for (ODataOperation operation : resource.getOperations()) {
+    for (ODataOperation operation : resource.getPayload().getOperations()) {
       operation.setTarget(URIUtils.getURI(base, operation.getTarget()));
       entity.getOperations().add(operation);
     }
 
-    if (resource.isMediaEntry()) {
+    if (resource.getPayload().isMediaEntry()) {
       entity.setMediaEntity(true);
-      entity.setMediaContentSource(resource.getMediaContentSource());
-      entity.setMediaContentType(resource.getMediaContentType());
-      entity.setMediaETag(resource.getMediaETag());
+      entity.setMediaContentSource(resource.getPayload().getMediaContentSource());
+      entity.setMediaContentType(resource.getPayload().getMediaContentType());
+      entity.setMediaETag(resource.getPayload().getMediaETag());
     }
 
-    copyProperties(resource.getProperties(), entity, base);
+    for (Property property : resource.getPayload().getProperties()) {
+      add(entity, getODataProperty(
+              new ResWrap<Property>(resource.getContextURL(), resource.getMetadataETag(), property)));
+    }
 
     return entity;
   }
 
-  protected ODataValue getODataValue(final Property resource, final URI base) {
-    ODataValue value = null;
+  protected EdmTypeInfo buildTypeInfo(final ResWrap<Property> resource) {
+    FullQualifiedName typeName = null;
+    final EdmType entityType = findEntityType(resource.getContextURL(), resource.getMetadataETag());
+    if (entityType instanceof EdmStructuredType) {
+      final EdmProperty edmProperty = ((EdmStructuredType) entityType).
+              getStructuralProperty(resource.getPayload().getName());
+      if (edmProperty != null) {
+        typeName = edmProperty.getType().getFullQualifiedName();
+      }
+    }
+
+    EdmTypeInfo typeInfo = null;
+    if (typeName == null) {
+      if (resource.getPayload().getType() != null) {
+        typeInfo = new EdmTypeInfo.Builder().setTypeExpression(resource.getPayload().getType()).build();
+      }
+    } else {
+      typeInfo = new EdmTypeInfo.Builder().setTypeExpression(typeName.toString()).build();
+    }
+    return typeInfo;
+  }
 
-    final EdmTypeInfo typeInfo = resource.getType() == null
-            ? null
-            : new EdmTypeInfo.Builder().setTypeExpression(resource.getType()).build();
-    if (resource.getValue().isPrimitive()) {
+  protected ODataValue getODataValue(final ResWrap<Property> resource) {
+    final EdmTypeInfo typeInfo = buildTypeInfo(resource);
+
+    ODataValue value = null;
+    if (resource.getPayload().getValue().isPrimitive()) {
       value = client.getObjectFactory().newPrimitiveValueBuilder().
-              setText(resource.getValue().asPrimitive().get()).
+              setText(resource.getPayload().getValue().asPrimitive().get()).
               setType(typeInfo == null
                       ? null
                       : EdmPrimitiveTypeKind.valueOfFQN(
                               client.getServiceVersion(), typeInfo.getFullQualifiedName().toString())).build();
-    } else if (resource.getValue().isGeospatial()) {
+    } else if (resource.getPayload().getValue().isGeospatial()) {
       value = client.getObjectFactory().newPrimitiveValueBuilder().
-              setValue(resource.getValue().asGeospatial().get()).
+              setValue(resource.getPayload().getValue().asGeospatial().get()).
               setType(typeInfo == null
                       || EdmPrimitiveTypeKind.Geography.getFullQualifiedName().equals(typeInfo.getFullQualifiedName())
                       || EdmPrimitiveTypeKind.Geometry.getFullQualifiedName().equals(typeInfo.getFullQualifiedName())
-                      ? resource.getValue().asGeospatial().get().getEdmPrimitiveTypeKind()
+                      ? resource.getPayload().getValue().asGeospatial().get().getEdmPrimitiveTypeKind()
                       : EdmPrimitiveTypeKind.valueOfFQN(
                               client.getServiceVersion(), typeInfo.getFullQualifiedName().toString())).build();
-    } else if (resource.getValue().isComplex()) {
+    } else if (resource.getPayload().getValue().isComplex()) {
       value = client.getObjectFactory().newComplexValue(typeInfo == null
               ? null : typeInfo.getFullQualifiedName().toString());
 
-      for (Property property : resource.getValue().asComplex().get()) {
-        value.asComplex().add(getODataProperty(property));
+      for (Property property : resource.getPayload().getValue().asComplex().get()) {
+        value.asComplex().add(getODataProperty(
+                new ResWrap<Property>(resource.getContextURL(), resource.getMetadataETag(), property)));
       }
-    } else if (resource.getValue().isCollection()) {
+    } else if (resource.getPayload().getValue().isCollection()) {
       value = client.getObjectFactory().newCollectionValue(typeInfo == null
               ? null : "Collection(" + typeInfo.getFullQualifiedName().toString() + ")");
 
-      for (Value _value : resource.getValue().asCollection().get()) {
+      for (Value _value : resource.getPayload().getValue().asCollection().get()) {
         final JSONPropertyImpl fake = new JSONPropertyImpl();
         fake.setValue(_value);
-        value.asCollection().add(getODataValue(fake, base));
+        value.asCollection().add(getODataValue(
+                new ResWrap<Property>(resource.getContextURL(), resource.getMetadataETag(), fake)));
       }
     }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataReader.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataReader.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataReader.java
index b7d29f7..0df51a5 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataReader.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataReader.java
@@ -19,6 +19,7 @@
 package org.apache.olingo.client.core.op;
 
 import java.io.InputStream;
+import java.net.URI;
 import java.util.List;
 import org.apache.commons.io.IOUtils;
 import org.apache.olingo.client.api.CommonODataClient;
@@ -35,7 +36,7 @@ import org.apache.olingo.commons.api.domain.ODataValue;
 import org.apache.olingo.client.api.edm.xml.XMLMetadata;
 import org.apache.olingo.client.api.op.CommonODataReader;
 import org.apache.olingo.client.core.edm.EdmClientImpl;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.data.Entry;
 import org.apache.olingo.commons.api.data.Feed;
 import org.apache.olingo.commons.api.edm.Edm;
@@ -74,7 +75,7 @@ public abstract class AbstractODataReader implements CommonODataReader {
   @Override
   public ODataServiceDocument readServiceDocument(final InputStream input, final ODataFormat format) {
     return client.getBinder().getODataServiceDocument(
-            client.getDeserializer().toServiceDocument(input, format).getObject());
+            client.getDeserializer().toServiceDocument(input, format).getPayload());
   }
 
   @Override
@@ -84,48 +85,60 @@ public abstract class AbstractODataReader implements CommonODataReader {
 
   @Override
   @SuppressWarnings("unchecked")
-  public <T> Container<T> read(final InputStream src, final String format, final Class<T> reference) {
-    Container<T> res;
+  public <T> ResWrap<T> read(final InputStream src, final String format, final Class<T> reference) {
+    ResWrap<T> res;
 
     try {
       if (ODataEntitySetIterator.class.isAssignableFrom(reference)) {
-        res = new Container<T>(
-                null, null, (T) new ODataEntitySetIterator(client, src, ODataPubFormat.fromString(format)));
+        res = new ResWrap<T>(
+                (URI) null,
+                null,
+                reference.cast(new ODataEntitySetIterator<CommonODataEntitySet, CommonODataEntity>(
+                                client, src, ODataPubFormat.fromString(format))));
       } else if (CommonODataEntitySet.class.isAssignableFrom(reference)) {
-        final Container<Feed> container = client.getDeserializer().toFeed(src, ODataPubFormat.fromString(format));
-        res = new Container<T>(
-                container.getContextURL(),
-                container.getMetadataETag(),
-                (T) client.getBinder().getODataEntitySet(container.getObject()));
+        final ResWrap<Feed> resource = client.getDeserializer().toFeed(src, ODataPubFormat.fromString(format));
+        res = new ResWrap<T>(
+                resource.getContextURL(),
+                resource.getMetadataETag(),
+                reference.cast(client.getBinder().getODataEntitySet(resource)));
       } else if (CommonODataEntity.class.isAssignableFrom(reference)) {
-        final Container<Entry> container = client.getDeserializer().toEntry(src, ODataPubFormat.fromString(format));
-        res = new Container<T>(
+        final ResWrap<Entry> container = client.getDeserializer().toEntry(src, ODataPubFormat.fromString(format));
+        res = new ResWrap<T>(
                 container.getContextURL(),
                 container.getMetadataETag(),
-                (T) client.getBinder().getODataEntity(container.getObject()));
+                reference.cast(client.getBinder().getODataEntity(container)));
       } else if (CommonODataProperty.class.isAssignableFrom(reference)) {
-        final Container<Property> container = client.getDeserializer().toProperty(src, ODataFormat.fromString(format));
-        res = new Container<T>(
+        final ResWrap<Property> container = client.getDeserializer().toProperty(src, ODataFormat.fromString(format));
+        res = new ResWrap<T>(
                 container.getContextURL(),
                 container.getMetadataETag(),
-                (T) client.getBinder().getODataProperty(container.getObject()));
+                reference.cast(client.getBinder().getODataProperty(container)));
       } else if (ODataValue.class.isAssignableFrom(reference)) {
-        res = new Container<T>(null, null, (T) client.getObjectFactory().newPrimitiveValueBuilder().
-                setType(ODataValueFormat.fromString(format) == ODataValueFormat.TEXT
-                        ? EdmPrimitiveTypeKind.String : EdmPrimitiveTypeKind.Stream).
-                setText(IOUtils.toString(src)).
-                build());
+        res = new ResWrap<T>(
+                (URI) null,
+                null,
+                reference.cast(client.getObjectFactory().newPrimitiveValueBuilder().
+                        setType(ODataValueFormat.fromString(format) == ODataValueFormat.TEXT
+                                ? EdmPrimitiveTypeKind.String : EdmPrimitiveTypeKind.Stream).
+                        setText(IOUtils.toString(src)).
+                        build()));
       } else if (XMLMetadata.class.isAssignableFrom(reference)) {
-        res = new Container<T>(null, null, (T) readMetadata(src));
+        res = new ResWrap<T>(
+                (URI) null,
+                null,
+                reference.cast(readMetadata(src)));
       } else if (ODataServiceDocument.class.isAssignableFrom(reference)) {
-        final Container<ServiceDocument> container =
+        final ResWrap<ServiceDocument> resource =
                 client.getDeserializer().toServiceDocument(src, ODataFormat.fromString(format));
-        res = new Container<T>(
-                container.getContextURL(),
-                container.getMetadataETag(),
-                (T) client.getBinder().getODataServiceDocument(container.getObject()));
+        res = new ResWrap<T>(
+                resource.getContextURL(),
+                resource.getMetadataETag(),
+                reference.cast(client.getBinder().getODataServiceDocument(resource.getPayload())));
       } else if (ODataError.class.isAssignableFrom(reference)) {
-        res = new Container<T>(null, null, (T) readError(src, !format.toString().contains("json")));
+        res = new ResWrap<T>(
+                (URI) null,
+                null,
+                reference.cast(readError(src, !format.toString().contains("json"))));
       } else {
         throw new IllegalArgumentException("Invalid reference type " + reference);
       }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataBinderImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataBinderImpl.java
index c0ce3f3..75d3eaa 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataBinderImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataBinderImpl.java
@@ -18,9 +18,6 @@
  */
 package org.apache.olingo.client.core.op.impl.v3;
 
-import java.net.URI;
-import java.util.List;
-import org.apache.olingo.commons.api.data.v3.LinkCollection;
 import org.apache.olingo.client.api.domain.v3.ODataLinkCollection;
 import org.apache.olingo.client.api.op.v3.ODataBinder;
 import org.apache.olingo.client.core.op.AbstractODataBinder;
@@ -28,6 +25,8 @@ import org.apache.olingo.client.core.v3.ODataClientImpl;
 import org.apache.olingo.commons.api.data.Entry;
 import org.apache.olingo.commons.api.data.Feed;
 import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.data.ResWrap;
+import org.apache.olingo.commons.api.data.v3.LinkCollection;
 import org.apache.olingo.commons.api.domain.CommonODataEntity;
 import org.apache.olingo.commons.api.domain.CommonODataEntitySet;
 import org.apache.olingo.commons.api.domain.CommonODataProperty;
@@ -73,35 +72,18 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder
   }
 
   @Override
-  public ODataEntitySet getODataEntitySet(final Feed resource) {
+  public ODataEntitySet getODataEntitySet(final ResWrap<Feed> resource) {
     return (ODataEntitySet) super.getODataEntitySet(resource);
   }
 
   @Override
-  public ODataEntitySet getODataEntitySet(final Feed resource, final URI defaultBaseURI) {
-    return (ODataEntitySet) super.getODataEntitySet(resource, defaultBaseURI);
-  }
-
-  @Override
-  protected void copyProperties(final List<Property> src, final CommonODataEntity dst, final URI base) {
-    for (Property property : src) {
-      add(dst, getODataProperty(property));
-    }
-  }
-
-  @Override
-  public ODataEntity getODataEntity(final Entry resource) {
+  public ODataEntity getODataEntity(final ResWrap<Entry> resource) {
     return (ODataEntity) super.getODataEntity(resource);
   }
 
   @Override
-  public ODataEntity getODataEntity(final Entry resource, final URI defaultBaseURI) {
-    return (ODataEntity) super.getODataEntity(resource, defaultBaseURI);
-  }
-
-  @Override
-  public ODataProperty getODataProperty(final Property property) {
-    return new ODataPropertyImpl(property.getName(), getODataValue(property, null));
+  public ODataProperty getODataProperty(final ResWrap<Property> property) {
+    return new ODataPropertyImpl(property.getPayload().getName(), getODataValue(property));
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataDeserializerImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataDeserializerImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataDeserializerImpl.java
index 01bacbe..2c5ae59 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataDeserializerImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataDeserializerImpl.java
@@ -31,7 +31,7 @@ import org.apache.olingo.client.core.data.v3.JSONServiceDocumentImpl;
 import org.apache.olingo.client.core.data.v4.XMLServiceDocumentImpl;
 import org.apache.olingo.client.core.edm.xml.v3.EdmxImpl;
 import org.apache.olingo.client.core.edm.xml.v3.XMLMetadataImpl;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.core.op.AbstractODataDeserializer;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 
@@ -53,14 +53,14 @@ public class ODataDeserializerImpl extends AbstractODataDeserializer implements
   }
 
   @Override
-  public Container<ServiceDocument> toServiceDocument(final InputStream input, final ODataFormat format) {
+  public ResWrap<ServiceDocument> toServiceDocument(final InputStream input, final ODataFormat format) {
     return format == ODataFormat.XML
             ? this.<ServiceDocument, XMLServiceDocumentImpl>xml(input, XMLServiceDocumentImpl.class)
             : this.<ServiceDocument, JSONServiceDocumentImpl>json(input, JSONServiceDocumentImpl.class);
   }
 
   @Override
-  public Container<LinkCollection> toLinkCollection(final InputStream input, final ODataFormat format) {
+  public ResWrap<LinkCollection> toLinkCollection(final InputStream input, final ODataFormat format) {
     return format == ODataFormat.XML
             ? this.<LinkCollection, XMLLinkCollectionImpl>atom(input, XMLLinkCollectionImpl.class)
             : this.<LinkCollection, JSONLinkCollectionImpl>json(input, JSONLinkCollectionImpl.class);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataReaderImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataReaderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataReaderImpl.java
index 8663e79..2b8bc5d 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataReaderImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataReaderImpl.java
@@ -25,8 +25,7 @@ import org.apache.olingo.commons.api.format.ODataFormat;
 import org.apache.olingo.client.api.op.v3.ODataReader;
 import org.apache.olingo.client.api.v3.ODataClient;
 import org.apache.olingo.client.core.op.AbstractODataReader;
-import org.apache.olingo.commons.api.data.Container;
-import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.data.v3.LinkCollection;
 import org.apache.olingo.commons.api.domain.v3.ODataEntity;
 import org.apache.olingo.commons.api.domain.v3.ODataEntitySet;
@@ -43,39 +42,36 @@ public class ODataReaderImpl extends AbstractODataReader implements ODataReader
 
   @Override
   public ODataEntitySet readEntitySet(final InputStream input, final ODataPubFormat format) {
-    return ((ODataClient) client).getBinder().
-            getODataEntitySet(client.getDeserializer().toFeed(input, format).getObject());
+    return ((ODataClient) client).getBinder().getODataEntitySet(client.getDeserializer().toFeed(input, format));
   }
 
   @Override
   public ODataEntity readEntity(final InputStream input, final ODataPubFormat format) {
-    return ((ODataClient) client).getBinder().
-            getODataEntity(client.getDeserializer().toEntry(input, format).getObject());
+    return ((ODataClient) client).getBinder().getODataEntity(client.getDeserializer().toEntry(input, format));
   }
 
   @Override
   public ODataProperty readProperty(final InputStream input, final ODataFormat format) {
-    final Property property = client.getDeserializer().toProperty(input, format).getObject();
-    return ((ODataClient) client).getBinder().getODataProperty(property);
+    return ((ODataClient) client).getBinder().getODataProperty(client.getDeserializer().toProperty(input, format));
   }
 
   @Override
   public ODataLinkCollection readLinks(final InputStream input, final ODataFormat format) {
     return ((ODataClient) client).getBinder().getLinkCollection(
-            ((ODataClient) client).getDeserializer().toLinkCollection(input, format).getObject());
+            ((ODataClient) client).getDeserializer().toLinkCollection(input, format).getPayload());
   }
 
   @Override
   @SuppressWarnings("unchecked")
-  public <T> Container<T> read(final InputStream src, final String format, final Class<T> reference) {
+  public <T> ResWrap<T> read(final InputStream src, final String format, final Class<T> reference) {
     if (ODataLinkCollection.class.isAssignableFrom(reference)) {
-      final Container<LinkCollection> container =
+      final ResWrap<LinkCollection> container =
               ((ODataClient) client).getDeserializer().toLinkCollection(src, ODataFormat.fromString(format));
 
-      return new Container<T>(
+      return new ResWrap<T>(
               container.getContextURL(),
               container.getMetadataETag(),
-              (T) ((ODataClient) client).getBinder().getLinkCollection(container.getObject()));
+              (T) ((ODataClient) client).getBinder().getLinkCollection(container.getPayload()));
     } else {
       return super.read(src, format, reference);
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java
index 950ea53..407ab1b 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java
@@ -18,11 +18,10 @@
  */
 package org.apache.olingo.client.core.op.impl.v4;
 
-import java.net.URI;
-import java.util.List;
 import org.apache.olingo.client.api.data.ServiceDocument;
 import org.apache.olingo.client.api.data.ServiceDocumentItem;
 import org.apache.olingo.client.api.op.v4.ODataBinder;
+import org.apache.olingo.client.api.v4.EdmEnabledODataClient;
 import org.apache.olingo.client.api.v4.ODataClient;
 import org.apache.olingo.client.core.op.AbstractODataBinder;
 import org.apache.olingo.client.core.uri.URIUtils;
@@ -30,6 +29,7 @@ import org.apache.olingo.commons.api.data.Entry;
 import org.apache.olingo.commons.api.data.Feed;
 import org.apache.olingo.commons.api.data.LinkedComplexValue;
 import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.data.Value;
 import org.apache.olingo.commons.api.domain.CommonODataEntity;
 import org.apache.olingo.commons.api.domain.CommonODataEntitySet;
@@ -40,6 +40,7 @@ import org.apache.olingo.commons.api.domain.v4.ODataEntity;
 import org.apache.olingo.commons.api.domain.v4.ODataEntitySet;
 import org.apache.olingo.commons.api.domain.v4.ODataLinkedComplexValue;
 import org.apache.olingo.commons.api.domain.v4.ODataProperty;
+import org.apache.olingo.commons.api.edm.EdmComplexType;
 import org.apache.olingo.commons.core.data.EnumValueImpl;
 import org.apache.olingo.commons.core.data.LinkedComplexValueImpl;
 import org.apache.olingo.commons.core.domain.v4.ODataPropertyImpl;
@@ -143,68 +144,52 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder
   }
 
   @Override
-  public ODataEntitySet getODataEntitySet(final Feed resource) {
+  public ODataEntitySet getODataEntitySet(final ResWrap<Feed> resource) {
     return (ODataEntitySet) super.getODataEntitySet(resource);
   }
 
   @Override
-  public ODataEntitySet getODataEntitySet(final Feed resource, final URI defaultBaseURI) {
-    return (ODataEntitySet) super.getODataEntitySet(resource, defaultBaseURI);
-  }
-
-  @Override
-  protected void copyProperties(final List<Property> src, final CommonODataEntity dst, final URI base) {
-    for (Property property : src) {
-      add(dst, getODataProperty(property, base));
-    }
-  }
-
-  @Override
-  public ODataEntity getODataEntity(final Entry resource) {
-    return (ODataEntity) super.getODataEntity(resource);
-  }
-
-  @Override
-  public ODataEntity getODataEntity(final Entry resource, final URI defaultBaseURI) {
-    final ODataEntity entity = (ODataEntity) super.getODataEntity(resource, defaultBaseURI);
-    entity.setReference(resource.getId());
+  public ODataEntity getODataEntity(final ResWrap<Entry> resource) {
+    final ODataEntity entity = (ODataEntity) super.getODataEntity(resource);
+    entity.setReference(resource.getPayload().getId());
     return entity;
   }
 
   @Override
-  public ODataProperty getODataProperty(final Property property) {
-    return getODataProperty(property, null);
+  public ODataProperty getODataProperty(final ResWrap<Property> property) {
+    return new ODataPropertyImpl(property.getPayload().getName(), getODataValue(property));
   }
 
   @Override
-  public ODataProperty getODataProperty(final Property property, final URI base) {
-    return new ODataPropertyImpl(property.getName(), getODataValue(property, base));
-  }
-
-  @Override
-  protected ODataValue getODataValue(final Property resource, final URI base) {
-    final EdmTypeInfo typeInfo = resource.getType() == null
-            ? null
-            : new EdmTypeInfo.Builder().setTypeExpression(resource.getType()).build();
+  protected ODataValue getODataValue(final ResWrap<Property> resource) {
+    final EdmTypeInfo typeInfo = buildTypeInfo(resource);
 
     ODataValue value;
-    if (resource.getValue().isEnum()) {
+    if (resource.getPayload().getValue().isEnum()) {
       value = ((ODataClient) client).getObjectFactory().newEnumValue(
               typeInfo == null ? null : typeInfo.getFullQualifiedName().toString(),
-              resource.getValue().asEnum().get());
-    } else if (resource.getValue().isLinkedComplex()) {
+              resource.getPayload().getValue().asEnum().get());
+    } else if (resource.getPayload().getValue().isLinkedComplex()) {
       final ODataLinkedComplexValue lcValue = ((ODataClient) client).getObjectFactory().
               newLinkedComplexValue(typeInfo == null ? null : typeInfo.getFullQualifiedName().toString());
 
-      for (Property property : resource.getValue().asComplex().get()) {
-        lcValue.add(getODataProperty(property));
+      for (Property property : resource.getPayload().getValue().asComplex().get()) {
+        lcValue.add(getODataProperty(
+                new ResWrap<Property>(resource.getContextURL(), resource.getMetadataETag(), property)));
+      }
+
+      EdmComplexType edmType = null;
+      if (client instanceof EdmEnabledODataClient && typeInfo != null) {
+        edmType = ((EdmEnabledODataClient) client).getEdm(resource.getMetadataETag()).
+                getComplexType(typeInfo.getFullQualifiedName());
       }
 
-      odataLinks(resource.getValue().asLinkedComplex(), lcValue, base);
+      odataNavigationLinks(edmType, resource.getPayload().getValue().asLinkedComplex(), lcValue,
+              resource.getMetadataETag(), resource.getContextURL() == null ? null : resource.getContextURL().getURI());
 
       value = lcValue;
     } else {
-      value = super.getODataValue(resource, base);
+      value = super.getODataValue(resource);
     }
 
     return value;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataDeserializerImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataDeserializerImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataDeserializerImpl.java
index 08d3556..9bb6727 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataDeserializerImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataDeserializerImpl.java
@@ -28,7 +28,7 @@ import org.apache.olingo.client.core.data.v4.JSONServiceDocumentImpl;
 import org.apache.olingo.client.core.data.v4.XMLServiceDocumentImpl;
 import org.apache.olingo.client.core.edm.xml.v4.EdmxImpl;
 import org.apache.olingo.client.core.edm.xml.v4.XMLMetadataImpl;
-import org.apache.olingo.commons.api.data.Container;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.core.op.AbstractODataDeserializer;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 
@@ -50,7 +50,7 @@ public class ODataDeserializerImpl extends AbstractODataDeserializer implements
   }
 
   @Override
-  public Container<ServiceDocument> toServiceDocument(final InputStream input, final ODataFormat format) {
+  public ResWrap<ServiceDocument> toServiceDocument(final InputStream input, final ODataFormat format) {
     return format == ODataFormat.XML
             ? this.<ServiceDocument, XMLServiceDocumentImpl>xml(input, XMLServiceDocumentImpl.class)
             : this.<ServiceDocument, JSONServiceDocumentImpl>json(input, JSONServiceDocumentImpl.class);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataReaderImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataReaderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataReaderImpl.java
index 41f1e3b..eb446d1 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataReaderImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataReaderImpl.java
@@ -22,7 +22,6 @@ import java.io.InputStream;
 import org.apache.olingo.client.api.op.v4.ODataReader;
 import org.apache.olingo.client.api.v4.ODataClient;
 import org.apache.olingo.client.core.op.AbstractODataReader;
-import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.domain.v4.ODataEntity;
 import org.apache.olingo.commons.api.domain.v4.ODataEntitySet;
 import org.apache.olingo.commons.api.domain.v4.ODataProperty;
@@ -39,19 +38,16 @@ public class ODataReaderImpl extends AbstractODataReader implements ODataReader
 
   @Override
   public ODataEntitySet readEntitySet(final InputStream input, final ODataPubFormat format) {
-    return ((ODataClient) client).getBinder().
-            getODataEntitySet(client.getDeserializer().toFeed(input, format).getObject());
+    return ((ODataClient) client).getBinder().getODataEntitySet(client.getDeserializer().toFeed(input, format));
   }
 
   @Override
   public ODataEntity readEntity(final InputStream input, final ODataPubFormat format) {
-    return ((ODataClient) client).getBinder().
-            getODataEntity(client.getDeserializer().toEntry(input, format).getObject());
+    return ((ODataClient) client).getBinder().getODataEntity(client.getDeserializer().toEntry(input, format));
   }
 
   @Override
   public ODataProperty readProperty(final InputStream input, final ODataFormat format) {
-    final Property property = client.getDeserializer().toProperty(input, format).getObject();
-    return ((ODataClient) client).getBinder().getODataProperty(property);
+    return ((ODataClient) client).getBinder().getODataProperty(client.getDeserializer().toProperty(input, format));
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/EdmEnabledODataClientImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/EdmEnabledODataClientImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/EdmEnabledODataClientImpl.java
new file mode 100644
index 0000000..e0f6dda
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/EdmEnabledODataClientImpl.java
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+package org.apache.olingo.client.core.v3;
+
+import org.apache.olingo.client.api.communication.request.retrieve.EdmMetadataRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.v3.EdmEnabledODataClient;
+import org.apache.olingo.commons.api.edm.Edm;
+
+public class EdmEnabledODataClientImpl extends ODataClientImpl implements EdmEnabledODataClient {
+
+  private final String serviceRoot;
+
+  private Edm edm;
+
+  public EdmEnabledODataClientImpl(final String serviceRoot) {
+    super();
+
+    this.serviceRoot = serviceRoot;
+  }
+
+  @Override
+  public String getServiceRoot() {
+    return serviceRoot;
+  }
+
+  @Override
+  public final Edm getEdm(final String metadataETag) {
+    synchronized (this) {
+      final EdmMetadataRequest metadataReq = getRetrieveRequestFactory().getMetadataRequest(serviceRoot);
+      final ODataRetrieveResponse<Edm> metadataRes = metadataReq.execute();
+      this.edm = metadataRes.getBody();
+    }
+    return this.edm;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/EdmEnabledODataClientImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/EdmEnabledODataClientImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/EdmEnabledODataClientImpl.java
new file mode 100644
index 0000000..238045f
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/EdmEnabledODataClientImpl.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+package org.apache.olingo.client.core.v4;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.client.api.communication.request.retrieve.EdmMetadataRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.v4.EdmEnabledODataClient;
+import org.apache.olingo.commons.api.edm.Edm;
+
+public class EdmEnabledODataClientImpl extends ODataClientImpl implements EdmEnabledODataClient {
+
+  private final String serviceRoot;
+
+  private Edm edm;
+
+  private String metadataETag;
+
+  public EdmEnabledODataClientImpl(final String serviceRoot) {
+    super();
+    
+    this.serviceRoot = serviceRoot;
+    this.metadataETag = StringUtils.EMPTY;
+  }
+
+  @Override
+  public String getServiceRoot() {
+    return serviceRoot;
+  }
+
+  @Override
+  public final Edm getEdm(final String metadataETag) {
+    synchronized (this) {
+      if (this.metadataETag != null && !this.metadataETag.equals(metadataETag)) {
+        final EdmMetadataRequest metadataReq = getRetrieveRequestFactory().getMetadataRequest(serviceRoot);
+        final ODataRetrieveResponse<Edm> metadataRes = metadataReq.execute();
+        this.metadataETag = metadataRes.getETag();
+        this.edm = metadataRes.getBody();
+      }
+    }
+    return this.edm;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/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 22719af..9f06dc4 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
@@ -297,7 +297,7 @@ public abstract class AbstractTestITCase extends AbstractBaseTestITCase {
     final ODataRetrieveResponse<ODataEntity> res = getClient().getRetrieveRequestFactory().
             getEntityRequest(uri).execute();
     try {
-      return res.getEtag();
+      return res.getETag();
     } finally {
       res.close();
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/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 2868f8c..9b9ba9c 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
@@ -79,7 +79,7 @@ public class AsyncTestITCase extends AbstractTestITCase {
 
     final ODataEntityUpdateRequest<ODataEntity> updateReq =
             client.getCUDRequestFactory().getEntityUpdateRequest(uri, UpdateType.MERGE, entity);
-    updateReq.setIfMatch(entityRes.getEtag());
+    updateReq.setIfMatch(entityRes.getETag());
     final Future<ODataEntityUpdateResponse<ODataEntity>> futureRes = updateReq.asyncExecute();
 
     while (!futureRes.isDone()) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java
index 7c3bb1d..2693fb2 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntityRetrieveTestITCase.java
@@ -18,6 +18,11 @@
  */
 package org.apache.olingo.client.core.it.v3;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
 import java.util.LinkedHashMap;
 import java.util.List;
 import org.apache.commons.lang3.StringUtils;
@@ -26,6 +31,7 @@ import org.apache.olingo.client.api.communication.request.retrieve.ODataRawReque
 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.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.domain.CommonODataEntity;
 import org.apache.olingo.commons.api.domain.CommonODataEntitySet;
 import org.apache.olingo.commons.api.domain.CommonODataProperty;
@@ -33,14 +39,10 @@ import org.apache.olingo.commons.api.domain.ODataInlineEntity;
 import org.apache.olingo.commons.api.domain.ODataInlineEntitySet;
 import org.apache.olingo.commons.api.domain.ODataLink;
 import org.apache.olingo.commons.api.domain.v3.ODataEntity;
+import org.apache.olingo.commons.api.domain.v3.ODataEntitySet;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.format.ODataPubFormat;
 import org.apache.olingo.commons.core.op.ResourceFactory;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
 import org.junit.Test;
 
 /**
@@ -154,11 +156,11 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
     final ODataRawResponse res = req.execute();
     assertNotNull(res);
 
-    final CommonODataEntitySet entitySet = res.getBodyAs(CommonODataEntitySet.class);
+    final ResWrap<ODataEntitySet> entitySet = res.getBodyAs(ODataEntitySet.class);
     assertNull(entitySet);
 
-    final CommonODataEntity entity = res.getBodyAs(CommonODataEntity.class);
-    assertNotNull(entity);
+    final ResWrap<ODataEntity> entity = res.getBodyAs(ODataEntity.class);
+    assertNotNull(entity.getPayload());
   }
 
   @Test
@@ -219,7 +221,7 @@ public class EntityRetrieveTestITCase extends AbstractTestITCase {
     final ODataRetrieveResponse<ODataEntity> res = req.execute();
     assertEquals(200, res.getStatusCode());
 
-    final String etag = res.getEtag();
+    final String etag = res.getETag();
     assertTrue(StringUtils.isNotBlank(etag));
 
     final CommonODataEntity product = res.getBody();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/15e7718a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java
index a8b1c51..abf0964 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/EntitySetTestITCase.java
@@ -32,6 +32,7 @@ import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse
 import org.apache.olingo.client.api.domain.ODataEntitySetIterator;
 import org.apache.olingo.client.api.uri.v3.URIBuilder;
 import org.apache.olingo.client.core.uri.URIUtils;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.domain.v3.ODataEntity;
 import org.apache.olingo.commons.api.domain.v3.ODataEntitySet;
 import org.apache.olingo.commons.api.format.ODataPubFormat;
@@ -155,8 +156,8 @@ public class EntitySetTestITCase extends AbstractTestITCase {
     final ODataRawResponse res = req.execute();
     assertNotNull(res);
 
-    final ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class);
-    assertEquals(10, entitySet.getCount());
+    final ResWrap<ODataEntitySet> entitySet = res.getBodyAs(ODataEntitySet.class);
+    assertEquals(10, entitySet.getPayload().getCount());
   }
 
   private void rawRequest(final ODataPubFormat format) {
@@ -169,7 +170,7 @@ public class EntitySetTestITCase extends AbstractTestITCase {
     final ODataRawResponse res = req.execute();
     assertNotNull(res);
 
-    final ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class);
-    assertNotNull(entitySet);
+    final ResWrap<ODataEntitySet> entitySet = res.getBodyAs(ODataEntitySet.class);
+    assertNotNull(entitySet.getPayload());
   }
 }