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/01 16:18:40 UTC

[13/51] [abbrv] git commit: [OLINGO-205] refactoring in order to add context url and metadata etag management

[OLINGO-205] refactoring in order to add context url and metadata etag management


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

Branch: refs/heads/master
Commit: e4bf21325df8f96927096fa875ff1db5fda49662
Parents: cde94fc
Author: fmartelli <fa...@gmail.com>
Authored: Thu Mar 27 15:41:09 2014 +0100
Committer: fmartelli <fa...@gmail.com>
Committed: Thu Mar 27 15:41:09 2014 +0100

----------------------------------------------------------------------
 .../communication/response/ODataResponse.java   | 25 +++++
 .../api/domain/ODataEntitySetIterator.java      |  6 +-
 .../client/api/op/ClientODataDeserializer.java  |  3 +-
 .../olingo/client/api/op/CommonODataReader.java |  3 +-
 .../client/api/op/v3/ODataDeserializer.java     |  3 +-
 .../retrieve/ODataEntityRequestImpl.java        |  8 +-
 .../retrieve/ODataEntitySetRequestImpl.java     | 14 ++-
 .../request/retrieve/ODataRawRequestImpl.java   | 10 +-
 .../response/AbstractODataResponse.java         | 40 ++++++++
 .../client/core/op/AbstractODataReader.java     | 63 +++++++++----
 .../core/op/impl/v3/ODataDeserializerImpl.java  | 14 +--
 .../client/core/op/impl/v3/ODataReaderImpl.java | 21 +++--
 .../core/op/impl/v4/ODataDeserializerImpl.java  |  7 +-
 .../client/core/op/impl/v4/ODataReaderImpl.java |  1 -
 .../client/core/AbstractPrimitiveTest.java      |  4 +-
 .../apache/olingo/client/core/AbstractTest.java |  2 -
 .../core/it/v3/QueryOptionsTestITCase.java      |  2 +-
 .../client/core/it/v4/EntitySetTestITCase.java  |  4 +-
 .../apache/olingo/client/core/v3/AtomTest.java  |  8 +-
 .../olingo/client/core/v3/EntitySetTest.java    |  2 +-
 .../olingo/client/core/v3/EntityTest.java       | 10 +-
 .../apache/olingo/commons/api/Constants.java    |  4 +
 .../olingo/commons/api/data/Container.java      | 76 +++++++++++++++
 .../commons/api/op/CommonODataDeserializer.java |  8 +-
 .../commons/core/data/AbstractAtomDealer.java   |  4 +
 .../commons/core/data/AbstractAtomObject.java   | 97 --------------------
 .../olingo/commons/core/data/AbstractEntry.java |  2 +-
 .../commons/core/data/AbstractODataObject.java  | 97 ++++++++++++++++++++
 .../commons/core/data/AtomDeserializer.java     | 61 ++++++------
 .../olingo/commons/core/data/AtomFeedImpl.java  |  2 +-
 .../commons/core/data/AtomSerializer.java       | 10 +-
 .../core/op/AbstractODataDeserializer.java      | 53 +++++++----
 32 files changed, 440 insertions(+), 224 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
index 65434ec..5498d1b 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
@@ -19,6 +19,7 @@
 package org.apache.olingo.client.api.communication.response;
 
 import java.io.InputStream;
+import java.net.URI;
 import java.util.Collection;
 import java.util.Map;
 import org.apache.olingo.client.api.communication.header.HeaderName;
@@ -58,6 +59,30 @@ public interface ODataResponse {
    * @return ETag header value, if provided
    */
   String getEtag();
+  
+  /**
+   * The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
+   * fragment identifying the relevant portion of the metadata document.
+   * <br />
+   * Request payloads generally do not require context URLs as the type of the payload can generally be determined from
+   * the request URL.
+   * <br />
+   * For details on how the context URL is used to describe a payload, see the relevant sections in the particular
+   * format.
+   *
+   * @return context URL.
+   */
+  URI getContextURL();
+
+  /**
+   * An ETag header MAY also be returned on a metadata document request or service document request to allow the client
+   * subsequently to make a conditional request for the metadata or service document. Clients can also compare the value
+   * of the ETag header returned from a metadata document request to the metadata ETag returned in a response in order
+   * to verify the version of the metadata used to generate that response.
+   *
+   * @return metadata ETag.
+   */
+  String getMetadataETag();
 
   /**
    * Gets the content type.

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySetIterator.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySetIterator.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySetIterator.java
index 9d720bf..e5eeeed 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySetIterator.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySetIterator.java
@@ -170,7 +170,7 @@ public class ODataEntitySetIterator implements Iterator<ODataEntity> {
 
     Entry jsonEntry = null;
     try {
-      int c = 0;
+      int c;
 
       boolean foundNewOne = false;
 
@@ -203,7 +203,7 @@ public class ODataEntitySetIterator implements Iterator<ODataEntity> {
 
         if (c >= 0) {
           jsonEntry = odataClient.getDeserializer().toEntry(
-                  new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.JSON);
+                  new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.JSON).getObject();
         }
       } else {
         while ((c = input.read()) >= 0) {
@@ -237,7 +237,7 @@ public class ODataEntitySetIterator implements Iterator<ODataEntity> {
 
         if (consume(input, "</entry>", entry, true) >= 0) {
           atomEntry = odataClient.getDeserializer().
-                  toEntry(new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.ATOM);
+                  toEntry(new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.ATOM).getObject();
         }
       }
     } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ClientODataDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ClientODataDeserializer.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ClientODataDeserializer.java
index ad482fb..24b6e60 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ClientODataDeserializer.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ClientODataDeserializer.java
@@ -21,6 +21,7 @@ package org.apache.olingo.client.api.op;
 import java.io.InputStream;
 import org.apache.olingo.client.api.data.ServiceDocument;
 import org.apache.olingo.client.api.edm.xml.XMLMetadata;
+import org.apache.olingo.commons.api.data.Container;
 import org.apache.olingo.commons.api.format.ODataFormat;
 import org.apache.olingo.commons.api.op.CommonODataDeserializer;
 
@@ -35,5 +36,5 @@ public interface ClientODataDeserializer extends CommonODataDeserializer {
    * @param format OData service document format.
    * @return <tt>ServiceDocument</tt> object.
    */
-  ServiceDocument toServiceDocument(InputStream input, ODataFormat format);
+  Container<ServiceDocument> toServiceDocument(InputStream input, ODataFormat format);
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataReader.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataReader.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataReader.java
index 9164918..f13e0ac 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataReader.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/CommonODataReader.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
 import java.io.Serializable;
 import java.util.List;
 import org.apache.olingo.client.api.edm.xml.Schema;
+import org.apache.olingo.commons.api.data.Container;
 import org.apache.olingo.commons.api.domain.ODataError;
 import org.apache.olingo.commons.api.domain.ODataEntity;
 import org.apache.olingo.commons.api.domain.ODataEntitySet;
@@ -111,5 +112,5 @@ public interface CommonODataReader extends Serializable {
    * @param reference reference.
    * @return read object.
    */
-  <T> T read(InputStream src, String format, Class<T> reference);
+  <T> Container<T> read(InputStream src, String format, Class<T> reference);
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataDeserializer.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataDeserializer.java
index b12b104..bc16b74 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataDeserializer.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/v3/ODataDeserializer.java
@@ -20,6 +20,7 @@ package org.apache.olingo.client.api.op.v3;
 
 import java.io.InputStream;
 import org.apache.olingo.client.api.op.ClientODataDeserializer;
+import org.apache.olingo.commons.api.data.Container;
 import org.apache.olingo.commons.api.data.v3.LinkCollection;
 import org.apache.olingo.commons.api.format.ODataFormat;
 
@@ -32,6 +33,6 @@ public interface ODataDeserializer extends ClientODataDeserializer {
    * @param format OData format.
    * @return de-serialized links.
    */
-  LinkCollection toLinkCollection(InputStream input, ODataFormat format);
+  Container<LinkCollection> toLinkCollection(InputStream input, ODataFormat format);
 
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/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 447f543..481d41e 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,6 +24,8 @@ 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.Entry;
 import org.apache.olingo.commons.api.domain.ODataEntity;
 import org.apache.olingo.commons.api.format.ODataPubFormat;
 
@@ -83,8 +85,10 @@ public class ODataEntityRequestImpl extends AbstractODataRetrieveRequest<ODataEn
     public ODataEntity getBody() {
       if (entity == null) {
         try {
-          entity = odataClient.getReader().
-                  readEntity(getRawResponse(), ODataPubFormat.fromString(getContentType()));
+          final Container<Entry> entry =
+                  odataClient.getDeserializer().toEntry(getRawResponse(), ODataPubFormat.fromString(getContentType()));
+
+          entity = odataClient.getBinder().getODataEntity(extractFromContainer(entry));
         } finally {
           this.close();
         }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/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 ef191ba..bb46ce8 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,6 +24,8 @@ 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.Feed;
 import org.apache.olingo.commons.api.domain.ODataEntitySet;
 import org.apache.olingo.commons.api.format.ODataPubFormat;
 
@@ -33,7 +35,7 @@ import org.apache.olingo.commons.api.format.ODataPubFormat;
 public class ODataEntitySetRequestImpl extends AbstractODataRetrieveRequest<ODataEntitySet, ODataPubFormat>
         implements ODataEntitySetRequest {
 
-  private ODataEntitySet feed = null;
+  private ODataEntitySet entitySet = null;
 
   /**
    * Private constructor.
@@ -83,15 +85,17 @@ public class ODataEntitySetRequestImpl extends AbstractODataRetrieveRequest<ODat
     @Override
     @SuppressWarnings("unchecked")
     public ODataEntitySet getBody() {
-      if (feed == null) {
+      if (entitySet == null) {
         try {
-          feed = odataClient.getReader().
-                  readEntitySet(getRawResponse(), ODataPubFormat.fromString(getContentType()));
+          final Container<Feed> feed =
+                  odataClient.getDeserializer().toFeed(getRawResponse(), ODataPubFormat.fromString(getContentType()));
+
+          entitySet = odataClient.getBinder().getODataEntitySet(extractFromContainer(feed));
         } finally {
           this.close();
         }
       }
-      return feed;
+      return entitySet;
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/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 0212048..09f4c14 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,6 +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.ODataRequestImpl;
 import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
+import org.apache.olingo.commons.api.data.Container;
 
 /**
  * This class implements a generic OData request.
@@ -92,10 +93,11 @@ public class ODataRawRequestImpl extends ODataRequestImpl<ODataPubFormat>
           this.close();
         }
       }
-      
-      return odataClient.getReader().read(new ByteArrayInputStream(obj), getContentType(), reference);
-    }
 
-  }
+      final Container<T> container =
+              odataClient.getReader().read(new ByteArrayInputStream(obj), getContentType(), reference);
 
+      return extractFromContainer(container);
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/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 7b27906..c571cd6 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
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.PipedInputStream;
 import java.io.PipedOutputStream;
+import java.net.URI;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Map;
@@ -37,6 +38,7 @@ import org.apache.olingo.client.api.communication.response.ODataResponse;
 import org.apache.olingo.client.api.http.NoContentException;
 import org.apache.olingo.client.core.communication.request.batch.ODataBatchController;
 import org.apache.olingo.client.core.communication.request.batch.ODataBatchUtilities;
+import org.apache.olingo.commons.api.data.Container;
 import org.slf4j.LoggerFactory;
 
 /**
@@ -50,6 +52,16 @@ 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;
@@ -133,6 +145,24 @@ public abstract class AbstractODataResponse implements ODataResponse {
     statusMessage = res.getStatusLine().getReasonPhrase();
   }
 
+  @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}
    */
@@ -273,4 +303,14 @@ 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/e4bf2132/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 bd3695d..ffc58e1 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
@@ -22,6 +22,7 @@ import java.io.InputStream;
 import java.util.List;
 import org.apache.commons.io.IOUtils;
 import org.apache.olingo.client.api.CommonODataClient;
+import org.apache.olingo.client.api.data.ServiceDocument;
 import org.apache.olingo.commons.api.domain.ODataError;
 import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.domain.ODataEntity;
@@ -32,12 +33,15 @@ import org.apache.olingo.commons.api.domain.ODataProperty;
 import org.apache.olingo.commons.api.domain.ODataServiceDocument;
 import org.apache.olingo.commons.api.domain.ODataValue;
 import org.apache.olingo.client.api.edm.xml.XMLMetadata;
-import org.apache.olingo.commons.api.format.ODataFormat;
-import org.apache.olingo.commons.api.format.ODataPubFormat;
-import org.apache.olingo.commons.api.format.ODataValueFormat;
 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.Entry;
+import org.apache.olingo.commons.api.data.Feed;
 import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.format.ODataPubFormat;
+import org.apache.olingo.commons.api.format.ODataValueFormat;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -69,22 +73,23 @@ 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));
+    return client.getBinder().getODataServiceDocument(
+            client.getDeserializer().toServiceDocument(input, format).getObject());
   }
 
   @Override
   public ODataEntitySet readEntitySet(final InputStream input, final ODataPubFormat format) {
-    return client.getBinder().getODataEntitySet(client.getDeserializer().toFeed(input, format));
+    return client.getBinder().getODataEntitySet(client.getDeserializer().toFeed(input, format).getObject());
   }
 
   @Override
   public ODataEntity readEntity(final InputStream input, final ODataPubFormat format) {
-    return client.getBinder().getODataEntity(client.getDeserializer().toEntry(input, format));
+    return client.getBinder().getODataEntity(client.getDeserializer().toEntry(input, format).getObject());
   }
 
   @Override
   public ODataProperty readProperty(final InputStream input, final ODataFormat format) {
-    final Property property = client.getDeserializer().toProperty(input, format);
+    final Property property = client.getDeserializer().toProperty(input, format).getObject();
     return client.getBinder().getODataProperty(property);
   }
 
@@ -95,30 +100,48 @@ public abstract class AbstractODataReader implements CommonODataReader {
 
   @Override
   @SuppressWarnings("unchecked")
-  public <T> T read(final InputStream src, final String format, final Class<T> reference) {
-    Object res;
+  public <T> Container<T> read(final InputStream src, final String format, final Class<T> reference) {
+    Container<T> res;
 
     try {
       if (ODataEntitySetIterator.class.isAssignableFrom(reference)) {
-        res = new ODataEntitySetIterator(client, src, ODataPubFormat.fromString(format));
+        res = new Container<T>(
+                null, null, (T) new ODataEntitySetIterator(client, src, ODataPubFormat.fromString(format)));
       } else if (ODataEntitySet.class.isAssignableFrom(reference)) {
-        res = readEntitySet(src, ODataPubFormat.fromString(format));
+        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()));
       } else if (ODataEntity.class.isAssignableFrom(reference)) {
-        res = readEntity(src, ODataPubFormat.fromString(format));
+        final Container<Entry> container = client.getDeserializer().toEntry(src, ODataPubFormat.fromString(format));
+        res = new Container<T>(
+                container.getContextURL(),
+                container.getMetadataETag(),
+                (T) client.getBinder().getODataEntity(container.getObject()));
       } else if (ODataProperty.class.isAssignableFrom(reference)) {
-        res = readProperty(src, ODataFormat.fromString(format));
+        final Container<Property> container = client.getDeserializer().toProperty(src, ODataFormat.fromString(format));
+        res = new Container<T>(
+                container.getContextURL(),
+                container.getMetadataETag(),
+                (T) client.getBinder().getODataProperty(container.getObject()));
       } else if (ODataValue.class.isAssignableFrom(reference)) {
-        res = client.getPrimitiveValueBuilder().
+        res = new Container<T>(null, null, (T) client.getPrimitiveValueBuilder().
                 setType(ODataValueFormat.fromString(format) == ODataValueFormat.TEXT
-                        ? EdmPrimitiveTypeKind.String : EdmPrimitiveTypeKind.Stream).
+                ? EdmPrimitiveTypeKind.String : EdmPrimitiveTypeKind.Stream).
                 setText(IOUtils.toString(src)).
-                build();
+                build());
       } else if (XMLMetadata.class.isAssignableFrom(reference)) {
-        res = readMetadata(src);
+        res = new Container<T>(null, null, (T) readMetadata(src));
       } else if (ODataServiceDocument.class.isAssignableFrom(reference)) {
-        res = readServiceDocument(src, ODataFormat.fromString(format));
+        final Container<ServiceDocument> container =
+                client.getDeserializer().toServiceDocument(src, ODataFormat.fromString(format));
+        res = new Container<T>(
+                container.getContextURL(),
+                container.getMetadataETag(),
+                (T) client.getBinder().getODataServiceDocument(container.getObject()));
       } else if (ODataError.class.isAssignableFrom(reference)) {
-        res = readError(src, !format.toString().contains("json"));
+        res = new Container<T>(null, null, (T) readError(src, !format.toString().contains("json")));
       } else {
         throw new IllegalArgumentException("Invalid reference type " + reference);
       }
@@ -131,6 +154,6 @@ public abstract class AbstractODataReader implements CommonODataReader {
       }
     }
 
-    return (T) res;
+    return res;
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/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 f88ae96..01bacbe 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,6 +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.core.op.AbstractODataDeserializer;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 
@@ -52,17 +53,16 @@ public class ODataDeserializerImpl extends AbstractODataDeserializer implements
   }
 
   @Override
-  public ServiceDocument toServiceDocument(final InputStream input, final ODataFormat format) {
+  public Container<ServiceDocument> toServiceDocument(final InputStream input, final ODataFormat format) {
     return format == ODataFormat.XML
-            ? xml(input, XMLServiceDocumentImpl.class)
-            : json(input, JSONServiceDocumentImpl.class);
+            ? this.<ServiceDocument, XMLServiceDocumentImpl>xml(input, XMLServiceDocumentImpl.class)
+            : this.<ServiceDocument, JSONServiceDocumentImpl>json(input, JSONServiceDocumentImpl.class);
   }
 
   @Override
-  public LinkCollection toLinkCollection(final InputStream input, final ODataFormat format) {
+  public Container<LinkCollection> toLinkCollection(final InputStream input, final ODataFormat format) {
     return format == ODataFormat.XML
-            ? atom(input, XMLLinkCollectionImpl.class)
-            : json(input, JSONLinkCollectionImpl.class);
+            ? 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/e4bf2132/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 beb69b9..b9cf6de 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,6 +25,8 @@ 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.v3.LinkCollection;
 
 public class ODataReaderImpl extends AbstractODataReader implements ODataReader {
 
@@ -37,15 +39,22 @@ public class ODataReaderImpl extends AbstractODataReader implements ODataReader
   @Override
   public ODataLinkCollection readLinks(final InputStream input, final ODataFormat format) {
     return ((ODataClient) client).getBinder().getLinkCollection(
-            ((ODataClient) client).getDeserializer().toLinkCollection(input, format));
+            ((ODataClient) client).getDeserializer().toLinkCollection(input, format).getObject());
   }
 
   @Override
   @SuppressWarnings("unchecked")
-  public <T> T read(final InputStream src, final String format, final Class<T> reference) {
-    return (ODataLinkCollection.class.isAssignableFrom(reference)
-            ? (T) readLinks(src, ODataFormat.fromString(format))
-            : super.read(src, format, reference));
+  public <T> Container<T> read(final InputStream src, final String format, final Class<T> reference) {
+    if (ODataLinkCollection.class.isAssignableFrom(reference)) {
+      final Container<LinkCollection> container =
+              ((ODataClient) client).getDeserializer().toLinkCollection(src, ODataFormat.fromString(format));
+
+      return new Container<T>(
+              container.getContextURL(),
+              container.getMetadataETag(),
+              (T) ((ODataClient) client).getBinder().getLinkCollection(container.getObject()));
+    } else {
+      return super.read(src, format, reference);
+    }
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/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 f936853..08d3556 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,6 +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.core.op.AbstractODataDeserializer;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 
@@ -49,10 +50,10 @@ public class ODataDeserializerImpl extends AbstractODataDeserializer implements
   }
 
   @Override
-  public ServiceDocument toServiceDocument(final InputStream input, final ODataFormat format) {
+  public Container<ServiceDocument> toServiceDocument(final InputStream input, final ODataFormat format) {
     return format == ODataFormat.XML
-            ? xml(input, XMLServiceDocumentImpl.class)
-            : json(input, JSONServiceDocumentImpl.class);
+            ? 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/e4bf2132/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 cb8958b..9340963 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
@@ -29,5 +29,4 @@ public class ODataReaderImpl extends AbstractODataReader implements ODataReader
   public ODataReaderImpl(final ODataClient client) {
     super(client);
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractPrimitiveTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractPrimitiveTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractPrimitiveTest.java
index 04eb893..9a42d86 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractPrimitiveTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractPrimitiveTest.java
@@ -75,7 +75,9 @@ public abstract class AbstractPrimitiveTest extends AbstractTest {
   }
 
   protected ODataPrimitiveValue readPrimitiveValue(final InputStream input) {
-    final ODataProperty property = getClient().getReader().readProperty(input, getFormat());
+    final ODataProperty property = getClient().getBinder().getODataProperty(
+            getClient().getDeserializer().toProperty(input, getFormat()).getObject());
+
     assertNotNull(property);
     assertTrue(property.hasPrimitiveValue());
     assertNotNull(property.getPrimitiveValue());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractTest.java
index 473b25e..04a5c96 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractTest.java
@@ -18,8 +18,6 @@
  */
 package org.apache.olingo.client.core;
 
-import java.util.Locale;
-
 import org.apache.olingo.client.api.CommonODataClient;
 import org.apache.olingo.commons.api.format.ODataFormat;
 import org.apache.olingo.commons.api.format.ODataPubFormat;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java
index a3fe55e..9f9c2c3 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/QueryOptionsTestITCase.java
@@ -192,7 +192,7 @@ public class QueryOptionsTestITCase extends AbstractTestITCase {
     req.setFormat(ODataPubFormat.ATOM);
 
     final Entry atomEntry =
-            client.getDeserializer().toEntry(req.execute().getRawResponse(), ODataPubFormat.ATOM);
+            client.getDeserializer().toEntry(req.execute().getRawResponse(), ODataPubFormat.ATOM).getObject();
     assertEquals("remotingdestructorprinterswitcheschannelssatellitelanguageresolve",
             ((AtomEntryImpl) atomEntry).getSummary());
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
index 473e721..2d78a6d 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v4/EntitySetTestITCase.java
@@ -104,7 +104,7 @@ public class EntitySetTestITCase extends AbstractTestITCase {
 
     assertNotNull(feed);
 
-    assertTrue(feed.getContextURL().toASCIIString().endsWith("$metadata#People"));
+    assertTrue(res.getContextURL().toASCIIString().endsWith("$metadata#People"));
 
     debugFeed(client.getBinder().getFeed(feed, ResourceFactory.feedClassForFormat(
             ODataPubFormat.ATOM == format)), "Just retrieved feed");
@@ -153,6 +153,6 @@ public class EntitySetTestITCase extends AbstractTestITCase {
 
     final ODataEntitySet entitySet = res.getBodyAs(ODataEntitySet.class);
     assertNotNull(entitySet);
-    assertTrue(entitySet.getContextURL().toASCIIString().endsWith("$metadata#People"));
+    assertTrue(res.getContextURL().toASCIIString().endsWith("$metadata#People"));
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/AtomTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/AtomTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/AtomTest.java
index 755b44b..1be265b 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/AtomTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/AtomTest.java
@@ -70,8 +70,7 @@ public class AtomTest extends AbstractTest {
   protected void feed(final String filename, final ODataPubFormat format) throws Exception {
     final StringWriter writer = new StringWriter();
     getClient().getSerializer().feed(getClient().getDeserializer().toFeed(
-            getClass().getResourceAsStream("Customer." + getSuffix(format)), format),
-            writer);
+            getClass().getResourceAsStream("Customer." + getSuffix(format)), format).getObject(), writer);
 
     assertSimilar("Customer." + getSuffix(format), writer.toString());
   }
@@ -84,7 +83,7 @@ public class AtomTest extends AbstractTest {
   protected void entry(final String filename, final ODataPubFormat format) throws Exception {
     final StringWriter writer = new StringWriter();
     getClient().getSerializer().entry(getClient().getDeserializer().toEntry(
-            getClass().getResourceAsStream(filename + "." + getSuffix(format)), format), writer);
+            getClass().getResourceAsStream(filename + "." + getSuffix(format)), format).getObject(), writer);
 
     assertSimilar(filename + "." + getSuffix(format), writer.toString());
   }
@@ -104,7 +103,7 @@ public class AtomTest extends AbstractTest {
   protected void property(final String filename, final ODataFormat format) throws Exception {
     final StringWriter writer = new StringWriter();
     getClient().getSerializer().property(getClient().getDeserializer().
-            toProperty(getClass().getResourceAsStream(filename + "." + getSuffix(format)), format), writer);
+            toProperty(getClass().getResourceAsStream(filename + "." + getSuffix(format)), format).getObject(), writer);
 
     assertSimilar(filename + "." + getSuffix(format), writer.toString());
   }
@@ -128,5 +127,4 @@ public class AtomTest extends AbstractTest {
     property("Product_-10_ComplexConcurrency_QueriedDateTime", getODataFormat());
     property("Product_-10_Dimensions_Width", getODataFormat());
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntitySetTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntitySetTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntitySetTest.java
index c6fd0d8..0812c6d 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntitySetTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntitySetTest.java
@@ -40,7 +40,7 @@ public class EntitySetTest extends AbstractTest {
   private void read(final ODataPubFormat format) throws IOException {
     final InputStream input = getClass().getResourceAsStream("Customer." + getSuffix(format));
     final ODataEntitySet entitySet = getClient().getBinder().getODataEntitySet(
-            getClient().getDeserializer().toFeed(input, format));
+            getClient().getDeserializer().toFeed(input, format).getObject());
     assertNotNull(entitySet);
 
     assertEquals(2, entitySet.getEntities().size());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntityTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntityTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntityTest.java
index 151478a..80c56c2 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntityTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntityTest.java
@@ -46,7 +46,7 @@ public class EntityTest extends AbstractTest {
   private void readAndWrite(final ODataPubFormat format) {
     final InputStream input = getClass().getResourceAsStream("Customer_-10." + getSuffix(format));
     final ODataEntity entity = getClient().getBinder().getODataEntity(
-            getClient().getDeserializer().toEntry(input, format));
+            getClient().getDeserializer().toEntry(input, format).getObject());
     assertNotNull(entity);
 
     assertEquals("Microsoft.Test.OData.Services.AstoriaDefaultService.Customer", entity.getName());
@@ -82,7 +82,7 @@ public class EntityTest extends AbstractTest {
   private void readGeospatial(final ODataPubFormat format) {
     final InputStream input = getClass().getResourceAsStream("AllGeoTypesSet_-8." + getSuffix(format));
     final ODataEntity entity = getClient().getBinder().getODataEntity(
-            getClient().getDeserializer().toEntry(input, format));
+            getClient().getDeserializer().toEntry(input, format).getObject());
     assertNotNull(entity);
 
     boolean found = false;
@@ -114,7 +114,7 @@ public class EntityTest extends AbstractTest {
   private void withActions(final ODataPubFormat format) {
     final InputStream input = getClass().getResourceAsStream("ComputerDetail_-10." + getSuffix(format));
     final ODataEntity entity = getClient().getBinder().getODataEntity(
-            getClient().getDeserializer().toEntry(input, format));
+            getClient().getDeserializer().toEntry(input, format).getObject());
     assertNotNull(entity);
 
     assertEquals(1, entity.getOperations().size());
@@ -140,7 +140,7 @@ public class EntityTest extends AbstractTest {
   private void mediaEntity(final ODataPubFormat format) {
     final InputStream input = getClass().getResourceAsStream("Car_16." + getSuffix(format));
     final ODataEntity entity = getClient().getBinder().getODataEntity(
-            getClient().getDeserializer().toEntry(input, format));
+            getClient().getDeserializer().toEntry(input, format).getObject());
     assertNotNull(entity);
     assertTrue(entity.isMediaEntity());
     assertNotNull(entity.getMediaContentSource());
@@ -164,7 +164,7 @@ public class EntityTest extends AbstractTest {
   private void issue128(final ODataPubFormat format) throws EdmPrimitiveTypeException {
     final InputStream input = getClass().getResourceAsStream("AllGeoTypesSet_-5." + getSuffix(format));
     final ODataEntity entity = getClient().getBinder().getODataEntity(
-            getClient().getDeserializer().toEntry(input, format));
+            getClient().getDeserializer().toEntry(input, format).getObject());
     assertNotNull(entity);
 
     final ODataProperty geogCollection = entity.getProperty("GeogCollection");

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java
index 3b5b9cc..39d9614 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/Constants.java
@@ -141,6 +141,8 @@ public interface Constants {
 
   public final static String JSON_METADATA = "odata.metadata";
 
+  public final static String JSON_METADATA_ETAG = "@odata.metadataEtag";
+
   public final static String JSON_TYPE = "odata.type";
 
   public final static String JSON_TYPE_SUFFIX = "@" + JSON_TYPE;
@@ -248,4 +250,6 @@ public interface Constants {
 
   public static final String ATOM_ATTR_ETAG = "etag";
 
+  public static final String ATOM_ATTR_METADATAETAG = "metadata-etag";
+
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Container.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Container.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Container.java
new file mode 100644
index 0000000..be3476b
--- /dev/null
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/Container.java
@@ -0,0 +1,76 @@
+/*
+ * 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.commons.api.data;
+
+import java.net.URI;
+
+/**
+ * Outermost response object container.
+ */
+public class Container<T> {
+
+  private final URI contextURL;
+
+  private final String metadataETag;
+
+  private final T object;
+
+  public Container(final URI contextURL, final String metadataETag, final T object) {
+    this.contextURL = contextURL;
+    this.metadataETag = metadataETag;
+    this.object = object;
+  }
+
+  /**
+   * The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
+   * fragment identifying the relevant portion of the metadata document.
+   * <br />
+   * Request payloads generally do not require context URLs as the type of the payload can generally be determined from
+   * the request URL.
+   * <br />
+   * For details on how the context URL is used to describe a payload, see the relevant sections in the particular
+   * format.
+   *
+   * @return context URL.
+   */
+  public URI getContextURL() {
+    return contextURL;
+  }
+
+  /**
+   * An ETag header MAY also be returned on a metadata document request or service document request to allow the client
+   * subsequently to make a conditional request for the metadata or service document. Clients can also compare the value
+   * of the ETag header returned from a metadata document request to the metadata ETag returned in a response in order
+   * to verify the version of the metadata used to generate that response.
+   *
+   * @return metadata ETag.
+   */
+  public String getMetadataETag() {
+    return metadataETag;
+  }
+
+  /**
+   * Gets contained object.
+   *
+   * @return contained object.
+   */
+  public T getObject() {
+    return object;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/commons-api/src/main/java/org/apache/olingo/commons/api/op/CommonODataDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/op/CommonODataDeserializer.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/op/CommonODataDeserializer.java
index dfefb78..4b30ddd 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/op/CommonODataDeserializer.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/op/CommonODataDeserializer.java
@@ -20,6 +20,7 @@ package org.apache.olingo.commons.api.op;
 
 import java.io.InputStream;
 import java.io.Serializable;
+import org.apache.olingo.commons.api.data.Container;
 import org.apache.olingo.commons.api.data.Entry;
 import org.apache.olingo.commons.api.domain.ODataError;
 import org.apache.olingo.commons.api.data.Feed;
@@ -39,7 +40,7 @@ public interface CommonODataDeserializer extends Serializable {
    * @param format Atom or JSON
    * @return Feed instance.
    */
-  Feed toFeed(InputStream input, ODataPubFormat format);
+  Container<Feed> toFeed(InputStream input, ODataPubFormat format);
 
   /**
    * Gets an entry object from the given InputStream.
@@ -48,7 +49,7 @@ public interface CommonODataDeserializer extends Serializable {
    * @param format Atom or JSON
    * @return Entry instance.
    */
-  Entry toEntry(InputStream input, ODataPubFormat format);
+  Container<Entry> toEntry(InputStream input, ODataPubFormat format);
 
   /**
    * Gets a property object from the given InputStream.
@@ -57,7 +58,7 @@ public interface CommonODataDeserializer extends Serializable {
    * @param format XML or JSON
    * @return Property instance.
    */
-  Property toProperty(InputStream input, ODataFormat format);
+  Container<Property> toProperty(InputStream input, ODataFormat format);
 
   /**
    * Gets the ODataError object represented by the given InputStream.
@@ -67,5 +68,4 @@ public interface CommonODataDeserializer extends Serializable {
    * @return
    */
   ODataError toError(InputStream input, boolean isXML);
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomDealer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomDealer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomDealer.java
index d4cf40a..e258219 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomDealer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomDealer.java
@@ -34,6 +34,8 @@ abstract class AbstractAtomDealer {
 
   protected final QName etagQName;
 
+  protected final QName metadataEtagQName;
+
   protected final QName inlineQName;
 
   protected final QName actionQName;
@@ -63,6 +65,8 @@ abstract class AbstractAtomDealer {
 
     this.etagQName =
             new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATOM_ATTR_ETAG);
+    this.metadataEtagQName =
+            new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATOM_ATTR_METADATAETAG);
     this.inlineQName =
             new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATOM_ELEM_INLINE);
     this.actionQName =

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomObject.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomObject.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomObject.java
deleted file mode 100644
index 2436e3e..0000000
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractAtomObject.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.commons.core.data;
-
-import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
-import java.net.URI;
-import java.text.ParseException;
-import java.util.Date;
-
-abstract class AbstractAtomObject extends AbstractPayloadObject {
-
-  private static final long serialVersionUID = -4391162864875546927L;
-
-  private static final ISO8601DateFormat ISO_DATEFORMAT = new ISO8601DateFormat();
-
-  private URI baseURI;
-
-  private URI contextURL;
-
-  private String id;
-
-  private String title;
-
-  private String summary;
-
-  private Date updated;
-
-  public URI getBaseURI() {
-    return baseURI;
-  }
-
-  public void setBaseURI(final String baseURI) {
-    this.baseURI = URI.create(baseURI);
-  }
-
-  /**
-   * The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
-   * fragment identifying the relevant portion of the metadata document.
-   *
-   * @return context URL.
-   */
-  public URI getContextURL() {
-    return contextURL;
-  }
-
-  public void setContextURL(final URI contextURL) {
-    this.contextURL = contextURL;
-  }
-
-  public String getId() {
-    return id;
-  }
-
-  public void setId(final String id) {
-    this.id = id;
-  }
-
-  public String getTitle() {
-    return title;
-  }
-
-  public String getSummary() {
-    return summary;
-  }
-
-  public Date getUpdated() {
-    return updated;
-  }
-
-  public void setCommonProperty(final String key, final String value) throws ParseException {
-    if ("id".equals(key)) {
-      this.id = value;
-    } else if ("title".equals(key)) {
-      this.title = value;
-    } else if ("summary".equals(key)) {
-      this.summary = value;
-    } else if ("updated".equals(key)) {
-      this.updated = ISO_DATEFORMAT.parse(value);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractEntry.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractEntry.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractEntry.java
index 29a4a75..85d6775 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractEntry.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractEntry.java
@@ -29,7 +29,7 @@ import org.apache.olingo.commons.api.domain.ODataOperation;
 /**
  * Abstract base for classes implementing an OData entry in Atom and JSON.
  */
-public abstract class AbstractEntry extends AbstractAtomObject implements Entry {
+public abstract class AbstractEntry extends AbstractODataObject implements Entry {
 
   private static final long serialVersionUID = 2127764552600969783L;
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractODataObject.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractODataObject.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractODataObject.java
new file mode 100644
index 0000000..3bcef74
--- /dev/null
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractODataObject.java
@@ -0,0 +1,97 @@
+/*
+ * 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.commons.core.data;
+
+import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
+import java.net.URI;
+import java.text.ParseException;
+import java.util.Date;
+
+abstract class AbstractODataObject extends AbstractPayloadObject {
+
+  private static final long serialVersionUID = -4391162864875546927L;
+
+  private static final ISO8601DateFormat ISO_DATEFORMAT = new ISO8601DateFormat();
+
+  private URI baseURI;
+
+  private URI contextURL;
+
+  private String id;
+
+  private String title;
+
+  private String summary;
+
+  private Date updated;
+
+  public URI getBaseURI() {
+    return baseURI;
+  }
+
+  public void setBaseURI(final String baseURI) {
+    this.baseURI = URI.create(baseURI);
+  }
+
+  /**
+   * The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
+   * fragment identifying the relevant portion of the metadata document.
+   *
+   * @return context URL.
+   */
+  public URI getContextURL() {
+    return contextURL;
+  }
+
+  public void setContextURL(final URI contextURL) {
+    this.contextURL = contextURL;
+  }
+
+  public String getId() {
+    return id;
+  }
+
+  public void setId(final String id) {
+    this.id = id;
+  }
+
+  public String getTitle() {
+    return title;
+  }
+
+  public String getSummary() {
+    return summary;
+  }
+
+  public Date getUpdated() {
+    return updated;
+  }
+
+  public void setCommonProperty(final String key, final String value) throws ParseException {
+    if ("id".equals(key)) {
+      this.id = value;
+    } else if ("title".equals(key)) {
+      this.title = value;
+    } else if ("summary".equals(key)) {
+      this.summary = value;
+    } else if ("updated".equals(key)) {
+      this.updated = ISO_DATEFORMAT.parse(value);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java
index 9a4eac1..d863eb6 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomDeserializer.java
@@ -18,6 +18,7 @@
  */
 package org.apache.olingo.commons.core.data;
 
+import org.apache.olingo.commons.api.data.Container;
 import java.io.InputStream;
 import java.net.URI;
 import java.text.ParseException;
@@ -40,7 +41,7 @@ public class AtomDeserializer extends AbstractAtomDealer {
 
   private static final Logger LOG = LoggerFactory.getLogger(AtomDeserializer.class);
 
-  private static final XMLInputFactory FACTORY = XMLInputFactory.newInstance();
+  public static final XMLInputFactory FACTORY = XMLInputFactory.newInstance();
 
   private final AtomPropertyDeserializer propDeserializer;
 
@@ -49,12 +50,13 @@ public class AtomDeserializer extends AbstractAtomDealer {
     this.propDeserializer = new AtomPropertyDeserializer(version);
   }
 
-  private AtomPropertyImpl property(final InputStream input) throws XMLStreamException {
+  private Container<AtomPropertyImpl> property(final InputStream input) throws XMLStreamException {
     final XMLEventReader reader = FACTORY.createXMLEventReader(input);
-    return propDeserializer.deserialize(reader, skipBeforeFirstStartElement(reader));
+    final StartElement start = skipBeforeFirstStartElement(reader);
+    return getContainer(start, propDeserializer.deserialize(reader, start));
   }
 
-  private StartElement skipBeforeFirstStartElement(final XMLEventReader reader) throws XMLStreamException {
+  public StartElement skipBeforeFirstStartElement(final XMLEventReader reader) throws XMLStreamException {
     StartElement startEvent = null;
     while (reader.hasNext() && startEvent == null) {
       final XMLEvent event = reader.nextEvent();
@@ -70,7 +72,7 @@ public class AtomDeserializer extends AbstractAtomDealer {
   }
 
   private void common(final XMLEventReader reader, final StartElement start,
-          final AbstractAtomObject object, final String key) throws XMLStreamException {
+          final AbstractODataObject object, final String key) throws XMLStreamException {
 
     boolean foundEndElement = false;
     while (reader.hasNext() && !foundEndElement) {
@@ -123,8 +125,14 @@ public class AtomDeserializer extends AbstractAtomDealer {
     }
   }
 
-  private XMLLinkCollectionImpl linkCollection(final InputStream input) throws XMLStreamException {
+  private Container<XMLLinkCollectionImpl> linkCollection(final InputStream input) throws XMLStreamException {
     final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+    final StartElement start = skipBeforeFirstStartElement(reader);
+    return getContainer(start, linkCollection(reader, start));
+  }
+
+  private XMLLinkCollectionImpl linkCollection(final XMLEventReader reader, final StartElement start)
+          throws XMLStreamException {
 
     final XMLLinkCollectionImpl linkCollection = new XMLLinkCollectionImpl();
 
@@ -178,8 +186,6 @@ public class AtomDeserializer extends AbstractAtomDealer {
         entry.setBaseURI(xmlBase.getValue());
       }
 
-      entry.setContextURL(retrieveContextURL(start, entry.getBaseURI()));
-
       final Attribute etag = start.getAttributeByName(etagQName);
       if (etag != null) {
         entry.setETag(etag.getValue());
@@ -291,7 +297,6 @@ public class AtomDeserializer extends AbstractAtomDealer {
 
   private AtomEntryImpl entryRef(final StartElement start) throws XMLStreamException {
     final AtomEntryImpl entry = new AtomEntryImpl();
-    entry.setContextURL(retrieveContextURL(start, null));
 
     final Attribute entryRefId = start.getAttributeByName(Constants.QNAME_ATOM_ELEM_ENTRY_REF_ID);
 
@@ -302,9 +307,10 @@ public class AtomDeserializer extends AbstractAtomDealer {
     return entry;
   }
 
-  private AtomEntryImpl entry(final InputStream input) throws XMLStreamException {
+  private Container<AtomEntryImpl> entry(final InputStream input) throws XMLStreamException {
     final XMLEventReader reader = FACTORY.createXMLEventReader(input);
-    return entry(reader, skipBeforeFirstStartElement(reader));
+    final StartElement start = skipBeforeFirstStartElement(reader);
+    return getContainer(start, entry(reader, start));
   }
 
   private void count(final XMLEventReader reader, final StartElement start, final AtomFeedImpl feed)
@@ -328,15 +334,12 @@ public class AtomDeserializer extends AbstractAtomDealer {
     if (!Constants.QNAME_ATOM_ELEM_FEED.equals(start.getName())) {
       return null;
     }
-
     final AtomFeedImpl feed = new AtomFeedImpl();
     final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE);
     if (xmlBase != null) {
       feed.setBaseURI(xmlBase.getValue());
     }
 
-    feed.setContextURL(retrieveContextURL(start, feed.getBaseURI()));
-
     boolean foundEndFeed = false;
     while (reader.hasNext() && !foundEndFeed) {
       final XMLEvent event = reader.nextEvent();
@@ -372,34 +375,34 @@ public class AtomDeserializer extends AbstractAtomDealer {
     return feed;
   }
 
-  private AtomFeedImpl feed(final InputStream input) throws XMLStreamException {
+  private Container<AtomFeedImpl> feed(final InputStream input) throws XMLStreamException {
     final XMLEventReader reader = FACTORY.createXMLEventReader(input);
-    return feed(reader, skipBeforeFirstStartElement(reader));
+    final StartElement start = skipBeforeFirstStartElement(reader);
+    return getContainer(start, feed(reader, start));
   }
 
   @SuppressWarnings("unchecked")
-  public <T> T read(final InputStream input, final Class<T> reference) throws XMLStreamException {
+  public <T, V extends T> Container<T> read(final InputStream input, final Class<V> reference)
+          throws XMLStreamException {
     if (AtomFeedImpl.class.equals(reference)) {
-      return (T) feed(input);
+      return (Container<T>) feed(input);
     } else if (AtomEntryImpl.class.equals(reference)) {
-      return (T) entry(input);
+      return (Container<T>) entry(input);
     } else if (AtomPropertyImpl.class.equals(reference)) {
-      return (T) property(input);
+      return (Container<T>) property(input);
     } else if (XMLLinkCollectionImpl.class.equals(reference)) {
-      return (T) linkCollection(input);
+      return (Container<T>) linkCollection(input);
     }
     return null;
   }
 
-  private URI retrieveContextURL(final StartElement start, final URI base) {
+  public <T> Container<T> getContainer(final StartElement start, final T object) {
     final Attribute context = start.getAttributeByName(contextQName);
+    final Attribute metadataETag = start.getAttributeByName(metadataEtagQName);
 
-    if (context == null) {
-      return base == null
-              ? null
-              : URI.create(base.toASCIIString() + "/" + Constants.METADATA);
-    } else {
-      return URI.create(context.getValue());
-    }
+    return new Container<T>(
+            context == null ? null : URI.create(context.getValue()),
+            metadataETag == null ? null : metadataETag.getValue(),
+            object);
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomFeedImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomFeedImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomFeedImpl.java
index d40f945..09dfdcf 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomFeedImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomFeedImpl.java
@@ -29,7 +29,7 @@ import org.apache.olingo.commons.api.data.Feed;
  *
  * @see AtomEntry
  */
-public class AtomFeedImpl extends AbstractAtomObject implements Feed {
+public class AtomFeedImpl extends AbstractODataObject implements Feed {
 
   private static final long serialVersionUID = 5466590540021319153L;
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomSerializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomSerializer.java
index 8bab108..4bcd3bf 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomSerializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AtomSerializer.java
@@ -104,7 +104,7 @@ public class AtomSerializer extends AbstractAtomDealer {
     }
   }
 
-  private void common(final XMLStreamWriter writer, final AbstractAtomObject object) throws XMLStreamException {
+  private void common(final XMLStreamWriter writer, final AbstractODataObject object) throws XMLStreamException {
     if (StringUtils.isNotBlank(object.getTitle())) {
       writer.writeStartElement(Constants.ATOM_ELEM_TITLE);
       writer.writeAttribute(Constants.ATTR_TYPE, TYPE_TEXT);
@@ -149,8 +149,8 @@ public class AtomSerializer extends AbstractAtomDealer {
     writer.writeAttribute(Constants.ATOM_ATTR_TERM, entry.getType());
     writer.writeEndElement();
 
-    if (entry instanceof AbstractAtomObject) {
-      common(writer, (AbstractAtomObject) entry);
+    if (entry instanceof AbstractODataObject) {
+      common(writer, (AbstractODataObject) entry);
     }
 
     links(writer, entry.getAssociationLinks());
@@ -215,8 +215,8 @@ public class AtomSerializer extends AbstractAtomDealer {
       writer.writeEndElement();
     }
 
-    if (feed instanceof AbstractAtomObject) {
-      common(writer, (AbstractAtomObject) feed);
+    if (feed instanceof AbstractODataObject) {
+      common(writer, (AbstractODataObject) feed);
     }
 
     for (Entry entry : feed.getEntries()) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e4bf2132/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java
index 991e723..99d4c5c 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/op/AbstractODataDeserializer.java
@@ -18,7 +18,13 @@
  */
 package org.apache.olingo.commons.core.op;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.events.StartElement;
 import org.apache.olingo.commons.api.data.Entry;
 import org.apache.olingo.commons.api.domain.ODataError;
 import org.apache.olingo.commons.api.data.Feed;
@@ -28,6 +34,7 @@ import org.apache.olingo.commons.api.format.ODataPubFormat;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.apache.olingo.commons.api.op.CommonODataDeserializer;
 import org.apache.olingo.commons.core.data.AtomDeserializer;
+import org.apache.olingo.commons.api.data.Container;
 import org.apache.olingo.commons.core.data.AtomEntryImpl;
 import org.apache.olingo.commons.core.data.AtomFeedImpl;
 import org.apache.olingo.commons.core.data.AtomPropertyImpl;
@@ -50,45 +57,59 @@ public abstract class AbstractODataDeserializer extends AbstractJacksonTool impl
   }
 
   @Override
-  public Feed toFeed(final InputStream input, final ODataPubFormat format) {
+  public Container<Feed> toFeed(final InputStream input, final ODataPubFormat format) {
     return format == ODataPubFormat.ATOM
-            ? atom(input, AtomFeedImpl.class)
-            : json(input, JSONFeedImpl.class);
+            ? this.<Feed, AtomFeedImpl>atom(input, AtomFeedImpl.class)
+            : this.<Feed, JSONFeedImpl>json(input, JSONFeedImpl.class);
   }
 
   @Override
-  public Entry toEntry(final InputStream input, final ODataPubFormat format) {
+  public Container<Entry> toEntry(final InputStream input, final ODataPubFormat format) {
     return format == ODataPubFormat.ATOM
-            ? atom(input, AtomEntryImpl.class)
-            : json(input, JSONEntryImpl.class);
+            ? this.<Entry, AtomEntryImpl>atom(input, AtomEntryImpl.class)
+            : this.<Entry, JSONEntryImpl>json(input, JSONEntryImpl.class);
   }
 
   @Override
-  public Property toProperty(final InputStream input, final ODataFormat format) {
+  public Container<Property> toProperty(final InputStream input, final ODataFormat format) {
     return format == ODataFormat.XML
-            ? atom(input, AtomPropertyImpl.class)
-            : json(input, JSONPropertyImpl.class);
+            ? this.<Property, AtomPropertyImpl>atom(input, AtomPropertyImpl.class)
+            : this.<Property, JSONPropertyImpl>json(input, JSONPropertyImpl.class);
   }
 
   @Override
   public ODataError toError(final InputStream input, final boolean isXML) {
     return isXML
-            ? xml(input, XMLErrorImpl.class)
-            : json(input, JSONErrorBundle.class).getError();
+            ? this.<ODataError, XMLErrorImpl>xml(input, XMLErrorImpl.class).getObject()
+            : this.<JSONErrorBundle, JSONErrorBundle>json(input, JSONErrorBundle.class).getObject().getError();
   }
 
   /*
    * ------------------ Protected methods ------------------
    */
-  protected <T> T xml(final InputStream input, final Class<T> reference) {
+  @SuppressWarnings("unchecked")
+  protected <T, V extends T> Container<T> xml(final InputStream input, final Class<V> reference) {
     try {
-      return getXmlMapper().readValue(input, reference);
+      ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+      final XMLEventReader reader = AtomDeserializer.FACTORY.createXMLEventReader(input);
+      final StartElement start = atomDeserializer.skipBeforeFirstStartElement(reader);
+
+      final XMLEventWriter writer = XMLOutputFactory.newFactory().createXMLEventWriter(bos);
+      writer.add(start);
+      writer.add(reader);
+      writer.flush();
+      writer.close();
+
+      return (Container<T>) atomDeserializer.getContainer(
+              start, getXmlMapper().readValue(new ByteArrayInputStream(bos.toByteArray()), reference));
+
     } catch (Exception e) {
       throw new IllegalArgumentException("While deserializing " + reference.getName(), e);
     }
   }
 
-  protected <T> T atom(final InputStream input, final Class<T> reference) {
+  protected <T, V extends T> Container<T> atom(final InputStream input, final Class<V> reference) {
     try {
       return atomDeserializer.read(input, reference);
     } catch (Exception e) {
@@ -96,9 +117,9 @@ public abstract class AbstractODataDeserializer extends AbstractJacksonTool impl
     }
   }
 
-  protected <T> T json(final InputStream input, final Class<T> reference) {
+  protected <T, V extends T> Container<T> json(final InputStream input, final Class<V> reference) {
     try {
-      return getObjectMapper().readValue(input, reference);
+      return new Container<T>(null, null, getObjectMapper().readValue(input, reference));
     } catch (Exception e) {
       throw new IllegalArgumentException("While deserializing " + reference.getName(), e);
     }