You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2014/03/13 16:23:43 UTC

[1/7] OLINGO-205 ODataJClient request/response layer implementation imported

Repository: incubator-olingo-odata4
Updated Branches:
  refs/heads/olingo200 b5c38353f -> d3b05e016


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/data/GeospatialJSONHandler.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/GeospatialJSONHandler.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/GeospatialJSONHandler.java
index 610f1a2..b5ec987 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/GeospatialJSONHandler.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/GeospatialJSONHandler.java
@@ -26,7 +26,7 @@ import java.util.Iterator;
 import java.util.List;
 import javax.xml.parsers.DocumentBuilder;
 import org.apache.olingo.client.api.ODataClient;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
 import org.apache.olingo.client.api.domain.geospatial.Geospatial;
 import org.apache.olingo.client.api.utils.XMLUtils;
@@ -49,9 +49,9 @@ final class GeospatialJSONHandler {
   }
 
   private static Element deserializePoint(final Document document, final Iterator<JsonNode> itor) {
-    final Element point = document.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_POINT);
+    final Element point = document.createElementNS(Constants.NS_GML, Constants.ELEM_POINT);
 
-    final Element ppos = document.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_POS);
+    final Element ppos = document.createElementNS(Constants.NS_GML, Constants.ELEM_POS);
     point.appendChild(ppos);
     if (itor.hasNext()) {
       ppos.appendChild(document.createTextNode(itor.next().asText() + " " + itor.next().asText()));
@@ -63,16 +63,16 @@ final class GeospatialJSONHandler {
   private static void appendPoses(final Element parent, final Document document, final Iterator<JsonNode> itor) {
     while (itor.hasNext()) {
       final Iterator<JsonNode> lineItor = itor.next().elements();
-      final Element pos = document.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_POS);
+      final Element pos = document.createElementNS(Constants.NS_GML, Constants.ELEM_POS);
       parent.appendChild(pos);
       pos.appendChild(document.createTextNode(lineItor.next().asText() + " " + lineItor.next().asText()));
     }
   }
 
   private static Element deserializeLineString(final Document document, final Iterator<JsonNode> itor) {
-    final Element lineString = document.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_LINESTRING);
+    final Element lineString = document.createElementNS(Constants.NS_GML, Constants.ELEM_LINESTRING);
     if (!itor.hasNext()) {
-      lineString.appendChild(document.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_POSLIST));
+      lineString.appendChild(document.createElementNS(Constants.NS_GML, Constants.ELEM_POSLIST));
     }
 
     appendPoses(lineString, document, itor);
@@ -81,15 +81,15 @@ final class GeospatialJSONHandler {
   }
 
   private static Element deserializePolygon(final Document document, final Iterator<JsonNode> itor) {
-    final Element polygon = document.createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_POLYGON);
+    final Element polygon = document.createElementNS(Constants.NS_GML, Constants.ELEM_POLYGON);
 
     if (itor.hasNext()) {
       final Iterator<JsonNode> extItor = itor.next().elements();
       final Element exterior = document.createElementNS(
-              ODataConstants.NS_GML, ODataConstants.ELEM_POLYGON_EXTERIOR);
+              Constants.NS_GML, Constants.ELEM_POLYGON_EXTERIOR);
       polygon.appendChild(exterior);
       final Element extLR = document.createElementNS(
-              ODataConstants.NS_GML, ODataConstants.ELEM_POLYGON_LINEARRING);
+              Constants.NS_GML, Constants.ELEM_POLYGON_LINEARRING);
       exterior.appendChild(extLR);
 
       appendPoses(extLR, document, extItor);
@@ -98,10 +98,10 @@ final class GeospatialJSONHandler {
     if (itor.hasNext()) {
       final Iterator<JsonNode> intItor = itor.next().elements();
       final Element interior = document.createElementNS(
-              ODataConstants.NS_GML, ODataConstants.ELEM_POLYGON_INTERIOR);
+              Constants.NS_GML, Constants.ELEM_POLYGON_INTERIOR);
       polygon.appendChild(interior);
       final Element intLR = document.createElementNS(
-              ODataConstants.NS_GML, ODataConstants.ELEM_POLYGON_LINEARRING);
+              Constants.NS_GML, Constants.ELEM_POLYGON_LINEARRING);
       interior.appendChild(intLR);
 
       appendPoses(intLR, document, intItor);
@@ -111,8 +111,8 @@ final class GeospatialJSONHandler {
   }
 
   public static void deserialize(final JsonNode node, final Element parent, final String type) {
-    final Iterator<JsonNode> cooItor = node.has(ODataConstants.JSON_COORDINATES)
-            ? node.get(ODataConstants.JSON_COORDINATES).elements()
+    final Iterator<JsonNode> cooItor = node.has(Constants.JSON_COORDINATES)
+            ? node.get(Constants.JSON_COORDINATES).elements()
             : Collections.<JsonNode>emptyList().iterator();
 
     Element root = null;
@@ -125,10 +125,10 @@ final class GeospatialJSONHandler {
 
       case GeographyMultiPoint:
       case GeometryMultiPoint:
-        root = parent.getOwnerDocument().createElementNS(ODataConstants.NS_GML, ODataConstants.ELEM_MULTIPOINT);
+        root = parent.getOwnerDocument().createElementNS(Constants.NS_GML, Constants.ELEM_MULTIPOINT);
         if (cooItor.hasNext()) {
           final Element pointMembers = parent.getOwnerDocument().createElementNS(
-                  ODataConstants.NS_GML, ODataConstants.ELEM_POINTMEMBERS);
+                  Constants.NS_GML, Constants.ELEM_POINTMEMBERS);
           root.appendChild(pointMembers);
           while (cooItor.hasNext()) {
             final Iterator<JsonNode> mpItor = cooItor.next().elements();
@@ -145,10 +145,10 @@ final class GeospatialJSONHandler {
       case GeographyMultiLineString:
       case GeometryMultiLineString:
         root = parent.getOwnerDocument().createElementNS(
-                ODataConstants.NS_GML, ODataConstants.ELEM_MULTILINESTRING);
+                Constants.NS_GML, Constants.ELEM_MULTILINESTRING);
         if (cooItor.hasNext()) {
           final Element lineStringMembers = parent.getOwnerDocument().createElementNS(
-                  ODataConstants.NS_GML, ODataConstants.ELEM_LINESTRINGMEMBERS);
+                  Constants.NS_GML, Constants.ELEM_LINESTRINGMEMBERS);
           root.appendChild(lineStringMembers);
           while (cooItor.hasNext()) {
             final Iterator<JsonNode> mlsItor = cooItor.next().elements();
@@ -165,10 +165,10 @@ final class GeospatialJSONHandler {
       case GeographyMultiPolygon:
       case GeometryMultiPolygon:
         root = parent.getOwnerDocument().createElementNS(
-                ODataConstants.NS_GML, ODataConstants.ELEM_MULTIPOLYGON);
+                Constants.NS_GML, Constants.ELEM_MULTIPOLYGON);
         if (cooItor.hasNext()) {
           final Element surfaceMembers = parent.getOwnerDocument().createElementNS(
-                  ODataConstants.NS_GML, ODataConstants.ELEM_SURFACEMEMBERS);
+                  Constants.NS_GML, Constants.ELEM_SURFACEMEMBERS);
           root.appendChild(surfaceMembers);
           while (cooItor.hasNext()) {
             final Iterator<JsonNode> mpItor = cooItor.next().elements();
@@ -180,17 +180,17 @@ final class GeospatialJSONHandler {
       case GeographyCollection:
       case GeometryCollection:
         root = parent.getOwnerDocument().createElementNS(
-                ODataConstants.NS_GML, ODataConstants.ELEM_GEOCOLLECTION);
-        if (node.has(ODataConstants.JSON_GEOMETRIES)) {
-          final Iterator<JsonNode> geoItor = node.get(ODataConstants.JSON_GEOMETRIES).elements();
+                Constants.NS_GML, Constants.ELEM_GEOCOLLECTION);
+        if (node.has(Constants.JSON_GEOMETRIES)) {
+          final Iterator<JsonNode> geoItor = node.get(Constants.JSON_GEOMETRIES).elements();
           if (geoItor.hasNext()) {
             final Element geometryMembers = parent.getOwnerDocument().createElementNS(
-                    ODataConstants.NS_GML, ODataConstants.ELEM_GEOMEMBERS);
+                    Constants.NS_GML, Constants.ELEM_GEOMEMBERS);
             root.appendChild(geometryMembers);
 
             while (geoItor.hasNext()) {
               final JsonNode geo = geoItor.next();
-              final String collItemType = geo.get(ODataConstants.ATTR_TYPE).asText();
+              final String collItemType = geo.get(Constants.ATTR_TYPE).asText();
               final String callAsType;
               if (ODataJClientEdmPrimitiveType.GeographyCollection.name().equals(collItemType)
                       || ODataJClientEdmPrimitiveType.GeometryCollection.name().equals(collItemType)) {
@@ -213,25 +213,25 @@ final class GeospatialJSONHandler {
 
     if (root != null) {
       parent.appendChild(root);
-      if (node.has(ODataConstants.JSON_CRS)) {
-        root.setAttribute(ODataConstants.ATTR_SRSNAME,
-                ODataConstants.JSON_GIS_URLPREFIX
-                + node.get(ODataConstants.JSON_CRS).get(ODataConstants.PROPERTIES).get(ODataConstants.NAME).
+      if (node.has(Constants.JSON_CRS)) {
+        root.setAttribute(Constants.ATTR_SRSNAME,
+                Constants.JSON_GIS_URLPREFIX
+                + node.get(Constants.JSON_CRS).get(Constants.PROPERTIES).get(Constants.NAME).
                 asText().split(":")[1]);
       }
     }
   }
 
   private static void serializeCrs(final JsonGenerator jgen, final Node node) throws IOException {
-    if (node.getAttributes().getNamedItem(ODataConstants.ATTR_SRSNAME) != null) {
-      final String srsName = node.getAttributes().getNamedItem(ODataConstants.ATTR_SRSNAME).getTextContent();
-      final int prefIdx = srsName.indexOf(ODataConstants.JSON_GIS_URLPREFIX);
-      final String crsValue = srsName.substring(prefIdx + ODataConstants.JSON_GIS_URLPREFIX.length());
-
-      jgen.writeObjectFieldStart(ODataConstants.JSON_CRS);
-      jgen.writeStringField(ODataConstants.ATTR_TYPE, ODataConstants.NAME);
-      jgen.writeObjectFieldStart(ODataConstants.PROPERTIES);
-      jgen.writeStringField(ODataConstants.NAME, "EPSG:" + crsValue);
+    if (node.getAttributes().getNamedItem(Constants.ATTR_SRSNAME) != null) {
+      final String srsName = node.getAttributes().getNamedItem(Constants.ATTR_SRSNAME).getTextContent();
+      final int prefIdx = srsName.indexOf(Constants.JSON_GIS_URLPREFIX);
+      final String crsValue = srsName.substring(prefIdx + Constants.JSON_GIS_URLPREFIX.length());
+
+      jgen.writeObjectFieldStart(Constants.JSON_CRS);
+      jgen.writeStringField(Constants.ATTR_TYPE, Constants.NAME);
+      jgen.writeObjectFieldStart(Constants.PROPERTIES);
+      jgen.writeStringField(Constants.NAME, "EPSG:" + crsValue);
       jgen.writeEndObject();
       jgen.writeEndObject();
     }
@@ -244,7 +244,7 @@ final class GeospatialJSONHandler {
   }
 
   private static void serializeLineString(final JsonGenerator jgen, final Element node) throws IOException {
-    for (Element element : XMLUtils.getChildElements(node, ODataConstants.ELEM_POS)) {
+    for (Element element : XMLUtils.getChildElements(node, Constants.ELEM_POS)) {
       jgen.writeStartArray();
       serializePoint(jgen, element);
       jgen.writeEndArray();
@@ -252,17 +252,17 @@ final class GeospatialJSONHandler {
   }
 
   private static void serializePolygon(final JsonGenerator jgen, final Element node) throws IOException {
-    for (Element exterior : XMLUtils.getChildElements(node, ODataConstants.ELEM_POLYGON_EXTERIOR)) {
+    for (Element exterior : XMLUtils.getChildElements(node, Constants.ELEM_POLYGON_EXTERIOR)) {
       jgen.writeStartArray();
       serializeLineString(jgen,
-              XMLUtils.getChildElements(exterior, ODataConstants.ELEM_POLYGON_LINEARRING).get(0));
+              XMLUtils.getChildElements(exterior, Constants.ELEM_POLYGON_LINEARRING).get(0));
       jgen.writeEndArray();
 
     }
-    for (Element interior : XMLUtils.getChildElements(node, ODataConstants.ELEM_POLYGON_INTERIOR)) {
+    for (Element interior : XMLUtils.getChildElements(node, Constants.ELEM_POLYGON_INTERIOR)) {
       jgen.writeStartArray();
       serializeLineString(jgen,
-              XMLUtils.getChildElements(interior, ODataConstants.ELEM_POLYGON_LINEARRING).get(0));
+              XMLUtils.getChildElements(interior, Constants.ELEM_POLYGON_LINEARRING).get(0));
       jgen.writeEndArray();
 
     }
@@ -276,35 +276,35 @@ final class GeospatialJSONHandler {
     if (edmSimpleType.equals(ODataJClientEdmPrimitiveType.GeographyCollection)
             || edmSimpleType.equals(ODataJClientEdmPrimitiveType.GeometryCollection)) {
 
-      jgen.writeStringField(ODataConstants.ATTR_TYPE, ODataJClientEdmPrimitiveType.GeometryCollection.name());
+      jgen.writeStringField(Constants.ATTR_TYPE, ODataJClientEdmPrimitiveType.GeometryCollection.name());
     } else {
       final int yIdx = edmSimpleType.name().indexOf('y');
       final String itemType = edmSimpleType.name().substring(yIdx + 1);
-      jgen.writeStringField(ODataConstants.ATTR_TYPE, itemType);
+      jgen.writeStringField(Constants.ATTR_TYPE, itemType);
     }
 
     Element root = null;
     switch (edmSimpleType) {
       case GeographyPoint:
       case GeometryPoint:
-        root = XMLUtils.getChildElements(node, ODataConstants.ELEM_POINT).get(0);
+        root = XMLUtils.getChildElements(node, Constants.ELEM_POINT).get(0);
 
-        jgen.writeArrayFieldStart(ODataConstants.JSON_COORDINATES);
-        serializePoint(jgen, XMLUtils.getChildElements(root, ODataConstants.ELEM_POS).get(0));
+        jgen.writeArrayFieldStart(Constants.JSON_COORDINATES);
+        serializePoint(jgen, XMLUtils.getChildElements(root, Constants.ELEM_POS).get(0));
         jgen.writeEndArray();
         break;
 
       case GeographyMultiPoint:
       case GeometryMultiPoint:
-        root = XMLUtils.getChildElements(node, ODataConstants.ELEM_MULTIPOINT).get(0);
+        root = XMLUtils.getChildElements(node, Constants.ELEM_MULTIPOINT).get(0);
 
-        jgen.writeArrayFieldStart(ODataConstants.JSON_COORDINATES);
+        jgen.writeArrayFieldStart(Constants.JSON_COORDINATES);
 
-        final List<Element> pMembs = XMLUtils.getChildElements(root, ODataConstants.ELEM_POINTMEMBERS);
+        final List<Element> pMembs = XMLUtils.getChildElements(root, Constants.ELEM_POINTMEMBERS);
         if (pMembs != null && !pMembs.isEmpty()) {
-          for (Element point : XMLUtils.getChildElements(pMembs.get(0), ODataConstants.ELEM_POINT)) {
+          for (Element point : XMLUtils.getChildElements(pMembs.get(0), Constants.ELEM_POINT)) {
             jgen.writeStartArray();
-            serializePoint(jgen, XMLUtils.getChildElements(point, ODataConstants.ELEM_POS).get(0));
+            serializePoint(jgen, XMLUtils.getChildElements(point, Constants.ELEM_POS).get(0));
             jgen.writeEndArray();
           }
         }
@@ -314,22 +314,22 @@ final class GeospatialJSONHandler {
 
       case GeographyLineString:
       case GeometryLineString:
-        root = XMLUtils.getChildElements(node, ODataConstants.ELEM_LINESTRING).get(0);
+        root = XMLUtils.getChildElements(node, Constants.ELEM_LINESTRING).get(0);
 
-        jgen.writeArrayFieldStart(ODataConstants.JSON_COORDINATES);
+        jgen.writeArrayFieldStart(Constants.JSON_COORDINATES);
         serializeLineString(jgen, root);
         jgen.writeEndArray();
         break;
 
       case GeographyMultiLineString:
       case GeometryMultiLineString:
-        root = XMLUtils.getChildElements(node, ODataConstants.ELEM_MULTILINESTRING).get(0);
+        root = XMLUtils.getChildElements(node, Constants.ELEM_MULTILINESTRING).get(0);
 
-        jgen.writeArrayFieldStart(ODataConstants.JSON_COORDINATES);
+        jgen.writeArrayFieldStart(Constants.JSON_COORDINATES);
 
-        final List<Element> lMembs = XMLUtils.getChildElements(root, ODataConstants.ELEM_LINESTRINGMEMBERS);
+        final List<Element> lMembs = XMLUtils.getChildElements(root, Constants.ELEM_LINESTRINGMEMBERS);
         if (lMembs != null && !lMembs.isEmpty()) {
-          for (Element lineStr : XMLUtils.getChildElements(lMembs.get(0), ODataConstants.ELEM_LINESTRING)) {
+          for (Element lineStr : XMLUtils.getChildElements(lMembs.get(0), Constants.ELEM_LINESTRING)) {
             jgen.writeStartArray();
             serializeLineString(jgen, lineStr);
             jgen.writeEndArray();
@@ -341,22 +341,22 @@ final class GeospatialJSONHandler {
 
       case GeographyPolygon:
       case GeometryPolygon:
-        root = XMLUtils.getChildElements(node, ODataConstants.ELEM_POLYGON).get(0);
+        root = XMLUtils.getChildElements(node, Constants.ELEM_POLYGON).get(0);
 
-        jgen.writeArrayFieldStart(ODataConstants.JSON_COORDINATES);
+        jgen.writeArrayFieldStart(Constants.JSON_COORDINATES);
         serializePolygon(jgen, root);
         jgen.writeEndArray();
         break;
 
       case GeographyMultiPolygon:
       case GeometryMultiPolygon:
-        root = XMLUtils.getChildElements(node, ODataConstants.ELEM_MULTIPOLYGON).get(0);
+        root = XMLUtils.getChildElements(node, Constants.ELEM_MULTIPOLYGON).get(0);
 
-        jgen.writeArrayFieldStart(ODataConstants.JSON_COORDINATES);
+        jgen.writeArrayFieldStart(Constants.JSON_COORDINATES);
 
-        final List<Element> mpMembs = XMLUtils.getChildElements(root, ODataConstants.ELEM_SURFACEMEMBERS);
+        final List<Element> mpMembs = XMLUtils.getChildElements(root, Constants.ELEM_SURFACEMEMBERS);
         if (mpMembs != null & !mpMembs.isEmpty()) {
-          for (Element pol : XMLUtils.getChildElements(mpMembs.get(0), ODataConstants.ELEM_POLYGON)) {
+          for (Element pol : XMLUtils.getChildElements(mpMembs.get(0), Constants.ELEM_POLYGON)) {
             jgen.writeStartArray();
             serializePolygon(jgen, pol);
             jgen.writeEndArray();
@@ -368,11 +368,11 @@ final class GeospatialJSONHandler {
 
       case GeographyCollection:
       case GeometryCollection:
-        root = XMLUtils.getChildElements(node, ODataConstants.ELEM_GEOCOLLECTION).get(0);
+        root = XMLUtils.getChildElements(node, Constants.ELEM_GEOCOLLECTION).get(0);
 
-        final List<Element> cMembs = XMLUtils.getChildElements(root, ODataConstants.ELEM_GEOMEMBERS);
+        final List<Element> cMembs = XMLUtils.getChildElements(root, Constants.ELEM_GEOMEMBERS);
         if (cMembs != null && !cMembs.isEmpty()) {
-          jgen.writeArrayFieldStart(ODataConstants.JSON_GEOMETRIES);
+          jgen.writeArrayFieldStart(Constants.JSON_GEOMETRIES);
 
           for (Node geom : XMLUtils.getChildNodes(cMembs.get(0), Node.ELEMENT_NODE)) {
             try {
@@ -382,7 +382,7 @@ final class GeospatialJSONHandler {
               final Element fakeParent = doc.createElementNS(
                       client.getServiceVersion().getNamespaceMap().
                       get(ODataServiceVersion.NS_DATASERVICES),
-                      ODataConstants.PREFIX_DATASERVICES + "fake");
+                      Constants.PREFIX_DATASERVICES + "fake");
               fakeParent.appendChild(doc.importNode(geom, true));
 
               final ODataJClientEdmPrimitiveType callAsType = XMLUtils.simpleTypeForNode(

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONDOMTreeUtils.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONDOMTreeUtils.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONDOMTreeUtils.java
index bfe36ff..f70cae9 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONDOMTreeUtils.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONDOMTreeUtils.java
@@ -24,7 +24,7 @@ import java.io.IOException;
 import java.util.Iterator;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.client.api.ODataClient;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
 import org.apache.olingo.client.api.domain.ODataPrimitiveValue;
 import org.apache.olingo.client.api.utils.XMLUtils;
@@ -60,14 +60,14 @@ final class JSONDOMTreeUtils {
       if (name.isEmpty()) {
         final Element element = parent.getOwnerDocument().createElementNS(
                 client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES),
-                ODataConstants.PREFIX_DATASERVICES + ODataConstants.ELEM_ELEMENT);
+                Constants.PREFIX_DATASERVICES + Constants.ELEM_ELEMENT);
         parent.appendChild(element);
 
         if (child.isValueNode()) {
           if (child.isNull()) {
             element.setAttributeNS(
                     client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
-                    ODataConstants.ATTR_NULL, Boolean.toString(true));
+                    Constants.ATTR_NULL, Boolean.toString(true));
           } else {
             element.appendChild(parent.getOwnerDocument().createTextNode(child.asText()));
           }
@@ -76,85 +76,85 @@ final class JSONDOMTreeUtils {
         if (child.isContainerNode()) {
           buildSubtree(client, element, child);
         }
-      } else if (!name.contains("@") && !ODataConstants.JSON_TYPE.equals(name)) {
+      } else if (!name.contains("@") && !Constants.JSON_TYPE.equals(name)) {
         final Element property = parent.getOwnerDocument().createElementNS(
                 client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES),
-                ODataConstants.PREFIX_DATASERVICES + name);
+                Constants.PREFIX_DATASERVICES + name);
         parent.appendChild(property);
 
         boolean typeSet = false;
-        if (node.hasNonNull(name + "@" + ODataConstants.JSON_TYPE)) {
+        if (node.hasNonNull(name + "@" + Constants.JSON_TYPE)) {
           property.setAttributeNS(
                   client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
-                  ODataConstants.ATTR_M_TYPE,
-                  node.get(name + "@" + ODataConstants.JSON_TYPE).textValue());
+                  Constants.ATTR_M_TYPE,
+                  node.get(name + "@" + Constants.JSON_TYPE).textValue());
           typeSet = true;
         }
 
         if (child.isNull()) {
           property.setAttributeNS(client.getServiceVersion().getNamespaceMap().
                   get(ODataServiceVersion.NS_METADATA),
-                  ODataConstants.ATTR_NULL, Boolean.toString(true));
+                  Constants.ATTR_NULL, Boolean.toString(true));
         } else if (child.isValueNode()) {
           if (!typeSet) {
             if (child.isInt()) {
               property.setAttributeNS(
                       client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
-                      ODataConstants.ATTR_M_TYPE, ODataJClientEdmPrimitiveType.Int32.toString());
+                      Constants.ATTR_M_TYPE, ODataJClientEdmPrimitiveType.Int32.toString());
             }
             if (child.isLong()) {
               property.setAttributeNS(
                       client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
-                      ODataConstants.ATTR_M_TYPE, ODataJClientEdmPrimitiveType.Int64.toString());
+                      Constants.ATTR_M_TYPE, ODataJClientEdmPrimitiveType.Int64.toString());
             }
             if (child.isBigDecimal()) {
               property.setAttributeNS(
                       client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
-                      ODataConstants.ATTR_M_TYPE, ODataJClientEdmPrimitiveType.Decimal.toString());
+                      Constants.ATTR_M_TYPE, ODataJClientEdmPrimitiveType.Decimal.toString());
             }
             if (child.isDouble()) {
               property.setAttributeNS(
                       client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
-                      ODataConstants.ATTR_M_TYPE, ODataJClientEdmPrimitiveType.Double.toString());
+                      Constants.ATTR_M_TYPE, ODataJClientEdmPrimitiveType.Double.toString());
             }
             if (child.isBoolean()) {
               property.setAttributeNS(
                       client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
-                      ODataConstants.ATTR_M_TYPE, ODataJClientEdmPrimitiveType.Boolean.toString());
+                      Constants.ATTR_M_TYPE, ODataJClientEdmPrimitiveType.Boolean.toString());
             }
             if (child.isTextual()) {
               property.setAttributeNS(
                       client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
-                      ODataConstants.ATTR_M_TYPE, ODataJClientEdmPrimitiveType.String.toString());
+                      Constants.ATTR_M_TYPE, ODataJClientEdmPrimitiveType.String.toString());
             }
           }
 
           property.appendChild(parent.getOwnerDocument().createTextNode(child.asText()));
         } else if (child.isContainerNode()) {
-          if (!typeSet && child.hasNonNull(ODataConstants.JSON_TYPE)) {
+          if (!typeSet && child.hasNonNull(Constants.JSON_TYPE)) {
             property.
                     setAttributeNS(client.getServiceVersion().getNamespaceMap().
                             get(ODataServiceVersion.NS_METADATA),
-                            ODataConstants.ATTR_M_TYPE,
-                            child.get(ODataConstants.JSON_TYPE).textValue());
+                            Constants.ATTR_M_TYPE,
+                            child.get(Constants.JSON_TYPE).textValue());
           }
 
-          final String type = property.getAttribute(ODataConstants.ATTR_M_TYPE);
+          final String type = property.getAttribute(Constants.ATTR_M_TYPE);
           if (StringUtils.isNotBlank(type) && ODataJClientEdmPrimitiveType.isGeospatial(type)) {
             if (ODataJClientEdmPrimitiveType.Geography.toString().equals(type)
                     || ODataJClientEdmPrimitiveType.Geometry.toString().equals(type)) {
 
-              final String geoType = child.get(ODataConstants.ATTR_TYPE).textValue();
+              final String geoType = child.get(Constants.ATTR_TYPE).textValue();
               property.setAttributeNS(client.getServiceVersion().getNamespaceMap().get(
-                      ODataServiceVersion.NS_METADATA), ODataConstants.ATTR_M_TYPE,
+                      ODataServiceVersion.NS_METADATA), Constants.ATTR_M_TYPE,
                       geoType.startsWith("Geo")
                       ? ODataJClientEdmPrimitiveType.namespace() + "." + geoType
                       : type + geoType);
             }
 
-            if (child.has(ODataConstants.JSON_COORDINATES) || child.has(ODataConstants.JSON_GEOMETRIES)) {
+            if (child.has(Constants.JSON_COORDINATES) || child.has(Constants.JSON_GEOMETRIES)) {
               GeospatialJSONHandler.deserialize(
-                      child, property, property.getAttribute(ODataConstants.ATTR_M_TYPE));
+                      child, property, property.getAttribute(Constants.ATTR_M_TYPE));
             }
           } else {
             buildSubtree(client, property, child);
@@ -194,9 +194,9 @@ final class JSONDOMTreeUtils {
     for (Node child : XMLUtils.getChildNodes(content, Node.ELEMENT_NODE)) {
       final String childName = XMLUtils.getSimpleName(child);
 
-      final Node typeAttr = child.getAttributes().getNamedItem(ODataConstants.ATTR_M_TYPE);
+      final Node typeAttr = child.getAttributes().getNamedItem(Constants.ATTR_M_TYPE);
       if (typeAttr != null && ODataJClientEdmPrimitiveType.isGeospatial(typeAttr.getTextContent())) {
-        jgen.writeStringField(propType ? ODataConstants.JSON_TYPE : childName + "@" + ODataConstants.JSON_TYPE,
+        jgen.writeStringField(propType ? Constants.JSON_TYPE : childName + "@" + Constants.JSON_TYPE,
                 typeAttr.getTextContent());
 
         jgen.writeObjectFieldStart(childName);
@@ -213,13 +213,13 @@ final class JSONDOMTreeUtils {
                     setText(child.getChildNodes().item(0).getNodeValue()).build();
             out = value.toString();
 
-            jgen.writeStringField(childName + "@" + ODataConstants.JSON_TYPE, type.toString());
+            jgen.writeStringField(childName + "@" + Constants.JSON_TYPE, type.toString());
           }
           jgen.writeStringField(childName, out);
         } else {
-          if (child.getAttributes().getNamedItem(ODataConstants.ATTR_NULL) == null) {
+          if (child.getAttributes().getNamedItem(Constants.ATTR_NULL) == null) {
             if (typeAttr != null && ODataJClientEdmPrimitiveType.String.toString().equals(typeAttr.getTextContent())) {
-              jgen.writeStringField(childName + "@" + ODataConstants.JSON_TYPE, typeAttr.getTextContent());
+              jgen.writeStringField(childName + "@" + Constants.JSON_TYPE, typeAttr.getTextContent());
               jgen.writeStringField(childName, StringUtils.EMPTY);
             } else {
               jgen.writeArrayFieldStart(childName);
@@ -247,7 +247,7 @@ final class JSONDOMTreeUtils {
         } else {
           jgen.writeObjectFieldStart(childName);
           if (typeAttr != null) {
-            jgen.writeStringField(ODataConstants.JSON_TYPE, typeAttr.getTextContent());
+            jgen.writeStringField(Constants.JSON_TYPE, typeAttr.getTextContent());
           }
 
           writeSubtree(client, jgen, child);

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONEntryDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONEntryDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONEntryDeserializer.java
index fad32ec..035a059 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONEntryDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONEntryDeserializer.java
@@ -34,7 +34,7 @@ import java.util.Map;
 import java.util.Set;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.ParserConfigurationException;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.domain.ODataLinkType;
 import org.apache.olingo.client.api.domain.ODataOperation;
 import org.apache.olingo.client.api.utils.XMLUtils;
@@ -87,73 +87,73 @@ public class JSONEntryDeserializer extends ODataJacksonDeserializer<JSONEntryImp
 
     final ObjectNode tree = (ObjectNode) parser.getCodec().readTree(parser);
 
-    if (tree.has(ODataConstants.JSON_VALUE) && tree.get(ODataConstants.JSON_VALUE).isArray()) {
+    if (tree.has(Constants.JSON_VALUE) && tree.get(Constants.JSON_VALUE).isArray()) {
       throw new JsonParseException("Expected OData Entity, found EntitySet", parser.getCurrentLocation());
     }
 
     final boolean isMediaEntry =
-            tree.hasNonNull(ODataConstants.JSON_MEDIAREAD_LINK)
-            && tree.hasNonNull(ODataConstants.JSON_MEDIA_CONTENT_TYPE);
+            tree.hasNonNull(Constants.JSON_MEDIAREAD_LINK)
+            && tree.hasNonNull(Constants.JSON_MEDIA_CONTENT_TYPE);
 
     final JSONEntryImpl entry = new JSONEntryImpl();
 
-    if (tree.hasNonNull(ODataConstants.JSON_METADATA)) {
-      entry.setMetadata(URI.create(tree.get(ODataConstants.JSON_METADATA).textValue()));
-      tree.remove(ODataConstants.JSON_METADATA);
+    if (tree.hasNonNull(Constants.JSON_METADATA)) {
+      entry.setMetadata(URI.create(tree.get(Constants.JSON_METADATA).textValue()));
+      tree.remove(Constants.JSON_METADATA);
     }
 
-    if (tree.hasNonNull(ODataConstants.JSON_MEDIA_ETAG)) {
-      entry.setMediaETag(tree.get(ODataConstants.JSON_MEDIA_ETAG).textValue());
-      tree.remove(ODataConstants.JSON_MEDIA_ETAG);
+    if (tree.hasNonNull(Constants.JSON_MEDIA_ETAG)) {
+      entry.setMediaETag(tree.get(Constants.JSON_MEDIA_ETAG).textValue());
+      tree.remove(Constants.JSON_MEDIA_ETAG);
     }
 
-    if (tree.hasNonNull(ODataConstants.JSON_ETAG)) {
-      entry.setETag(tree.get(ODataConstants.JSON_ETAG).textValue());
-      tree.remove(ODataConstants.JSON_ETAG);
+    if (tree.hasNonNull(Constants.JSON_ETAG)) {
+      entry.setETag(tree.get(Constants.JSON_ETAG).textValue());
+      tree.remove(Constants.JSON_ETAG);
     }
 
-    if (tree.hasNonNull(ODataConstants.JSON_TYPE)) {
-      entry.setType(tree.get(ODataConstants.JSON_TYPE).textValue());
-      tree.remove(ODataConstants.JSON_TYPE);
+    if (tree.hasNonNull(Constants.JSON_TYPE)) {
+      entry.setType(tree.get(Constants.JSON_TYPE).textValue());
+      tree.remove(Constants.JSON_TYPE);
     }
 
-    if (tree.hasNonNull(ODataConstants.JSON_ID)) {
-      entry.setId(tree.get(ODataConstants.JSON_ID).textValue());
-      tree.remove(ODataConstants.JSON_ID);
+    if (tree.hasNonNull(Constants.JSON_ID)) {
+      entry.setId(tree.get(Constants.JSON_ID).textValue());
+      tree.remove(Constants.JSON_ID);
     }
 
-    if (tree.hasNonNull(ODataConstants.JSON_READ_LINK)) {
+    if (tree.hasNonNull(Constants.JSON_READ_LINK)) {
       final LinkImpl link = new LinkImpl();
-      link.setRel(ODataConstants.SELF_LINK_REL);
-      link.setHref(tree.get(ODataConstants.JSON_READ_LINK).textValue());
+      link.setRel(Constants.SELF_LINK_REL);
+      link.setHref(tree.get(Constants.JSON_READ_LINK).textValue());
       entry.setSelfLink(link);
 
-      tree.remove(ODataConstants.JSON_READ_LINK);
+      tree.remove(Constants.JSON_READ_LINK);
     }
 
-    if (tree.hasNonNull(ODataConstants.JSON_EDIT_LINK)) {
+    if (tree.hasNonNull(Constants.JSON_EDIT_LINK)) {
       final LinkImpl link = new LinkImpl();
-      link.setRel(ODataConstants.EDIT_LINK_REL);
-      link.setHref(tree.get(ODataConstants.JSON_EDIT_LINK).textValue());
+      link.setRel(Constants.EDIT_LINK_REL);
+      link.setHref(tree.get(Constants.JSON_EDIT_LINK).textValue());
       entry.setEditLink(link);
 
-      tree.remove(ODataConstants.JSON_EDIT_LINK);
+      tree.remove(Constants.JSON_EDIT_LINK);
     }
 
-    if (tree.hasNonNull(ODataConstants.JSON_MEDIAREAD_LINK)) {
-      entry.setMediaContentSource(tree.get(ODataConstants.JSON_MEDIAREAD_LINK).textValue());
-      tree.remove(ODataConstants.JSON_MEDIAREAD_LINK);
+    if (tree.hasNonNull(Constants.JSON_MEDIAREAD_LINK)) {
+      entry.setMediaContentSource(tree.get(Constants.JSON_MEDIAREAD_LINK).textValue());
+      tree.remove(Constants.JSON_MEDIAREAD_LINK);
     }
-    if (tree.hasNonNull(ODataConstants.JSON_MEDIAEDIT_LINK)) {
+    if (tree.hasNonNull(Constants.JSON_MEDIAEDIT_LINK)) {
       /*final LinkImpl link = new LinkImpl();
-      link.setHref(tree.get(ODataConstants.JSON_MEDIAEDIT_LINK).textValue());
+      link.setHref(tree.get(Constants.JSON_MEDIAEDIT_LINK).textValue());
       entry.getMediaEditLinks().add(link);*/
 
-      tree.remove(ODataConstants.JSON_MEDIAEDIT_LINK);
+      tree.remove(Constants.JSON_MEDIAEDIT_LINK);
     }
-    if (tree.hasNonNull(ODataConstants.JSON_MEDIA_CONTENT_TYPE)) {
-      entry.setMediaContentType(tree.get(ODataConstants.JSON_MEDIA_CONTENT_TYPE).textValue());
-      tree.remove(ODataConstants.JSON_MEDIA_CONTENT_TYPE);
+    if (tree.hasNonNull(Constants.JSON_MEDIA_CONTENT_TYPE)) {
+      entry.setMediaContentType(tree.get(Constants.JSON_MEDIA_CONTENT_TYPE).textValue());
+      tree.remove(Constants.JSON_MEDIA_CONTENT_TYPE);
     }
 
     final Set<String> toRemove = new HashSet<String>();
@@ -161,7 +161,7 @@ public class JSONEntryDeserializer extends ODataJacksonDeserializer<JSONEntryImp
     while (itor.hasNext()) {
       final Map.Entry<String, JsonNode> field = itor.next();
 
-      if (field.getKey().endsWith(ODataConstants.JSON_NAVIGATION_LINK_SUFFIX)) {
+      if (field.getKey().endsWith(Constants.JSON_NAVIGATION_LINK_SUFFIX)) {
         final LinkImpl link = new LinkImpl();
         link.setTitle(getTitle(field));
         link.setRel(client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NAVIGATION_LINK_REL)
@@ -179,8 +179,8 @@ public class JSONEntryDeserializer extends ODataJacksonDeserializer<JSONEntryImp
 
         toRemove.add(field.getKey());
         toRemove.add(setInline(field.getKey(),
-                ODataConstants.JSON_NAVIGATION_LINK_SUFFIX, tree, parser.getCodec(), link));
-      } else if (field.getKey().endsWith(ODataConstants.JSON_ASSOCIATION_LINK_SUFFIX)) {
+                Constants.JSON_NAVIGATION_LINK_SUFFIX, tree, parser.getCodec(), link));
+      } else if (field.getKey().endsWith(Constants.JSON_ASSOCIATION_LINK_SUFFIX)) {
         final LinkImpl link = new LinkImpl();
         link.setTitle(getTitle(field));
         link.setRel(client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.ASSOCIATION_LINK_REL)
@@ -190,7 +190,7 @@ public class JSONEntryDeserializer extends ODataJacksonDeserializer<JSONEntryImp
         entry.getAssociationLinks().add(link);
 
         toRemove.add(field.getKey());
-      } else if (field.getKey().endsWith(ODataConstants.JSON_MEDIAEDIT_LINK_SUFFIX)) {
+      } else if (field.getKey().endsWith(Constants.JSON_MEDIAEDIT_LINK_SUFFIX)) {
         final LinkImpl link = new LinkImpl();
         link.setTitle(getTitle(field));
         link.setRel(client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.MEDIA_EDIT_LINK_REL)
@@ -201,14 +201,14 @@ public class JSONEntryDeserializer extends ODataJacksonDeserializer<JSONEntryImp
 
         toRemove.add(field.getKey());
         toRemove.add(setInline(field.getKey(),
-                ODataConstants.JSON_MEDIAEDIT_LINK_SUFFIX, tree, parser.getCodec(), link));
+                Constants.JSON_MEDIAEDIT_LINK_SUFFIX, tree, parser.getCodec(), link));
       } else if (field.getKey().charAt(0) == '#') {
         final ODataOperation operation = new ODataOperation();
         operation.setMetadataAnchor(field.getKey());
 
         final ObjectNode opNode = (ObjectNode) tree.get(field.getKey());
-        operation.setTitle(opNode.get(ODataConstants.ATTR_TITLE).asText());
-        operation.setTarget(URI.create(opNode.get(ODataConstants.ATTR_TARGET).asText()));
+        operation.setTitle(opNode.get(Constants.ATTR_TITLE).asText());
+        operation.setTarget(URI.create(opNode.get(Constants.ATTR_TARGET).asText()));
 
         entry.getOperations().add(operation);
 
@@ -223,7 +223,7 @@ public class JSONEntryDeserializer extends ODataJacksonDeserializer<JSONEntryImp
 
       final Element properties = document.createElementNS(
               client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA),
-              ODataConstants.ELEM_PROPERTIES);
+              Constants.ELEM_PROPERTIES);
 
       JSONDOMTreeUtils.buildSubtree(client, properties, tree);
 

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONEntrySerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONEntrySerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONEntrySerializer.java
index 2a35606..36d0d84 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONEntrySerializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONEntrySerializer.java
@@ -27,7 +27,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.data.Link;
 import org.apache.olingo.client.api.domain.ODataLinkType;
 
@@ -43,28 +43,28 @@ public class JSONEntrySerializer extends ODataJacksonSerializer<JSONEntryImpl> {
     jgen.writeStartObject();
 
     if (entry.getMetadata() != null) {
-      jgen.writeStringField(ODataConstants.JSON_METADATA, entry.getMetadata().toASCIIString());
+      jgen.writeStringField(Constants.JSON_METADATA, entry.getMetadata().toASCIIString());
     }
     if (StringUtils.isNotBlank(entry.getType())) {
-      jgen.writeStringField(ODataConstants.JSON_TYPE, entry.getType());
+      jgen.writeStringField(Constants.JSON_TYPE, entry.getType());
     }
     if (entry.getId() != null) {
-      jgen.writeStringField(ODataConstants.JSON_ID, entry.getId());
+      jgen.writeStringField(Constants.JSON_ID, entry.getId());
     }
 
     if (entry.getSelfLink() != null) {
-      jgen.writeStringField(ODataConstants.JSON_READ_LINK, entry.getSelfLink().getHref());
+      jgen.writeStringField(Constants.JSON_READ_LINK, entry.getSelfLink().getHref());
     }
 
     if (entry.getEditLink() != null) {
-      jgen.writeStringField(ODataConstants.JSON_EDIT_LINK, entry.getEditLink().getHref());
+      jgen.writeStringField(Constants.JSON_EDIT_LINK, entry.getEditLink().getHref());
     }
 
     if (entry.getMediaContentSource() != null) {
-      jgen.writeStringField(ODataConstants.JSON_MEDIAREAD_LINK, entry.getMediaContentSource());
+      jgen.writeStringField(Constants.JSON_MEDIAREAD_LINK, entry.getMediaContentSource());
     }
     if (entry.getMediaContentType() != null) {
-      jgen.writeStringField(ODataConstants.JSON_MEDIA_CONTENT_TYPE, entry.getMediaContentType());
+      jgen.writeStringField(Constants.JSON_MEDIA_CONTENT_TYPE, entry.getMediaContentType());
     }
 
     final Map<String, List<String>> entitySetLinks = new HashMap<String, List<String>>();
@@ -92,12 +92,12 @@ public class JSONEntrySerializer extends ODataJacksonSerializer<JSONEntryImpl> {
           }
           uris.add(link.getHref());
         } else {
-          jgen.writeStringField(link.getTitle() + ODataConstants.JSON_BIND_LINK_SUFFIX, link.getHref());
+          jgen.writeStringField(link.getTitle() + Constants.JSON_BIND_LINK_SUFFIX, link.getHref());
         }
       }
     }
     for (Map.Entry<String, List<String>> entitySetLink : entitySetLinks.entrySet()) {
-      jgen.writeArrayFieldStart(entitySetLink.getKey() + ODataConstants.JSON_BIND_LINK_SUFFIX);
+      jgen.writeArrayFieldStart(entitySetLink.getKey() + Constants.JSON_BIND_LINK_SUFFIX);
       for (String uri : entitySetLink.getValue()) {
         jgen.writeString(uri);
       }
@@ -106,7 +106,7 @@ public class JSONEntrySerializer extends ODataJacksonSerializer<JSONEntryImpl> {
 
     for (Link link : entry.getMediaEditLinks()) {
       if (link.getTitle() == null) {
-        jgen.writeStringField(ODataConstants.JSON_MEDIAEDIT_LINK, link.getHref());
+        jgen.writeStringField(Constants.JSON_MEDIAEDIT_LINK, link.getHref());
       }
 
       if (link.getInlineEntry() != null) {

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONFeedDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONFeedDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONFeedDeserializer.java
index 23dd23a..2b91e1e 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONFeedDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONFeedDeserializer.java
@@ -26,7 +26,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
 import java.io.IOException;
 import java.net.URI;
 import java.util.Iterator;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 
 /**
  * Reads JSON string into a feed.
@@ -43,8 +43,8 @@ public class JSONFeedDeserializer extends ODataJacksonDeserializer<JSONFeedImpl>
 
     final JSONFeedImpl feed = new JSONFeedImpl();
 
-    if (tree.hasNonNull(ODataConstants.JSON_METADATA)) {
-      feed.setMetadata(URI.create(tree.get(ODataConstants.JSON_METADATA).textValue()));
+    if (tree.hasNonNull(Constants.JSON_METADATA)) {
+      feed.setMetadata(URI.create(tree.get(Constants.JSON_METADATA).textValue()));
     }
     if (tree.hasNonNull("odata.count")) {
       feed.setCount(tree.get("odata.count").asInt());
@@ -53,8 +53,8 @@ public class JSONFeedDeserializer extends ODataJacksonDeserializer<JSONFeedImpl>
       feed.setNext(URI.create(tree.get("odata.nextLink").textValue()));
     }
 
-    if (tree.hasNonNull(ODataConstants.JSON_VALUE)) {
-      for (final Iterator<JsonNode> itor = tree.get(ODataConstants.JSON_VALUE).iterator(); itor.hasNext();) {
+    if (tree.hasNonNull(Constants.JSON_VALUE)) {
+      for (final Iterator<JsonNode> itor = tree.get(Constants.JSON_VALUE).iterator(); itor.hasNext();) {
         feed.getEntries().add(itor.next().traverse(parser.getCodec()).readValueAs(JSONEntryImpl.class));
       }
     }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertyDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertyDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertyDeserializer.java
index 6451eab..5800c83 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertyDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertyDeserializer.java
@@ -30,7 +30,7 @@ import java.util.List;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.ParserConfigurationException;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
 import org.apache.olingo.client.api.utils.XMLUtils;
 import org.w3c.dom.Document;
@@ -52,46 +52,46 @@ public class JSONPropertyDeserializer extends ODataJacksonDeserializer<JSONPrope
 
     final JSONPropertyImpl property = new JSONPropertyImpl();
 
-    if (tree.hasNonNull(ODataConstants.JSON_METADATA)) {
-      property.setMetadata(URI.create(tree.get(ODataConstants.JSON_METADATA).textValue()));
-      tree.remove(ODataConstants.JSON_METADATA);
+    if (tree.hasNonNull(Constants.JSON_METADATA)) {
+      property.setMetadata(URI.create(tree.get(Constants.JSON_METADATA).textValue()));
+      tree.remove(Constants.JSON_METADATA);
     }
 
     try {
       final DocumentBuilder builder = XMLUtils.DOC_BUILDER_FACTORY.newDocumentBuilder();
       final Document document = builder.newDocument();
 
-      Element content = document.createElement(ODataConstants.ELEM_PROPERTY);
+      Element content = document.createElement(Constants.ELEM_PROPERTY);
 
       if (property.getMetadata() != null) {
         final String metadataURI = property.getMetadata().toASCIIString();
         final int dashIdx = metadataURI.lastIndexOf('#');
         if (dashIdx != -1) {
-          content.setAttribute(ODataConstants.ATTR_M_TYPE, metadataURI.substring(dashIdx + 1));
+          content.setAttribute(Constants.ATTR_M_TYPE, metadataURI.substring(dashIdx + 1));
         }
       }
 
       JsonNode subtree = null;
-      if (tree.has(ODataConstants.JSON_VALUE)) {
-        if (tree.has(ODataConstants.JSON_TYPE)
-                && StringUtils.isBlank(content.getAttribute(ODataConstants.ATTR_M_TYPE))) {
+      if (tree.has(Constants.JSON_VALUE)) {
+        if (tree.has(Constants.JSON_TYPE)
+                && StringUtils.isBlank(content.getAttribute(Constants.ATTR_M_TYPE))) {
 
-          content.setAttribute(ODataConstants.ATTR_M_TYPE, tree.get(ODataConstants.JSON_TYPE).asText());
+          content.setAttribute(Constants.ATTR_M_TYPE, tree.get(Constants.JSON_TYPE).asText());
         }
 
-        final JsonNode value = tree.get(ODataConstants.JSON_VALUE);
+        final JsonNode value = tree.get(Constants.JSON_VALUE);
         if (value.isValueNode()) {
           content.appendChild(document.createTextNode(value.asText()));
-        } else if (ODataJClientEdmPrimitiveType.isGeospatial(content.getAttribute(ODataConstants.ATTR_M_TYPE))) {
+        } else if (ODataJClientEdmPrimitiveType.isGeospatial(content.getAttribute(Constants.ATTR_M_TYPE))) {
           subtree = tree.objectNode();
-          ((ObjectNode) subtree).put(ODataConstants.JSON_VALUE, tree.get(ODataConstants.JSON_VALUE));
-          if (StringUtils.isNotBlank(content.getAttribute(ODataConstants.ATTR_M_TYPE))) {
+          ((ObjectNode) subtree).put(Constants.JSON_VALUE, tree.get(Constants.JSON_VALUE));
+          if (StringUtils.isNotBlank(content.getAttribute(Constants.ATTR_M_TYPE))) {
             ((ObjectNode) subtree).put(
-                    ODataConstants.JSON_VALUE + "@" + ODataConstants.JSON_TYPE,
-                    content.getAttribute(ODataConstants.ATTR_M_TYPE));
+                    Constants.JSON_VALUE + "@" + Constants.JSON_TYPE,
+                    content.getAttribute(Constants.ATTR_M_TYPE));
           }
         } else {
-          subtree = tree.get(ODataConstants.JSON_VALUE);
+          subtree = tree.get(Constants.JSON_VALUE);
         }
       } else {
         subtree = tree;
@@ -104,9 +104,9 @@ public class JSONPropertyDeserializer extends ODataJacksonDeserializer<JSONPrope
       final List<Node> children = XMLUtils.getChildNodes(content, Node.ELEMENT_NODE);
       if (children.size() == 1) {
         final Element value = (Element) children.iterator().next();
-        if (ODataConstants.JSON_VALUE.equals(XMLUtils.getSimpleName(value))) {
-          if (StringUtils.isNotBlank(content.getAttribute(ODataConstants.ATTR_M_TYPE))) {
-            value.setAttribute(ODataConstants.ATTR_M_TYPE, content.getAttribute(ODataConstants.ATTR_M_TYPE));
+        if (Constants.JSON_VALUE.equals(XMLUtils.getSimpleName(value))) {
+          if (StringUtils.isNotBlank(content.getAttribute(Constants.ATTR_M_TYPE))) {
+            value.setAttribute(Constants.ATTR_M_TYPE, content.getAttribute(Constants.ATTR_M_TYPE));
           }
           content = value;
         }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertySerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertySerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertySerializer.java
index be272f1..1752e46 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertySerializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/JSONPropertySerializer.java
@@ -25,7 +25,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.SerializerProvider;
 import java.io.IOException;
 import javax.xml.parsers.DocumentBuilder;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
 import org.apache.olingo.client.api.utils.XMLUtils;
 import org.w3c.dom.Document;
@@ -45,26 +45,26 @@ public class JSONPropertySerializer extends ODataJacksonSerializer<JSONPropertyI
     jgen.writeStartObject();
 
     if (property.getMetadata() != null) {
-      jgen.writeStringField(ODataConstants.JSON_METADATA, property.getMetadata().toASCIIString());
+      jgen.writeStringField(Constants.JSON_METADATA, property.getMetadata().toASCIIString());
     }
 
     final Element content = property.getContent();
     if (XMLUtils.hasOnlyTextChildNodes(content)) {
-      jgen.writeStringField(ODataConstants.JSON_VALUE, content.getTextContent());
+      jgen.writeStringField(Constants.JSON_VALUE, content.getTextContent());
     } else {
       try {
         final DocumentBuilder builder = XMLUtils.DOC_BUILDER_FACTORY.newDocumentBuilder();
         final Document document = builder.newDocument();
-        final Element wrapper = document.createElement(ODataConstants.ELEM_PROPERTY);
+        final Element wrapper = document.createElement(Constants.ELEM_PROPERTY);
 
         if (XMLUtils.hasElementsChildNode(content)) {
           wrapper.appendChild(document.renameNode(
-                  document.importNode(content, true), null, ODataConstants.JSON_VALUE));
+                  document.importNode(content, true), null, Constants.JSON_VALUE));
 
           JSONDOMTreeUtils.writeSubtree(client, jgen, wrapper);
-        } else if (ODataJClientEdmPrimitiveType.isGeospatial(content.getAttribute(ODataConstants.ATTR_M_TYPE))) {
+        } else if (ODataJClientEdmPrimitiveType.isGeospatial(content.getAttribute(Constants.ATTR_M_TYPE))) {
           wrapper.appendChild(document.renameNode(
-                  document.importNode(content, true), null, ODataConstants.JSON_VALUE));
+                  document.importNode(content, true), null, Constants.JSON_VALUE));
 
           JSONDOMTreeUtils.writeSubtree(client, jgen, wrapper, true);
         } else {

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/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 10f5664..4a6ebc0 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
@@ -28,7 +28,7 @@ import java.io.IOException;
 import java.util.Iterator;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 
 public class JSONServiceDocumentDeserializer extends ODataJacksonDeserializer<AbstractServiceDocument> {
@@ -43,20 +43,20 @@ public class JSONServiceDocumentDeserializer extends ODataJacksonDeserializer<Ab
             ? new org.apache.olingo.client.core.data.v3.JSONServiceDocumentImpl()
             : new org.apache.olingo.client.core.data.v4.JSONServiceDocumentImpl();
 
-    if (tree.hasNonNull(ODataConstants.JSON_METADATA)
+    if (tree.hasNonNull(Constants.JSON_METADATA)
             && serviceDocument instanceof org.apache.olingo.client.core.data.v3.JSONServiceDocumentImpl) {
 
       ((org.apache.olingo.client.core.data.v3.JSONServiceDocumentImpl) serviceDocument).
-              setMetadata(tree.get(ODataConstants.JSON_METADATA).textValue());
+              setMetadata(tree.get(Constants.JSON_METADATA).textValue());
     }
-    if (tree.hasNonNull(ODataConstants.JSON_CONTEXT)
+    if (tree.hasNonNull(Constants.JSON_CONTEXT)
             && serviceDocument instanceof org.apache.olingo.client.core.data.v4.JSONServiceDocumentImpl) {
 
       ((org.apache.olingo.client.core.data.v4.JSONServiceDocumentImpl) serviceDocument).
-              setMetadataContext(tree.get(ODataConstants.JSON_CONTEXT).textValue());
+              setMetadataContext(tree.get(Constants.JSON_CONTEXT).textValue());
     }
 
-    for (final Iterator<JsonNode> itor = tree.get(ODataConstants.JSON_VALUE).elements(); itor.hasNext();) {
+    for (final Iterator<JsonNode> itor = tree.get(Constants.JSON_VALUE).elements(); itor.hasNext();) {
       final JsonNode node = itor.next();
 
       final ServiceDocumentItemImpl item = new ServiceDocumentItemImpl();

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/data/ODataEntitySetIterator.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/ODataEntitySetIterator.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/ODataEntitySetIterator.java
deleted file mode 100644
index ad9d837..0000000
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/ODataEntitySetIterator.java
+++ /dev/null
@@ -1,309 +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.client.core.data;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URI;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.client.api.ODataClient;
-import org.apache.olingo.client.api.ODataConstants;
-import org.apache.olingo.client.api.data.Entry;
-import org.apache.olingo.client.api.domain.ODataEntity;
-import org.apache.olingo.client.api.domain.ODataEntitySet;
-import org.apache.olingo.client.api.format.ODataPubFormat;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * OData entity set iterator class.
- * <br/>
- * <b>Please don't forget to call the <tt>close()>/<tt> method when not needed any more.</b>
- */
-public class ODataEntitySetIterator implements Iterator<ODataEntity> {
-
-  /**
-   * Logger.
-   */
-  private static final Logger LOG = LoggerFactory.getLogger(ODataEntitySetIterator.class);
-
-  private static final long serialVersionUID = 9039605899821494025L;
-
-  private final ODataClient odataClient;
-
-  private final InputStream stream;
-
-  private final ODataPubFormat format;
-
-  private Entry cached;
-
-  private ODataEntitySet entitySet;
-
-  private final ByteArrayOutputStream osFeed;
-
-  private final String namespaces;
-
-  private boolean available = true;
-
-  /**
-   * Constructor.
-   *
-   * @param odataClient client instance getting this request
-   * @param stream source stream.
-   * @param format OData format.
-   */
-  public ODataEntitySetIterator(final ODataClient odataClient, final InputStream stream, final ODataPubFormat format) {
-    this.odataClient = odataClient;
-    this.stream = stream;
-    this.format = format;
-    this.osFeed = new ByteArrayOutputStream();
-
-    if (format == ODataPubFormat.ATOM) {
-      namespaces = getAllElementAttributes(stream, "feed", osFeed);
-    } else {
-      namespaces = null;
-      try {
-        if (consume(stream, "\"value\":", osFeed, true) >= 0) {
-          int c = 0;
-          while (c != '[' && (c = stream.read()) >= 0) {
-            osFeed.write(c);
-          }
-        }
-      } catch (IOException e) {
-        LOG.error("Error parsing feed", e);
-        throw new IllegalStateException(e);
-      }
-    }
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public boolean hasNext() {
-    if (available && cached == null) {
-      if (format == ODataPubFormat.ATOM) {
-        cached = nextAtomEntryFromFeed(stream, osFeed, namespaces);
-      } else {
-        cached = nextJsonEntryFromFeed(stream, osFeed);
-      }
-
-      if (cached == null) {
-        available = false;
-        entitySet = odataClient.getReader().
-                readEntitySet(new ByteArrayInputStream(osFeed.toByteArray()), format);
-        close();
-      }
-    }
-
-    return available;
-  }
-
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public ODataEntity next() {
-    if (hasNext()) {
-      final ODataEntity res = odataClient.getBinder().getODataEntity(cached);
-      cached = null;
-      return res;
-    }
-
-    throw new NoSuchElementException("No entity found");
-  }
-
-  /**
-   * Unsupported operation.
-   */
-  @Override
-  public void remove() {
-    throw new UnsupportedOperationException("Operation not supported");
-  }
-
-  /**
-   * Closes the current iterator.
-   */
-  public void close() {
-    IOUtils.closeQuietly(stream);
-    IOUtils.closeQuietly(osFeed);
-  }
-
-  /**
-   * Gets the next link if exists.
-   *
-   * @return next link if exists; null otherwise.
-   */
-  public URI getNext() {
-    if (entitySet == null) {
-      throw new IllegalStateException("Iteration must be completed in order to retrieve the link for next page");
-    }
-    return entitySet.getNext();
-  }
-
-  private Entry nextJsonEntryFromFeed(final InputStream input, final OutputStream osFeed) {
-    final ByteArrayOutputStream entry = new ByteArrayOutputStream();
-
-    Entry jsonEntry = null;
-    try {
-      int c = 0;
-
-      boolean foundNewOne = false;
-
-      do {
-        c = input.read();
-        if (c == '{') {
-          entry.write(c);
-          c = -1;
-          foundNewOne = true;
-        }
-        if (c == ']') {
-          osFeed.write(c);
-          c = -1;
-        }
-      } while (c >= 0);
-
-      if (foundNewOne) {
-        int count = 1;
-        c = 0;
-
-        while (count > 0 && c >= 0) {
-          c = input.read();
-          if (c == '{') {
-            count++;
-          } else if (c == '}') {
-            count--;
-          }
-          entry.write(c);
-        }
-
-        if (c >= 0) {
-          jsonEntry = odataClient.getDeserializer().toEntry(
-                  new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.JSON);
-        }
-      } else {
-        while ((c = input.read()) >= 0) {
-          osFeed.write(c);
-        }
-      }
-    } catch (Exception e) {
-      LOG.error("Error retrieving entities from EntitySet", e);
-    }
-
-    return jsonEntry;
-  }
-
-  /**
-   * De-Serializes a stream into an OData entity set.
-   *
-   * @param input stream to de-serialize.
-   * @param format de-serialize as AtomFeed or JSONFeed
-   * @return de-serialized entity set.
-   */
-  private Entry nextAtomEntryFromFeed(final InputStream input, final OutputStream osFeed, final String namespaces) {
-    final ByteArrayOutputStream entry = new ByteArrayOutputStream();
-
-    Entry atomEntry = null;
-
-    try {
-      if (consume(input, "<entry>", osFeed, false) >= 0) {
-        entry.write("<entry ".getBytes(ODataConstants.UTF8));
-        entry.write(namespaces.getBytes(ODataConstants.UTF8));
-        entry.write(">".getBytes(ODataConstants.UTF8));
-
-        if (consume(input, "</entry>", entry, true) >= 0) {
-          atomEntry = odataClient.getDeserializer().
-                  toEntry(new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.ATOM);
-        }
-      }
-    } catch (Exception e) {
-      LOG.error("Error retrieving entities from EntitySet", e);
-    }
-
-    return atomEntry;
-  }
-
-  private String getAllElementAttributes(final InputStream input, final String name, final OutputStream os) {
-    final ByteArrayOutputStream attrs = new ByteArrayOutputStream();
-
-    String res;
-
-    try {
-      byte[] attrsDeclaration = null;
-
-      final String key = "<" + name + " ";
-      if (consume(input, key, os, true) >= 0 && consume(input, ">", attrs, false) >= 0) {
-        attrsDeclaration = attrs.toByteArray();
-        os.write(attrsDeclaration);
-        os.write('>');
-      }
-
-      res = attrsDeclaration == null
-              ? StringUtils.EMPTY
-              : new String(attrsDeclaration, ODataConstants.UTF8).trim();
-    } catch (Exception e) {
-      LOG.error("Error retrieving entities from EntitySet", e);
-      res = StringUtils.EMPTY;
-    }
-
-    return res.endsWith("/") ? res.substring(0, res.length() - 1) : res;
-  }
-
-  private int consume(
-          final InputStream input, final String end, final OutputStream os, final boolean includeEndKey)
-          throws IOException {
-
-    final char[] endKey = end.toCharArray();
-    final char[] endLowerKey = end.toLowerCase().toCharArray();
-    final char[] endUpperKey = end.toUpperCase().toCharArray();
-
-    int pos = 0;
-    int c = 0;
-    while (pos < endKey.length && (c = input.read()) >= 0) {
-      if (c == endLowerKey[pos] || c == endUpperKey[pos]) {
-        pos++;
-        if (includeEndKey && os != null) {
-          os.write(c);
-        }
-      } else if (pos > 0) {
-        if (!includeEndKey && os != null) {
-          for (int i = 0; i < pos; i++) {
-            os.write(endKey[i]);
-          }
-        }
-        if (os != null) {
-          os.write(c);
-        }
-        pos = 0;
-      } else {
-        if (os != null) {
-          os.write(c);
-        }
-      }
-    }
-
-    return c;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
index e00b921..edead41 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataBinder.java
@@ -25,7 +25,7 @@ import javax.xml.parsers.ParserConfigurationException;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.client.api.ODataClient;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.data.Entry;
 import org.apache.olingo.client.api.data.Feed;
 import org.apache.olingo.client.api.data.Link;
@@ -81,13 +81,13 @@ public abstract class AbstractODataBinder implements ODataBinder {
     try {
       final DocumentBuilder builder = XMLUtils.DOC_BUILDER_FACTORY.newDocumentBuilder();
       final Document doc = builder.newDocument();
-      properties = doc.createElement(ODataConstants.ELEM_PROPERTIES);
-      properties.setAttribute(ODataConstants.XMLNS_METADATA,
+      properties = doc.createElement(Constants.ELEM_PROPERTIES);
+      properties.setAttribute(Constants.XMLNS_METADATA,
               client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA));
-      properties.setAttribute(ODataConstants.XMLNS_DATASERVICES,
+      properties.setAttribute(Constants.XMLNS_DATASERVICES,
               client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES));
-      properties.setAttribute(ODataConstants.XMLNS_GML, ODataConstants.NS_GML);
-      properties.setAttribute(ODataConstants.XMLNS_GEORSS, ODataConstants.NS_GEORSS);
+      properties.setAttribute(Constants.XMLNS_GML, Constants.NS_GML);
+      properties.setAttribute(Constants.XMLNS_GEORSS, Constants.NS_GEORSS);
     } catch (ParserConfigurationException e) {
       LOG.error("Failure building entry content", e);
     }
@@ -143,7 +143,7 @@ public abstract class AbstractODataBinder implements ODataBinder {
       final LinkImpl entryEditLink = new LinkImpl();
       entryEditLink.setTitle(entity.getName());
       entryEditLink.setHref(editLink.toASCIIString());
-      entryEditLink.setRel(ODataConstants.EDIT_LINK_REL);
+      entryEditLink.setRel(Constants.EDIT_LINK_REL);
       entry.setEditLink(entryEditLink);
     }
 
@@ -151,7 +151,7 @@ public abstract class AbstractODataBinder implements ODataBinder {
       final LinkImpl entrySelfLink = new LinkImpl();
       entrySelfLink.setTitle(entity.getName());
       entrySelfLink.setHref(entity.getLink().toASCIIString());
-      entrySelfLink.setRel(ODataConstants.SELF_LINK_REL);
+      entrySelfLink.setRel(Constants.SELF_LINK_REL);
       entry.setSelfLink(entrySelfLink);
     }
         // -------------------------------------------------------------
@@ -367,12 +367,12 @@ public abstract class AbstractODataBinder implements ODataBinder {
   public ODataProperty getODataProperty(final Element property) {
     final ODataProperty res;
 
-    final Node nullNode = property.getAttributes().getNamedItem(ODataConstants.ATTR_NULL);
+    final Node nullNode = property.getAttributes().getNamedItem(Constants.ATTR_NULL);
 
     if (nullNode == null) {
-      final ODataJClientEdmType edmType = StringUtils.isBlank(property.getAttribute(ODataConstants.ATTR_M_TYPE))
+      final ODataJClientEdmType edmType = StringUtils.isBlank(property.getAttribute(Constants.ATTR_M_TYPE))
               ? null
-              : new ODataJClientEdmType(property.getAttribute(ODataConstants.ATTR_M_TYPE));
+              : new ODataJClientEdmType(property.getAttribute(Constants.ATTR_M_TYPE));
 
       final PropertyType propType = edmType == null
               ? guessPropertyType(property)
@@ -416,9 +416,9 @@ public abstract class AbstractODataBinder implements ODataBinder {
         final Node child = children.item(i);
 
         if (child.getNodeType() == Node.ELEMENT_NODE
-                && !child.getNodeName().startsWith(ODataConstants.PREFIX_GML)) {
+                && !child.getNodeName().startsWith(Constants.PREFIX_GML)) {
 
-          res = ODataConstants.ELEM_ELEMENT.equals(XMLUtils.getSimpleName(child))
+          res = Constants.ELEM_ELEMENT.equals(XMLUtils.getSimpleName(child))
                   ? PropertyType.COLLECTION
                   : PropertyType.COMPLEX;
         }
@@ -451,19 +451,19 @@ public abstract class AbstractODataBinder implements ODataBinder {
       element = toComplexPropertyElement(prop, doc, setType);
     }
 
-    element.setAttribute(ODataConstants.XMLNS_METADATA,
+    element.setAttribute(Constants.XMLNS_METADATA,
             client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA));
-    element.setAttribute(ODataConstants.XMLNS_DATASERVICES,
+    element.setAttribute(Constants.XMLNS_DATASERVICES,
             client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES));
-    element.setAttribute(ODataConstants.XMLNS_GML, ODataConstants.NS_GML);
-    element.setAttribute(ODataConstants.XMLNS_GEORSS, ODataConstants.NS_GEORSS);
+    element.setAttribute(Constants.XMLNS_GML, Constants.NS_GML);
+    element.setAttribute(Constants.XMLNS_GEORSS, Constants.NS_GEORSS);
 
     return element;
   }
 
   protected Element toNullPropertyElement(final ODataProperty prop, final Document doc) {
-    final Element element = doc.createElement(ODataConstants.PREFIX_DATASERVICES + prop.getName());
-    element.setAttribute(ODataConstants.ATTR_NULL, Boolean.toString(true));
+    final Element element = doc.createElement(Constants.PREFIX_DATASERVICES + prop.getName());
+    element.setAttribute(Constants.ATTR_NULL, Boolean.toString(true));
     return element;
   }
 
@@ -476,9 +476,9 @@ public abstract class AbstractODataBinder implements ODataBinder {
   protected Element toPrimitivePropertyElement(
           final String name, final ODataPrimitiveValue value, final Document doc, final boolean setType) {
 
-    final Element element = doc.createElement(ODataConstants.PREFIX_DATASERVICES + name);
+    final Element element = doc.createElement(Constants.PREFIX_DATASERVICES + name);
     if (setType) {
-      element.setAttribute(ODataConstants.ATTR_M_TYPE, value.getTypeName());
+      element.setAttribute(Constants.ATTR_M_TYPE, value.getTypeName());
     }
 
     if (value instanceof ODataGeospatialValue) {
@@ -500,18 +500,18 @@ public abstract class AbstractODataBinder implements ODataBinder {
 
     final ODataCollectionValue value = prop.getCollectionValue();
 
-    final Element element = doc.createElement(ODataConstants.PREFIX_DATASERVICES + prop.getName());
+    final Element element = doc.createElement(Constants.PREFIX_DATASERVICES + prop.getName());
     if (value.getTypeName() != null && setType) {
-      element.setAttribute(ODataConstants.ATTR_M_TYPE, value.getTypeName());
+      element.setAttribute(Constants.ATTR_M_TYPE, value.getTypeName());
     }
 
     for (ODataValue el : value) {
       if (el.isPrimitive()) {
         element.appendChild(
-                toPrimitivePropertyElement(ODataConstants.ELEM_ELEMENT, el.asPrimitive(), doc, setType));
+                toPrimitivePropertyElement(Constants.ELEM_ELEMENT, el.asPrimitive(), doc, setType));
       } else {
         element.appendChild(
-                toComplexPropertyElement(ODataConstants.ELEM_ELEMENT, el.asComplex(), doc, setType));
+                toComplexPropertyElement(Constants.ELEM_ELEMENT, el.asComplex(), doc, setType));
       }
     }
 
@@ -527,9 +527,9 @@ public abstract class AbstractODataBinder implements ODataBinder {
   protected Element toComplexPropertyElement(
           final String name, final ODataComplexValue value, final Document doc, final boolean setType) {
 
-    final Element element = doc.createElement(ODataConstants.PREFIX_DATASERVICES + name);
+    final Element element = doc.createElement(Constants.PREFIX_DATASERVICES + name);
     if (value.getTypeName() != null && setType) {
-      element.setAttribute(ODataConstants.ATTR_M_TYPE, value.getTypeName());
+      element.setAttribute(Constants.ATTR_M_TYPE, value.getTypeName());
     }
 
     for (ODataProperty field : value) {
@@ -541,7 +541,7 @@ public abstract class AbstractODataBinder implements ODataBinder {
   protected ODataPrimitiveValue fromPrimitiveValueElement(final Element prop, final ODataJClientEdmType edmType) {
     final ODataPrimitiveValue value;
     if (edmType != null && edmType.getSimpleType().isGeospatial()) {
-      final Element geoProp = ODataConstants.PREFIX_GML.equals(prop.getPrefix())
+      final Element geoProp = Constants.PREFIX_GML.equals(prop.getPrefix())
               ? prop : (Element) XMLUtils.getChildNodes(prop, Node.ELEMENT_NODE).get(0);
       value = client.getGeospatialValueBuilder().
               setType(edmType.getSimpleType()).setTree(geoProp).build();

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
index 43636b3..c3c5fb0 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataDeserializer.java
@@ -29,7 +29,7 @@ import java.io.InputStream;
 import java.net.URI;
 
 import org.apache.olingo.client.api.ODataClient;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.data.Entry;
 import org.apache.olingo.client.api.data.Error;
 import org.apache.olingo.client.api.data.Feed;
@@ -150,9 +150,9 @@ public abstract class AbstractODataDeserializer extends AbstractJacksonTool impl
   protected XMLLinkCollectionImpl toLinkCollectionFromXML(final InputStream input) {
     final Element root = toDOM(input);
 
-    final NodeList uris = root.getOwnerDocument().getElementsByTagName(ODataConstants.ELEM_URI);
+    final NodeList uris = root.getOwnerDocument().getElementsByTagName(Constants.ELEM_URI);
 
-    final NodeList next = root.getElementsByTagName(ODataConstants.NEXT_LINK_REL);
+    final NodeList next = root.getElementsByTagName(Constants.NEXT_LINK_REL);
     final XMLLinkCollectionImpl linkCollection = next.getLength() > 0
             ? new XMLLinkCollectionImpl(URI.create(next.item(0).getTextContent()))
             : new XMLLinkCollectionImpl();

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataReader.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataReader.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataReader.java
index d8a85c6..dad3707 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataReader.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataReader.java
@@ -22,10 +22,11 @@ import java.io.InputStream;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.client.api.ODataClient;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.data.Error;
 import org.apache.olingo.client.api.domain.ODataEntity;
 import org.apache.olingo.client.api.domain.ODataEntitySet;
+import org.apache.olingo.client.api.domain.ODataEntitySetIterator;
 import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
 import org.apache.olingo.client.api.domain.ODataLinkCollection;
 import org.apache.olingo.client.api.domain.ODataProperty;
@@ -36,7 +37,6 @@ import org.apache.olingo.client.api.format.ODataFormat;
 import org.apache.olingo.client.api.format.ODataPubFormat;
 import org.apache.olingo.client.api.format.ODataValueFormat;
 import org.apache.olingo.client.api.op.ODataReader;
-import org.apache.olingo.client.core.data.ODataEntitySetIterator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Element;
@@ -88,12 +88,12 @@ public abstract class AbstractODataReader implements ODataReader {
     //     <functionImportName m:type="Collection(AnotherType)">
     //       <element m:type="AnotherType">...</element>
     //     <functionImportName>
-    final String type = property.getAttribute(ODataConstants.ATTR_M_TYPE);
-    final NodeList elements = property.getElementsByTagName(ODataConstants.ELEM_ELEMENT);
+    final String type = property.getAttribute(Constants.ATTR_M_TYPE);
+    final NodeList elements = property.getElementsByTagName(Constants.ELEM_ELEMENT);
     if (StringUtils.isBlank(type) && elements != null && elements.getLength() > 0) {
-      final Node elementType = elements.item(0).getAttributes().getNamedItem(ODataConstants.ATTR_M_TYPE);
+      final Node elementType = elements.item(0).getAttributes().getNamedItem(Constants.ATTR_M_TYPE);
       if (elementType != null) {
-        property.setAttribute(ODataConstants.ATTR_M_TYPE, "Collection(" + elementType.getTextContent() + ")");
+        property.setAttribute(Constants.ATTR_M_TYPE, "Collection(" + elementType.getTextContent() + ")");
       }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataSerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataSerializer.java
index 151ff49..8be014c 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataSerializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/AbstractODataSerializer.java
@@ -28,7 +28,7 @@ import java.io.Writer;
 import javax.xml.parsers.DocumentBuilder;
 
 import org.apache.olingo.client.api.ODataClient;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.data.Entry;
 import org.apache.olingo.client.api.data.Feed;
 import org.apache.olingo.client.api.data.Link;
@@ -160,7 +160,7 @@ public abstract class AbstractODataSerializer extends AbstractJacksonTool implem
       final Document doc = builder.newDocument();
       final Element uri = doc.createElementNS(
               client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES),
-              ODataConstants.ELEM_URI);
+              Constants.ELEM_URI);
       uri.appendChild(doc.createTextNode(link.getHref()));
 
       dom(uri, writer);
@@ -172,7 +172,7 @@ public abstract class AbstractODataSerializer extends AbstractJacksonTool implem
   protected void jsonLink(final Link link, final Writer writer) {
     final ObjectMapper mapper = getObjectMapper();
     final ObjectNode uri = mapper.createObjectNode();
-    uri.put(ODataConstants.JSON_URL, link.getHref());
+    uri.put(Constants.JSON_URL, link.getHref());
 
     try {
       mapper.writeValue(writer, uri);

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/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 8613695..5dded95 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
@@ -31,7 +31,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.UUID;
 import org.apache.commons.codec.binary.Base64;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
 import org.apache.olingo.client.api.domain.ODataGeospatialValue;
 import org.apache.olingo.client.api.domain.ODataPrimitiveValue;
@@ -77,7 +77,7 @@ public abstract class AbstractPrimitiveTest extends AbstractTest {
     }
 
     final InputStream written = getClient().getWriter().writeProperty(
-            getClient().getObjectFactory().newPrimitiveProperty(ODataConstants.ELEM_PROPERTY, newValue),
+            getClient().getObjectFactory().newPrimitiveProperty(Constants.ELEM_PROPERTY, newValue),
             getFormat());
     return readPrimitiveValue(written);
   }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntryTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntryTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntryTest.java
index 2e38d9f..cc90496 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntryTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/EntryTest.java
@@ -25,7 +25,7 @@ import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
 import java.io.InputStream;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.ODataV3Client;
 import org.apache.olingo.client.api.data.Entry;
 import org.apache.olingo.client.api.format.ODataPubFormat;
@@ -72,7 +72,7 @@ public class EntryTest extends AbstractTest {
     assertNotNull(entry.getBaseURI());
 
     final Element content = entry.getContent();
-    assertEquals(ODataConstants.ELEM_PROPERTIES, content.getNodeName());
+    assertEquals(Constants.ELEM_PROPERTIES, content.getNodeName());
 
     boolean entered = false;
     boolean checked = false;
@@ -84,7 +84,7 @@ public class EntryTest extends AbstractTest {
         checked = true;
 
         assertEquals("Microsoft.Test.OData.Services.AstoriaDefaultService.ContactDetails",
-                ((Element) property).getAttribute(ODataConstants.ATTR_M_TYPE));
+                ((Element) property).getAttribute(Constants.ATTR_M_TYPE));
       }
     }
     assertTrue(entered);


[6/7] OLINGO-205 ODataJClient request/response layer implementation imported

Posted by fm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/CUDRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/CUDRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/CUDRequestFactory.java
new file mode 100644
index 0000000..c7d6bc6
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/CUDRequestFactory.java
@@ -0,0 +1,145 @@
+/*
+ * 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.api.communication.request.cud;
+
+import java.io.Serializable;
+import java.net.URI;
+import org.apache.olingo.client.api.communication.request.UpdateType;
+import org.apache.olingo.client.api.domain.ODataEntity;
+import org.apache.olingo.client.api.domain.ODataLink;
+import org.apache.olingo.client.api.domain.ODataPrimitiveValue;
+import org.apache.olingo.client.api.domain.ODataProperty;
+
+/**
+ * OData request factory class.
+ */
+public interface CUDRequestFactory extends Serializable {
+
+  /**
+   * Gets a create request object instance.
+   * <br/>
+   * Use this kind of request to create a new entity.
+   *
+   * @param targetURI entity set URI.
+   * @param entity entity to be created.
+   * @return new ODataEntityCreateRequest instance.
+   */
+  ODataEntityCreateRequest getEntityCreateRequest(URI targetURI, ODataEntity entity);
+
+  /**
+   * Gets an update request object instance.
+   *
+   * @param targetURI edit link of the object to be updated.
+   * @param type type of update to be performed.
+   * @param changes changes to be applied.
+   * @return new ODataEntityUpdateRequest instance.
+   */
+  ODataEntityUpdateRequest getEntityUpdateRequest(URI targetURI, UpdateType type, ODataEntity changes);
+
+  /**
+   * Gets an update request object instance; uses entity's edit link as endpoint.
+   *
+   * @param type type of update to be performed.
+   * @param entity changes to be applied.
+   * @return new ODataEntityUpdateRequest instance.
+   */
+  ODataEntityUpdateRequest getEntityUpdateRequest(UpdateType type, ODataEntity entity);
+
+  /**
+   * Gets a create request object instance.
+   * <br/>
+   * Use this kind of request to create a new value (e.g. http://Northwind.svc/Customer(1)/Picture/$value).
+   *
+   * @param targetURI entity set or entity or entity property URI.
+   * @param type type of update to be performed.
+   * @param value value to be created.
+   * @return new ODataValueUpdateRequest instance.
+   */
+  ODataValueUpdateRequest getValueUpdateRequest(URI targetURI, UpdateType type, ODataPrimitiveValue value);
+
+  /**
+   * Gets an update request object instance.
+   * <br/>
+   * Use this kind of request to update a primitive property value.
+   *
+   * @param targetURI entity set or entity or entity property URI.
+   * @param property value to be update.
+   * @return new ODataPropertyUpdateRequest instance.
+   */
+  ODataPropertyUpdateRequest getPropertyPrimitiveValueUpdateRequest(URI targetURI, ODataProperty property);
+
+  /**
+   * Gets an update request object instance.
+   * <br/>
+   * Use this kind of request to update a complex property value.
+   *
+   * @param targetURI entity set or entity or entity property URI.
+   * @param type type of update to be performed.
+   * @param property value to be update.
+   * @return new ODataPropertyUpdateRequest instance.
+   */
+  ODataPropertyUpdateRequest getPropertyComplexValueUpdateRequest(
+          URI targetURI, UpdateType type, ODataProperty property);
+
+  /**
+   * Gets an update request object instance.
+   * <br/>
+   * Use this kind of request to update a collection property value.
+   *
+   * @param targetURI entity set or entity or entity property URI.
+   * @param property value to be update.
+   * @return new ODataPropertyUpdateRequest instance.
+   */
+  ODataPropertyUpdateRequest getPropertyCollectionValueUpdateRequest(URI targetURI, ODataProperty property);
+
+  /**
+   * Gets an add link request object instance.
+   * <br/>
+   * Use this kind of request to create a navigation link between existing entities.
+   *
+   * @param targetURI navigation property's link collection.
+   * @param link navigation link to be added.
+   * @return new ODataLinkCreateRequest instance.
+   */
+  ODataLinkCreateRequest getLinkCreateRequest(URI targetURI, ODataLink link);
+
+  /**
+   * Gets a link update request object instance.
+   * <br/>
+   * Use this kind of request to update a navigation link between existing entities.
+   * <br/>
+   * In case of the old navigation link doesn't exist the new one will be added as well.
+   *
+   * @param targetURI navigation property's link collection.
+   * @param type type of update to be performed.
+   * @param link URL that identifies the entity to be linked.
+   * @return new ODataLinkUpdateRequest instance.
+   */
+  ODataLinkUpdateRequest getLinkUpdateRequest(URI targetURI, UpdateType type, ODataLink link);
+
+  /**
+   * Gets a delete request object instance.
+   * <br/>
+   * Use this kind of request to delete an entity and media entity as well.
+   *
+   * @param targetURI edit link of the object to be removed.
+   * @return new ODataDeleteRequest instance.
+   */
+  ODataDeleteRequest getDeleteRequest(URI targetURI);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataDeleteRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataDeleteRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataDeleteRequest.java
new file mode 100644
index 0000000..7206f50
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataDeleteRequest.java
@@ -0,0 +1,29 @@
+/*
+ * 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.api.communication.request.cud;
+
+import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.response.ODataDeleteResponse;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+
+/**
+ * This class implements an OData delete request.
+ */
+public interface ODataDeleteRequest extends ODataBasicRequest<ODataDeleteResponse, ODataPubFormat> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataEntityCreateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataEntityCreateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataEntityCreateRequest.java
new file mode 100644
index 0000000..357ed9a
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataEntityCreateRequest.java
@@ -0,0 +1,29 @@
+/*
+ * 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.api.communication.request.cud;
+
+import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+
+/**
+ * This class implements an OData create request.
+ */
+public interface ODataEntityCreateRequest extends ODataBasicRequest<ODataEntityCreateResponse, ODataPubFormat>{
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataEntityUpdateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataEntityUpdateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataEntityUpdateRequest.java
new file mode 100644
index 0000000..bff13dc
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataEntityUpdateRequest.java
@@ -0,0 +1,29 @@
+/*
+ * 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.api.communication.request.cud;
+
+import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+
+/**
+ * This class implements an OData update request.
+ */
+public interface ODataEntityUpdateRequest extends ODataBasicRequest<ODataEntityUpdateResponse, ODataPubFormat> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataLinkCreateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataLinkCreateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataLinkCreateRequest.java
new file mode 100644
index 0000000..65c070d
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataLinkCreateRequest.java
@@ -0,0 +1,29 @@
+/*
+ * 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.api.communication.request.cud;
+
+import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.response.ODataLinkOperationResponse;
+import org.apache.olingo.client.api.format.ODataFormat;
+
+/**
+ * This class implements an insert link OData request.
+ */
+public interface ODataLinkCreateRequest extends ODataBasicRequest<ODataLinkOperationResponse, ODataFormat> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataLinkUpdateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataLinkUpdateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataLinkUpdateRequest.java
new file mode 100644
index 0000000..624c693
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataLinkUpdateRequest.java
@@ -0,0 +1,29 @@
+/*
+ * 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.api.communication.request.cud;
+
+import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.response.ODataLinkOperationResponse;
+import org.apache.olingo.client.api.format.ODataFormat;
+
+/**
+ * This class implements an update link OData request.
+ */
+public interface ODataLinkUpdateRequest extends ODataBasicRequest<ODataLinkOperationResponse, ODataFormat> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataPropertyUpdateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataPropertyUpdateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataPropertyUpdateRequest.java
new file mode 100644
index 0000000..683c3e3
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataPropertyUpdateRequest.java
@@ -0,0 +1,29 @@
+/*
+ * 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.api.communication.request.cud;
+
+import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.response.ODataPropertyUpdateResponse;
+import org.apache.olingo.client.api.format.ODataFormat;
+
+/**
+ * This class implements an OData update entity property request.
+ */
+public interface ODataPropertyUpdateRequest extends ODataBasicRequest<ODataPropertyUpdateResponse, ODataFormat> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataValueUpdateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataValueUpdateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataValueUpdateRequest.java
new file mode 100644
index 0000000..7085788
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/ODataValueUpdateRequest.java
@@ -0,0 +1,29 @@
+/*
+ * 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.api.communication.request.cud;
+
+import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.response.ODataValueUpdateResponse;
+import org.apache.olingo.client.api.format.ODataValueFormat;
+
+/**
+ * This class implements an OData update entity property value request.
+ */
+public interface ODataValueUpdateRequest extends ODataBasicRequest<ODataValueUpdateResponse, ODataValueFormat> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/V3CUDRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/V3CUDRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/V3CUDRequestFactory.java
new file mode 100644
index 0000000..85e5dbf
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/V3CUDRequestFactory.java
@@ -0,0 +1,22 @@
+/*
+ * 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.api.communication.request.cud;
+
+public interface V3CUDRequestFactory extends CUDRequestFactory {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/V4CUDRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/V4CUDRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/V4CUDRequestFactory.java
new file mode 100644
index 0000000..5896c59
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/V4CUDRequestFactory.java
@@ -0,0 +1,22 @@
+/*
+ * 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.api.communication.request.cud;
+
+public interface V4CUDRequestFactory extends CUDRequestFactory {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/InvokeRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/InvokeRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/InvokeRequestFactory.java
new file mode 100644
index 0000000..f786602
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/InvokeRequestFactory.java
@@ -0,0 +1,58 @@
+/*
+ * 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.api.communication.request.invoke;
+
+import java.io.Serializable;
+import java.net.URI;
+import java.util.Map;
+import org.apache.olingo.client.api.domain.ODataInvokeResult;
+import org.apache.olingo.client.api.domain.ODataValue;
+import org.apache.olingo.client.api.edm.xml.CommonFunctionImport;
+import org.apache.olingo.client.api.edm.xml.XMLMetadata;
+
+/**
+ * OData request factory class.
+ */
+public interface InvokeRequestFactory<FI extends CommonFunctionImport> extends Serializable {
+
+  /**
+   * Gets an invoke request instance.
+   *
+   * @param <RES> OData domain object result, derived from return type defined in the function import
+   * @param uri URI that identifies the function import
+   * @param metadata Edm metadata
+   * @param functionImport function import to be invoked
+   * @return new ODataInvokeRequest instance.
+   */
+  <RES extends ODataInvokeResult> ODataInvokeRequest<RES> getInvokeRequest(
+          URI uri, XMLMetadata metadata, FI functionImport);
+
+  /**
+   * Gets an invoke request instance.
+   *
+   * @param <RES> OData domain object result, derived from return type defined in the function import
+   * @param uri URI that identifies the function import
+   * @param metadata Edm metadata
+   * @param functionImport function import to be invoked
+   * @param parameters parameters to pass to function import invocation
+   * @return new ODataInvokeRequest instance.
+   */
+  <RES extends ODataInvokeResult> ODataInvokeRequest<RES> getInvokeRequest(
+          URI uri, XMLMetadata metadata, FI functionImport, Map<String, ODataValue> parameters);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/ODataInvokeRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/ODataInvokeRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/ODataInvokeRequest.java
new file mode 100644
index 0000000..22360fb
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/ODataInvokeRequest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.api.communication.request.invoke;
+
+import java.util.Map;
+import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.response.ODataInvokeResponse;
+import org.apache.olingo.client.api.domain.ODataInvokeResult;
+import org.apache.olingo.client.api.domain.ODataValue;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+
+/**
+ * This class implements an OData invoke operation request.
+ */
+public interface ODataInvokeRequest<T extends ODataInvokeResult>
+        extends ODataBasicRequest<ODataInvokeResponse<T>, ODataPubFormat> {
+
+  /**
+   * Sets operation parameters.
+   *
+   * @param parameters operation parameters.
+   */
+  void setParameters(Map<String, ODataValue> parameters);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/ODataNoContent.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/ODataNoContent.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/ODataNoContent.java
new file mode 100644
index 0000000..e9c0379
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/ODataNoContent.java
@@ -0,0 +1,31 @@
+/*
+ * 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.api.communication.request.invoke;
+
+import java.io.Serializable;
+import org.apache.olingo.client.api.domain.ODataInvokeResult;
+
+/**
+ * Marker class for invoke with no return type.
+ */
+public class ODataNoContent implements Serializable, ODataInvokeResult {
+
+  private static final long serialVersionUID = 2780193571934253136L;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/V3InvokeRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/V3InvokeRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/V3InvokeRequestFactory.java
new file mode 100644
index 0000000..cfa8aca
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/V3InvokeRequestFactory.java
@@ -0,0 +1,24 @@
+/*
+ * 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.api.communication.request.invoke;
+
+import org.apache.olingo.client.api.edm.xml.v3.FunctionImport;
+
+public interface V3InvokeRequestFactory extends InvokeRequestFactory<FunctionImport> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/V4InvokeRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/V4InvokeRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/V4InvokeRequestFactory.java
new file mode 100644
index 0000000..3740a1e
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/V4InvokeRequestFactory.java
@@ -0,0 +1,24 @@
+/*
+ * 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.api.communication.request.invoke;
+
+import org.apache.olingo.client.api.edm.xml.v4.FunctionImport;
+
+public interface V4InvokeRequestFactory extends InvokeRequestFactory<FunctionImport> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataEntityRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataEntityRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataEntityRequest.java
new file mode 100644
index 0000000..9dd7104
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataEntityRequest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.request.retrieve;
+
+import org.apache.olingo.client.api.domain.ODataEntity;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+
+/**
+ * This class implements an OData retrieve query request returning a single entity.
+ */
+public interface ODataEntityRequest extends ODataRetrieveRequest<ODataEntity, ODataPubFormat> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataEntitySetIteratorRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataEntitySetIteratorRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataEntitySetIteratorRequest.java
new file mode 100644
index 0000000..2d7c369
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataEntitySetIteratorRequest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.request.retrieve;
+
+import org.apache.olingo.client.api.domain.ODataEntitySetIterator;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+
+/**
+ * This class implements an OData EntitySet query request.
+ */
+public interface ODataEntitySetIteratorRequest extends ODataRetrieveRequest<ODataEntitySetIterator, ODataPubFormat> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataEntitySetRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataEntitySetRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataEntitySetRequest.java
new file mode 100644
index 0000000..d76d04a
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataEntitySetRequest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.request.retrieve;
+
+import org.apache.olingo.client.api.domain.ODataEntitySet;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+
+/**
+ * This class implements an OData EntitySet query request.
+ */
+public interface ODataEntitySetRequest extends ODataRetrieveRequest<ODataEntitySet, ODataPubFormat> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataGenericRetrieveRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataGenericRetrieveRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataGenericRetrieveRequest.java
new file mode 100644
index 0000000..c4dcc78
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataGenericRetrieveRequest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.api.communication.request.retrieve;
+
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.data.ObjectWrapper;
+
+/**
+ * This class implements a generic OData retrieve query request.
+ */
+public interface ODataGenericRetrieveRequest extends ODataRawRequest {
+
+  /**
+   * Sets accepted format.
+   *
+   * @param format format.
+   */
+  void setFormat(final String format);
+
+  /**
+   * Executes the query.
+   *
+   * @return query response.
+   */
+  ODataRetrieveResponse<ObjectWrapper> execute();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataLinkCollectionRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataLinkCollectionRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataLinkCollectionRequest.java
new file mode 100644
index 0000000..080f92a
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataLinkCollectionRequest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.request.retrieve;
+
+import org.apache.olingo.client.api.domain.ODataLinkCollection;
+import org.apache.olingo.client.api.format.ODataFormat;
+
+/**
+ * This class implements an OData link query request.
+ */
+public interface ODataLinkCollectionRequest extends ODataRetrieveRequest<ODataLinkCollection, ODataFormat> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataMediaRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataMediaRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataMediaRequest.java
new file mode 100644
index 0000000..4500152
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataMediaRequest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.request.retrieve;
+
+import java.io.InputStream;
+import org.apache.olingo.client.api.format.ODataMediaFormat;
+
+/**
+ * This class implements an OData media query request.
+ */
+public interface ODataMediaRequest extends ODataRetrieveRequest<InputStream, ODataMediaFormat> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataMetadataRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataMetadataRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataMetadataRequest.java
new file mode 100644
index 0000000..1a1f6b0
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataMetadataRequest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.request.retrieve;
+
+import org.apache.olingo.client.api.edm.xml.XMLMetadata;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+
+/**
+ * This class implements a metadata query request.
+ */
+public interface ODataMetadataRequest extends ODataRetrieveRequest<XMLMetadata, ODataPubFormat> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataPropertyRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataPropertyRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataPropertyRequest.java
new file mode 100644
index 0000000..9806a2e
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataPropertyRequest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.request.retrieve;
+
+import org.apache.olingo.client.api.domain.ODataProperty;
+import org.apache.olingo.client.api.format.ODataFormat;
+
+/**
+ * This class implements an OData entity property query request.
+ */
+public interface ODataPropertyRequest extends ODataRetrieveRequest<ODataProperty, ODataFormat> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRawRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRawRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRawRequest.java
new file mode 100644
index 0000000..b586b3f
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRawRequest.java
@@ -0,0 +1,27 @@
+/*
+ * 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.api.communication.request.retrieve;
+
+import org.apache.olingo.client.api.communication.request.ODataRequest;
+
+/**
+ * This class implements a generic OData request.
+ */
+public interface ODataRawRequest extends ODataRequest {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
new file mode 100644
index 0000000..07a3141
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataRetrieveRequest.java
@@ -0,0 +1,29 @@
+/*
+ * 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.api.communication.request.retrieve;
+
+import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+
+/**
+ * This is an abstract representation of an OData retrieve query request returning one or more result item. Get instance
+ * by using ODataRetrieveRequestFactory.
+ */
+public interface ODataRetrieveRequest<V, T extends Enum<T>> extends ODataBasicRequest<ODataRetrieveResponse<V>, T> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataServiceDocumentRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataServiceDocumentRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataServiceDocumentRequest.java
new file mode 100644
index 0000000..862ed49
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataServiceDocumentRequest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.request.retrieve;
+
+import org.apache.olingo.client.api.domain.ODataServiceDocument;
+import org.apache.olingo.client.api.format.ODataFormat;
+
+/**
+ * This class implements an OData service document request.
+ */
+public interface ODataServiceDocumentRequest extends ODataRetrieveRequest<ODataServiceDocument, ODataFormat> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataValueRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataValueRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataValueRequest.java
new file mode 100644
index 0000000..d125c65
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/ODataValueRequest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.request.retrieve;
+
+import org.apache.olingo.client.api.domain.ODataValue;
+import org.apache.olingo.client.api.format.ODataValueFormat;
+
+/**
+ * This class implements an OData entity property value query request.
+ */
+public interface ODataValueRequest extends ODataRetrieveRequest<ODataValue, ODataValueFormat> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/RetrieveRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/RetrieveRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/RetrieveRequestFactory.java
new file mode 100644
index 0000000..8964ac8
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/RetrieveRequestFactory.java
@@ -0,0 +1,113 @@
+/*
+ * 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.api.communication.request.retrieve;
+
+import java.io.Serializable;
+import java.net.URI;
+
+/**
+ * OData request factory class.
+ */
+public interface RetrieveRequestFactory extends Serializable {
+
+  /**
+   * Gets a service document request instance.
+   *
+   * @param serviceRoot absolute URL (schema, host and port included) representing the location of the root of the data
+   * service.
+   * @return new ODataServiceDocumentRequest instance.
+   */
+  ODataServiceDocumentRequest getServiceDocumentRequest(String serviceRoot);
+
+  /**
+   * Gets a metadata request instance.
+   *
+   * @param serviceRoot absolute URL (schema, host and port included) representing the location of the root of the data
+   * service.
+   * @return new ODataMetadataRequest instance.
+   */
+  ODataMetadataRequest getMetadataRequest(String serviceRoot);
+
+  /**
+   * Gets a query request returning a set of one or more OData entities.
+   *
+   * @param query query to be performed.
+   * @return new ODataEntitySetRequest instance.
+   */
+  ODataEntitySetRequest getEntitySetRequest(URI query);
+
+  /**
+   * Gets a query request returning a set of one or more OData entities.
+   * <br/>
+   * Returned request gives the possibility to consume entities iterating on them without parsing and loading in memory
+   * the entire entity set.
+   *
+   * @param query query to be performed.
+   * @return new ODataEntitySetIteratorRequest instance.
+   */
+  ODataEntitySetIteratorRequest getEntitySetIteratorRequest(URI query);
+
+  /**
+   * Gets a query request returning a single OData entity.
+   *
+   * @param query query to be performed.
+   * @return new ODataEntityRequest instance.
+   */
+  ODataEntityRequest getEntityRequest(URI query);
+
+  /**
+   * Gets a query request returning a single OData entity property.
+   *
+   * @param query query to be performed.
+   * @return new ODataPropertyRequest instance.
+   */
+  ODataPropertyRequest getPropertyRequest(URI query);
+
+  /**
+   * Gets a query request returning a single OData entity property value.
+   *
+   * @param query query to be performed.
+   * @return new ODataValueRequest instance.
+   */
+  ODataValueRequest getValueRequest(URI query);
+
+  /**
+   * Gets a query request returning a media stream.
+   *
+   * @param query query to be performed.
+   * @return new ODataMediaRequest instance.
+   */
+  ODataMediaRequest getMediaRequest(URI query);
+
+  /**
+   * Implements a raw request returning a stream.
+   *
+   * @param uri query to be performed.
+   * @return new ODataRawRequest instance.
+   */
+  ODataRawRequest getRawRequest(URI uri);
+
+  /**
+   * Implements a generic retrieve request without specifying any return type.
+   *
+   * @param uri query to be performed.
+   * @return new ODataGenericRerieveRequest instance.
+   */
+  ODataGenericRetrieveRequest getGenericRetrieveRequest(URI uri);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/V3RetrieveRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/V3RetrieveRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/V3RetrieveRequestFactory.java
new file mode 100644
index 0000000..5089073
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/V3RetrieveRequestFactory.java
@@ -0,0 +1,33 @@
+/*
+ * 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.api.communication.request.retrieve;
+
+import java.net.URI;
+
+public interface V3RetrieveRequestFactory extends RetrieveRequestFactory {
+
+  /**
+   * Gets a query request returning a single OData link.
+   *
+   * @param targetURI target URI.
+   * @param linkName link name.
+   * @return new ODataLinkRequest instance.
+   */
+  ODataLinkCollectionRequest getLinkCollectionRequest(URI targetURI, String linkName);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/V4RetrieveRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/V4RetrieveRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/V4RetrieveRequestFactory.java
new file mode 100644
index 0000000..272ed86
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/retrieve/V4RetrieveRequestFactory.java
@@ -0,0 +1,22 @@
+/*
+ * 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.api.communication.request.retrieve;
+
+public interface V4RetrieveRequestFactory extends RetrieveRequestFactory {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/MediaEntityCreateStreamManager.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/MediaEntityCreateStreamManager.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/MediaEntityCreateStreamManager.java
new file mode 100644
index 0000000..21c9c89
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/MediaEntityCreateStreamManager.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.request.streamed;
+
+import org.apache.olingo.client.api.communication.request.ODataStreamManager;
+import org.apache.olingo.client.api.communication.response.ODataMediaEntityCreateResponse;
+
+/**
+ * Media entity payload object.
+ */
+public interface MediaEntityCreateStreamManager extends ODataStreamManager<ODataMediaEntityCreateResponse> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/MediaEntityUpdateStreamManager.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/MediaEntityUpdateStreamManager.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/MediaEntityUpdateStreamManager.java
new file mode 100644
index 0000000..d545e3a
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/MediaEntityUpdateStreamManager.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.request.streamed;
+
+import org.apache.olingo.client.api.communication.request.ODataStreamManager;
+import org.apache.olingo.client.api.communication.response.ODataMediaEntityUpdateResponse;
+
+/**
+ * Media entity payload object.
+ */
+public interface MediaEntityUpdateStreamManager extends ODataStreamManager<ODataMediaEntityUpdateResponse> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataMediaEntityCreateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataMediaEntityCreateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataMediaEntityCreateRequest.java
new file mode 100644
index 0000000..76a7a8c
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataMediaEntityCreateRequest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.request.streamed;
+
+import org.apache.olingo.client.api.communication.response.ODataMediaEntityCreateResponse;
+
+/**
+ * This class implements an OData Media Entity create request. Get instance by using ODataStreamedRequestFactory.
+ */
+public interface ODataMediaEntityCreateRequest
+        extends ODataStreamedEntityRequest<ODataMediaEntityCreateResponse, MediaEntityCreateStreamManager> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataMediaEntityUpdateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataMediaEntityUpdateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataMediaEntityUpdateRequest.java
new file mode 100644
index 0000000..913ce36
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataMediaEntityUpdateRequest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.request.streamed;
+
+import org.apache.olingo.client.api.communication.response.ODataMediaEntityUpdateResponse;
+
+/**
+ * This class implements an OData Media Entity create request. Get instance by using ODataStreamedRequestFactory.
+ */
+public interface ODataMediaEntityUpdateRequest
+        extends ODataStreamedEntityRequest<ODataMediaEntityUpdateResponse, MediaEntityUpdateStreamManager> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataStreamUpdateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataStreamUpdateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataStreamUpdateRequest.java
new file mode 100644
index 0000000..e403cf5
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataStreamUpdateRequest.java
@@ -0,0 +1,30 @@
+/*
+ * 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.api.communication.request.streamed;
+
+import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
+import org.apache.olingo.client.api.communication.response.ODataStreamUpdateResponse;
+
+/**
+ * This class implements an OData stream create/update request.
+ * Get instance by using ODataStreamedRequestFactory.
+ */
+public interface ODataStreamUpdateRequest
+        extends ODataStreamedRequest<ODataStreamUpdateResponse, StreamUpdateStreamManager> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataStreamedEntityRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataStreamedEntityRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataStreamedEntityRequest.java
new file mode 100644
index 0000000..f5b717c
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/ODataStreamedEntityRequest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.api.communication.request.streamed;
+
+import javax.security.auth.login.Configuration;
+import org.apache.olingo.client.api.communication.request.ODataStreamManager;
+import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.api.format.ODataFormat;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+
+/**
+ * Abstract class representing a request concerning a streamed entity.
+ *
+ * @param <V> OData response type corresponding to the request implementation.
+ * @param <T> OData request payload type corresponding to the request implementation.
+ */
+public interface ODataStreamedEntityRequest<V extends ODataResponse, T extends ODataStreamManager<V>>
+        extends ODataStreamedRequest<V, T> {
+
+  /**
+   * Returns resource representation format.
+   *
+   * @return the configured format (or default if not specified).
+   * @see Configuration#getDefaultPubFormat()
+   */
+  ODataPubFormat getFormat();
+
+  /**
+   * Override configured request format.
+   *
+   * @param format request format.
+   * @see ODataFormat
+   */
+  void setFormat(final ODataPubFormat format);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/StreamUpdateStreamManager.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/StreamUpdateStreamManager.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/StreamUpdateStreamManager.java
new file mode 100644
index 0000000..af1e259
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/StreamUpdateStreamManager.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.request.streamed;
+
+import org.apache.olingo.client.api.communication.request.ODataStreamManager;
+import org.apache.olingo.client.api.communication.response.ODataStreamUpdateResponse;
+
+/**
+ * Streamed entity payload object.
+ */
+public interface StreamUpdateStreamManager extends ODataStreamManager<ODataStreamUpdateResponse> {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/StreamedRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/StreamedRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/StreamedRequestFactory.java
new file mode 100644
index 0000000..04ac27c
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/StreamedRequestFactory.java
@@ -0,0 +1,62 @@
+/*
+ * 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.api.communication.request.streamed;
+
+import java.io.InputStream;
+import java.io.Serializable;
+import java.net.URI;
+
+/**
+ * OData request factory class.
+ */
+public interface StreamedRequestFactory extends Serializable {
+
+  /**
+   * Gets a media entity create request object instance.
+   * <br/>
+   * Use this kind of request to create a new media entity.
+   *
+   * @param targetURI entity set URI.
+   * @param media entity blob to be created.
+   * @return new ODataMediaEntityCreateRequest instance.
+   */
+  ODataMediaEntityCreateRequest getMediaEntityCreateRequest(URI targetURI, InputStream media);
+
+  /**
+   * Gets a stream update request object instance.
+   * <br/>
+   * Use this kind of request to update a named stream property.
+   *
+   * @param targetURI target URI.
+   * @param stream stream to be updated.
+   * @return new ODataStreamUpdateRequest instance.
+   */
+  ODataStreamUpdateRequest getStreamUpdateRequest(URI targetURI, InputStream stream);
+
+  /**
+   * Gets a media entity update request object instance.
+   * <br/>
+   * Use this kind of request to update a media entity.
+   *
+   * @param editURI media entity edit link URI.
+   * @param media entity blob to be updated.
+   * @return new ODataMediaEntityUpdateRequest instance.
+   */
+  ODataMediaEntityUpdateRequest getMediaEntityUpdateRequest(URI editURI, InputStream media);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/V3StreamedRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/V3StreamedRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/V3StreamedRequestFactory.java
new file mode 100644
index 0000000..fd6a99c
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/V3StreamedRequestFactory.java
@@ -0,0 +1,22 @@
+/*
+ * 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.api.communication.request.streamed;
+
+public interface V3StreamedRequestFactory extends StreamedRequestFactory {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/V4StreamedRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/V4StreamedRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/V4StreamedRequestFactory.java
new file mode 100644
index 0000000..b8f28ac
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/streamed/V4StreamedRequestFactory.java
@@ -0,0 +1,22 @@
+/*
+ * 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.api.communication.request.streamed;
+
+public interface V4StreamedRequestFactory extends StreamedRequestFactory {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataBatchResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataBatchResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataBatchResponse.java
new file mode 100644
index 0000000..658acbd
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataBatchResponse.java
@@ -0,0 +1,37 @@
+/*
+ * 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.api.communication.response;
+
+import java.util.Iterator;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem;
+
+/**
+ * This class implements a response to a batch request.
+ *
+ * @see org.apache.olingo.client.core.communication.request.batch.ODataBatchRequest
+ */
+public interface ODataBatchResponse extends ODataResponse {
+
+  /**
+   * Get all the batch response items.
+   *
+   * @return an iterator on batch response items.
+   */
+  Iterator<ODataBatchResponseItem> getBody();
+}


[7/7] git commit: OLINGO-205 ODataJClient request/response layer implementation imported

Posted by fm...@apache.org.
OLINGO-205 ODataJClient request/response layer implementation imported


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

Branch: refs/heads/olingo200
Commit: d3b05e016d446d0cbca6e664efd35801751e87f8
Parents: b5c3835
Author: fmartelli <fa...@gmail.com>
Authored: Thu Mar 13 16:23:24 2014 +0100
Committer: fmartelli <fa...@gmail.com>
Committed: Thu Mar 13 16:23:24 2014 +0100

----------------------------------------------------------------------
 lib/client-api/pom.xml                          |   4 +
 .../org/apache/olingo/client/api/Constants.java |   2 +
 .../olingo/client/api/ODataBatchConstants.java  |  56 +++
 .../apache/olingo/client/api/ODataClient.java   |  24 +-
 .../olingo/client/api/ODataConstants.java       | 219 ---------
 .../apache/olingo/client/api/ODataV3Client.java |  19 +
 .../apache/olingo/client/api/ODataV4Client.java |  19 +
 .../ODataClientErrorException.java              | 110 +++++
 .../ODataServerErrorException.java              |  38 ++
 .../api/communication/header/HeaderName.java    | 147 ++++++
 .../communication/header/ODataHeaderValues.java |  45 ++
 .../api/communication/header/ODataHeaders.java  |  59 +++
 .../request/ODataBasicRequest.java              |  54 +++
 .../request/ODataBatchableRequest.java          |  46 ++
 .../api/communication/request/ODataRequest.java | 191 ++++++++
 .../request/ODataStreamManager.java             |  57 +++
 .../request/ODataStreamedRequest.java           |  38 ++
 .../communication/request/ODataStreamer.java    |  39 ++
 .../api/communication/request/UpdateType.java   |  55 +++
 .../request/batch/BatchRequestFactory.java      |  35 ++
 .../request/batch/BatchStreamManager.java       |  42 ++
 .../request/batch/ODataBatchLineIterator.java   |  57 +++
 .../request/batch/ODataBatchRequest.java        |  57 +++
 .../request/batch/ODataBatchRequestItem.java    |  46 ++
 .../request/batch/ODataBatchResponseItem.java   |  56 +++
 .../request/batch/ODataChangeset.java           |  39 ++
 .../request/batch/ODataRetrieve.java            |  37 ++
 .../request/batch/V3BatchRequestFactory.java    |  22 +
 .../request/batch/V4BatchRequestFactory.java    |  22 +
 .../request/cud/CUDRequestFactory.java          | 145 ++++++
 .../request/cud/ODataDeleteRequest.java         |  29 ++
 .../request/cud/ODataEntityCreateRequest.java   |  29 ++
 .../request/cud/ODataEntityUpdateRequest.java   |  29 ++
 .../request/cud/ODataLinkCreateRequest.java     |  29 ++
 .../request/cud/ODataLinkUpdateRequest.java     |  29 ++
 .../request/cud/ODataPropertyUpdateRequest.java |  29 ++
 .../request/cud/ODataValueUpdateRequest.java    |  29 ++
 .../request/cud/V3CUDRequestFactory.java        |  22 +
 .../request/cud/V4CUDRequestFactory.java        |  22 +
 .../request/invoke/InvokeRequestFactory.java    |  58 +++
 .../request/invoke/ODataInvokeRequest.java      |  40 ++
 .../request/invoke/ODataNoContent.java          |  31 ++
 .../request/invoke/V3InvokeRequestFactory.java  |  24 +
 .../request/invoke/V4InvokeRequestFactory.java  |  24 +
 .../request/retrieve/ODataEntityRequest.java    |  28 ++
 .../retrieve/ODataEntitySetIteratorRequest.java |  28 ++
 .../request/retrieve/ODataEntitySetRequest.java |  28 ++
 .../retrieve/ODataGenericRetrieveRequest.java   |  42 ++
 .../retrieve/ODataLinkCollectionRequest.java    |  28 ++
 .../request/retrieve/ODataMediaRequest.java     |  28 ++
 .../request/retrieve/ODataMetadataRequest.java  |  28 ++
 .../request/retrieve/ODataPropertyRequest.java  |  28 ++
 .../request/retrieve/ODataRawRequest.java       |  27 ++
 .../request/retrieve/ODataRetrieveRequest.java  |  29 ++
 .../retrieve/ODataServiceDocumentRequest.java   |  28 ++
 .../request/retrieve/ODataValueRequest.java     |  28 ++
 .../retrieve/RetrieveRequestFactory.java        | 113 +++++
 .../retrieve/V3RetrieveRequestFactory.java      |  33 ++
 .../retrieve/V4RetrieveRequestFactory.java      |  22 +
 .../MediaEntityCreateStreamManager.java         |  28 ++
 .../MediaEntityUpdateStreamManager.java         |  28 ++
 .../streamed/ODataMediaEntityCreateRequest.java |  28 ++
 .../streamed/ODataMediaEntityUpdateRequest.java |  28 ++
 .../streamed/ODataStreamUpdateRequest.java      |  30 ++
 .../streamed/ODataStreamedEntityRequest.java    |  52 ++
 .../streamed/StreamUpdateStreamManager.java     |  28 ++
 .../streamed/StreamedRequestFactory.java        |  62 +++
 .../streamed/V3StreamedRequestFactory.java      |  22 +
 .../streamed/V4StreamedRequestFactory.java      |  22 +
 .../response/ODataBatchResponse.java            |  37 ++
 .../response/ODataDeleteResponse.java           |  27 ++
 .../response/ODataEntityCreateResponse.java     |  36 ++
 .../response/ODataEntityUpdateResponse.java     |  36 ++
 .../response/ODataInvokeResponse.java           |  36 ++
 .../response/ODataLinkOperationResponse.java    |  28 ++
 .../ODataMediaEntityCreateResponse.java         |  36 ++
 .../ODataMediaEntityUpdateResponse.java         |  36 ++
 .../response/ODataPropertyUpdateResponse.java   |  36 ++
 .../communication/response/ODataResponse.java   | 117 +++++
 .../response/ODataRetrieveResponse.java         |  34 ++
 .../response/ODataStreamUpdateResponse.java     |  36 ++
 .../response/ODataValueUpdateResponse.java      |  36 ++
 .../olingo/client/api/data/ObjectWrapper.java   | 149 ++++++
 .../client/api/domain/ODataEntitySet.java       |   1 -
 .../api/domain/ODataEntitySetIterator.java      | 307 ++++++++++++
 .../olingo/client/api/utils/URIUtils.java       |  33 +-
 lib/client-core/pom.xml                         |  19 -
 .../client/core/AbstractConfiguration.java      |   3 +-
 .../olingo/client/core/ODataV3ClientImpl.java   |  97 ++--
 .../olingo/client/core/ODataV4ClientImpl.java   |  96 ++--
 .../org/apache/olingo/client/core/Wrapper.java  |  41 ++
 .../communication/header/ODataHeadersImpl.java  | 111 +++++
 .../request/AbstractODataBasicRequest.java      | 126 +++++
 .../request/AbstractODataStreamManager.java     | 183 +++++++
 .../request/AbstractODataStreamer.java          | 101 ++++
 .../communication/request/ODataRequestImpl.java | 483 +++++++++++++++++++
 .../batch/AbstractBatchRequestFactory.java      |  36 ++
 .../batch/AbstractODataBatchRequestItem.java    | 124 +++++
 .../batch/AbstractODataBatchResponseItem.java   | 146 ++++++
 .../request/batch/ODataBatchController.java     |  89 ++++
 .../batch/ODataBatchLineIteratorImpl.java       |  93 ++++
 .../request/batch/ODataBatchRequestImpl.java    | 255 ++++++++++
 .../request/batch/ODataBatchUtilities.java      | 329 +++++++++++++
 .../request/batch/ODataChangesetImpl.java       | 128 +++++
 .../batch/ODataChangesetResponseItem.java       | 129 +++++
 .../request/batch/ODataRetrieveImpl.java        |  81 ++++
 .../batch/ODataRetrieveResponseItem.java        |  85 ++++
 .../batch/V3BatchRequestFactoryImpl.java        |  32 ++
 .../batch/V4BatchRequestFactoryImpl.java        |  32 ++
 .../request/cud/AbstractCUDRequestFactory.java  | 197 ++++++++
 .../request/cud/ODataDeleteRequestImpl.java     |  93 ++++
 .../cud/ODataEntityCreateRequestImpl.java       | 125 +++++
 .../cud/ODataEntityUpdateRequestImpl.java       | 131 +++++
 .../request/cud/ODataLinkCreateRequestImpl.java | 108 +++++
 .../request/cud/ODataLinkUpdateRequestImpl.java | 111 +++++
 .../cud/ODataPropertyUpdateRequestImpl.java     | 129 +++++
 .../cud/ODataValueUpdateRequestImpl.java        | 140 ++++++
 .../request/cud/V3CUDRequestFactoryImpl.java    |  32 ++
 .../request/cud/V4CUDRequestFactoryImpl.java    |  32 ++
 .../invoke/AbstractInvokeRequestFactory.java    |  51 ++
 .../request/invoke/ODataInvokeRequestImpl.java  | 235 +++++++++
 .../invoke/V3InvokeRequestFactoryImpl.java      |  89 ++++
 .../invoke/V4InvokeRequestFactoryImpl.java      |  43 ++
 .../retrieve/AbstractODataRetrieveRequest.java  |  98 ++++
 .../AbstractRetrieveRequestFactory.java         |  98 ++++
 .../retrieve/ODataEntityRequestImpl.java        |  95 ++++
 .../ODataEntitySetIteratorRequestImpl.java      |  86 ++++
 .../retrieve/ODataEntitySetRequestImpl.java     |  97 ++++
 .../ODataGenericRetrieveRequestImpl.java        | 105 ++++
 .../ODataLinkCollectionRequestImpl.java         |  98 ++++
 .../request/retrieve/ODataMediaRequestImpl.java | 109 +++++
 .../retrieve/ODataMetadataRequestImpl.java      | 109 +++++
 .../retrieve/ODataPropertyRequestImpl.java      |  97 ++++
 .../request/retrieve/ODataRawRequestImpl.java   |  43 ++
 .../ODataServiceDocumentRequestImpl.java        |  93 ++++
 .../request/retrieve/ODataValueRequestImpl.java | 108 +++++
 .../retrieve/V3RetrieveRequestFactoryImpl.java  |  39 ++
 .../retrieve/V4RetrieveRequestFactoryImpl.java  |  32 ++
 .../AbstractODataStreamedEntityRequest.java     |  70 +++
 .../streamed/AbstractODataStreamedRequest.java  | 153 ++++++
 .../AbstractStreamedRequestFactory.java         |  76 +++
 .../ODataMediaEntityCreateRequestImpl.java      | 134 +++++
 .../ODataMediaEntityUpdateRequestImpl.java      | 137 ++++++
 .../streamed/ODataStreamUpdateRequestImpl.java  | 132 +++++
 .../streamed/V3StreamedRequestFactoryImpl.java  |  32 ++
 .../streamed/V4StreamedRequestFactoryImpl.java  |  32 ++
 .../response/ODataResponseImpl.java             | 276 +++++++++++
 .../batch/ODataBatchResponseManager.java        | 151 ++++++
 .../client/core/data/AtomDeserializer.java      |  80 +--
 .../olingo/client/core/data/AtomSerializer.java |  64 +--
 .../client/core/data/GeospatialJSONHandler.java | 136 +++---
 .../client/core/data/JSONDOMTreeUtils.java      |  58 +--
 .../client/core/data/JSONEntryDeserializer.java |  88 ++--
 .../client/core/data/JSONEntrySerializer.java   |  22 +-
 .../client/core/data/JSONFeedDeserializer.java  |  10 +-
 .../core/data/JSONPropertyDeserializer.java     |  40 +-
 .../core/data/JSONPropertySerializer.java       |  14 +-
 .../data/JSONServiceDocumentDeserializer.java   |  12 +-
 .../core/data/ODataEntitySetIterator.java       | 309 ------------
 .../core/op/impl/AbstractODataBinder.java       |  56 +--
 .../core/op/impl/AbstractODataDeserializer.java |   6 +-
 .../core/op/impl/AbstractODataReader.java       |  12 +-
 .../core/op/impl/AbstractODataSerializer.java   |   6 +-
 .../client/core/AbstractPrimitiveTest.java      |   4 +-
 .../apache/olingo/client/core/v3/EntryTest.java |   6 +-
 165 files changed, 10881 insertions(+), 948 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/pom.xml
----------------------------------------------------------------------
diff --git a/lib/client-api/pom.xml b/lib/client-api/pom.xml
index aae0276..e506a97 100644
--- a/lib/client-api/pom.xml
+++ b/lib/client-api/pom.xml
@@ -42,6 +42,10 @@
     </dependency>
 
     <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-lang3</artifactId>
     </dependency>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/Constants.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/Constants.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/Constants.java
index fd0570b..091f000 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/Constants.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/Constants.java
@@ -131,6 +131,8 @@ public class Constants {
   public static final String ELEM_URI = "uri";
 
   // JSON stuff
+  public final static String JSON_CONTEXT = "@odata.context";
+
   public final static String JSON_METADATA = "odata.metadata";
 
   public final static String JSON_TYPE = "odata.type";

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataBatchConstants.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataBatchConstants.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataBatchConstants.java
new file mode 100644
index 0000000..65fbf8f
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataBatchConstants.java
@@ -0,0 +1,56 @@
+/*
+ * 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.api;
+
+/**
+ * Constant values related to the OData protocol.
+ */
+public class ODataBatchConstants {
+
+  /**
+   * Batch/Changeset content type.
+   */
+  public static final String MULTIPART_CONTENT_TYPE = "multipart/mixed";
+
+  /**
+   * Batch item content type.
+   */
+  public static final String ITEM_CONTENT_TYPE = "application/http";
+
+  /**
+   * Boundary key.
+   */
+  public static final String BOUNDARY = "boundary";
+
+  /**
+   * Item content type.
+   */
+  public static String ITEM_CONTENT_TYPE_LINE = "Content-Type: application/http";
+
+  /**
+   * Item transfer encoding.
+   */
+  public static String ITEM_TRANSFER_ENCODING_LINE = "Content-Transfer-Encoding: binary";
+
+  /**
+   * Content id header name.
+   */
+  public static String CHANGESET_CONTENT_ID_NAME = "Content-ID";
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClient.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClient.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClient.java
index f53c195..459ee10 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClient.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataClient.java
@@ -18,6 +18,12 @@
  */
 package org.apache.olingo.client.api;
 
+import org.apache.olingo.client.api.communication.header.ODataHeaders;
+import org.apache.olingo.client.api.communication.request.batch.BatchRequestFactory;
+import org.apache.olingo.client.api.communication.request.cud.CUDRequestFactory;
+import org.apache.olingo.client.api.communication.request.invoke.InvokeRequestFactory;
+import org.apache.olingo.client.api.communication.request.retrieve.RetrieveRequestFactory;
+import org.apache.olingo.client.api.communication.request.streamed.StreamedRequestFactory;
 import org.apache.olingo.client.api.domain.ODataGeospatialValue;
 import org.apache.olingo.client.api.domain.ODataObjectFactory;
 import org.apache.olingo.client.api.domain.ODataPrimitiveValue;
@@ -34,7 +40,8 @@ public interface ODataClient {
 
   ODataServiceVersion getServiceVersion();
 
-  //ODataHeaders getVersionHeaders();
+  ODataHeaders getVersionHeaders();
+
   Configuration getConfiguration();
 
   URIBuilder<?> getURIBuilder(String serviceRoot);
@@ -56,9 +63,14 @@ public interface ODataClient {
   ODataBinder getBinder();
 
   ODataObjectFactory getObjectFactory();
-//  RetrieveRequestFactory getRetrieveRequestFactory();
-//  CUDRequestFactory getCUDRequestFactory();
-//  StreamedRequestFactory getStreamedRequestFactory();
-//  InvokeRequestFactory<?, ?, ?, ?, ?, ?, ?, ?> getInvokeRequestFactory();
-//  BatchRequestFactory getBatchRequestFactory();
+
+  RetrieveRequestFactory getRetrieveRequestFactory();
+
+  CUDRequestFactory getCUDRequestFactory();
+
+  StreamedRequestFactory getStreamedRequestFactory();
+
+  InvokeRequestFactory<?> getInvokeRequestFactory();
+
+  BatchRequestFactory getBatchRequestFactory();
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataConstants.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataConstants.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataConstants.java
deleted file mode 100644
index 84109d4..0000000
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataConstants.java
+++ /dev/null
@@ -1,219 +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.client.api;
-
-import javax.xml.XMLConstants;
-
-/**
- * Constant values related to the OData protocol.
- */
-public class ODataConstants {
-
-  // Other stuff
-  public final static String UTF8 = "UTF-8";
-
-  public final static String NAME = "name";
-
-  public final static String PROPERTIES = "properties";
-
-  // XML namespaces and prefixes
-  public final static String NS_ATOM = "http://www.w3.org/2005/Atom";
-
-  public static final String NS_GEORSS = "http://www.georss.org/georss";
-
-  public static final String NS_GML = "http://www.opengis.net/gml";
-
-  public static final String XMLNS_DATASERVICES = XMLConstants.XMLNS_ATTRIBUTE + ":d";
-
-  public static final String PREFIX_DATASERVICES = "d:";
-
-  public static final String XMLNS_METADATA = XMLConstants.XMLNS_ATTRIBUTE + ":m";
-
-  public static final String PREFIX_METADATA = "m:";
-
-  public static final String XMLNS_GEORSS = XMLConstants.XMLNS_ATTRIBUTE + ":georss";
-
-  public static final String PREFIX_GEORSS = "georss:";
-
-  public static final String XMLNS_GML = XMLConstants.XMLNS_ATTRIBUTE + ":gml";
-
-  public static final String PREFIX_GML = "gml:";
-
-  /**
-   * Edit link rel value.
-   */
-  public static final String EDIT_LINK_REL = "edit";
-
-  /**
-   * Self link rel value.
-   */
-  public static final String SELF_LINK_REL = "self";
-
-  public static final String NEXT_LINK_REL = "next";
-
-  // XML elements and attributes
-  public static final String ELEM_PROPERTIES = PREFIX_METADATA + PROPERTIES;
-
-  public static final String ELEM_ELEMENT = "element";
-
-  public final static String ATTR_TYPE = "type";
-
-  public static final String ATTR_M_TYPE = PREFIX_METADATA + ATTR_TYPE;
-
-  public static final String ATTR_NULL = PREFIX_METADATA + "null";
-
-  public static final String ATTR_XMLBASE = "xml:base";
-
-  public static final String ATTR_REL = "rel";
-
-  public static final String ATTR_HREF = "href";
-
-  public static final String ATTR_METADATA = "metadata";
-
-  public static final String ATTR_TITLE = "title";
-
-  public static final String ATTR_TARGET = "target";
-
-  public static final String ELEM_COLLECTION = "collection";
-
-  public static final String ATTR_SRSNAME = PREFIX_GML + "srsName";
-
-  public static final String ELEM_POINT = PREFIX_GML + "Point";
-
-  public static final String ELEM_MULTIPOINT = PREFIX_GML + "MultiPoint";
-
-  public static final String ELEM_POINTMEMBERS = PREFIX_GML + "pointMembers";
-
-  public static final String ELEM_LINESTRING = PREFIX_GML + "LineString";
-
-  public static final String ELEM_MULTILINESTRING = PREFIX_GML + "MultiCurve";
-
-  public static final String ELEM_LINESTRINGMEMBERS = PREFIX_GML + "curveMembers";
-
-  public static final String ELEM_POLYGON = PREFIX_GML + "Polygon";
-
-  public static final String ELEM_POLYGON_EXTERIOR = PREFIX_GML + "exterior";
-
-  public static final String ELEM_POLYGON_INTERIOR = PREFIX_GML + "interior";
-
-  public static final String ELEM_POLYGON_LINEARRING = PREFIX_GML + "LinearRing";
-
-  public static final String ELEM_MULTIPOLYGON = PREFIX_GML + "MultiSurface";
-
-  public static final String ELEM_SURFACEMEMBERS = PREFIX_GML + "surfaceMembers";
-
-  public static final String ELEM_GEOCOLLECTION = PREFIX_GML + "MultiGeometry";
-
-  public static final String ELEM_GEOMEMBERS = PREFIX_GML + "geometryMembers";
-
-  public static final String ELEM_POS = PREFIX_GML + "pos";
-
-  public static final String ELEM_POSLIST = PREFIX_GML + "posList";
-
-  public static final String ELEM_PROPERTY = "property";
-
-  public static final String ELEM_URI = "uri";
-
-  // JSON stuff
-  public final static String JSON_CONTEXT = "@odata.context";
-
-  public final static String JSON_METADATA = "odata.metadata";
-
-  public final static String JSON_TYPE = "odata.type";
-
-  public final static String JSON_ETAG = "odata.etag";
-
-  public final static String JSON_MEDIA_ETAG = "odata.mediaETag";
-
-  public final static String JSON_ID = "odata.id";
-
-  public final static String JSON_READ_LINK = "odata.readLink";
-
-  public final static String JSON_EDIT_LINK = "odata.editLink";
-
-  public final static String JSON_MEDIAREAD_LINK = "odata.mediaReadLink";
-
-  public final static String JSON_MEDIAEDIT_LINK = "odata.mediaEditLink";
-
-  public final static String JSON_MEDIA_CONTENT_TYPE = "odata.mediaContentType";
-
-  public final static String JSON_NAVIGATION_LINK_SUFFIX = "@odata.navigationLinkUrl";
-
-  public final static String JSON_BIND_LINK_SUFFIX = "@odata.bind";
-
-  public final static String JSON_ASSOCIATION_LINK_SUFFIX = "@odata.associationLinkUrl";
-
-  public final static String JSON_MEDIAEDIT_LINK_SUFFIX = "@odata.mediaEditLink";
-
-  public final static String JSON_VALUE = "value";
-
-  public final static String JSON_URL = "url";
-
-  public final static String JSON_COORDINATES = "coordinates";
-
-  public final static String JSON_GEOMETRIES = "geometries";
-
-  public final static String JSON_CRS = "crs";
-
-  public final static String JSON_GIS_URLPREFIX = "http://www.opengis.net/def/crs/EPSG/0/";
-
-  // Atom stuff
-  public final static String ATOM_ELEM_ENTRY = "entry";
-
-  public final static String ATOM_ELEM_FEED = "feed";
-
-  public final static String ATOM_ELEM_CATEGORY = "category";
-
-  public final static String ATOM_ELEM_ID = "id";
-
-  public final static String ATOM_ELEM_LINK = "link";
-
-  public final static String ATOM_ELEM_CONTENT = "content";
-
-  public static final String ATOM_ELEM_TITLE = "title";
-
-  public static final String ATOM_ELEM_SUMMARY = "summary";
-
-  public static final String ATOM_ELEM_UPDATED = "updated";
-
-  public static final String ATOM_ELEM_AUTHOR = "author";
-
-  public static final String ATOM_ELEM_AUTHOR_NAME = "name";
-
-  public static final String ATOM_ELEM_AUTHOR_URI = "uri";
-
-  public static final String ATOM_ELEM_AUTHOR_EMAIL = "email";
-
-  public static final String ATOM_ELEM_ACTION = PREFIX_METADATA + "action";
-
-  public static final String ATOM_ELEM_INLINE = PREFIX_METADATA + "inline";
-
-  public static final String ATOM_ATTR_TITLE = "atom:title";
-
-  public static final String ATOM_ATTR_TERM = "term";
-
-  public static final String ATOM_ATTR_SCHEME = "scheme";
-
-  public static final String ATOM_ATTR_SRC = "src";
-
-  public static final String ATOM_ATTR_ETAG = PREFIX_METADATA + "etag";
-
-  public static final String ATOM_ATTR_COUNT = PREFIX_METADATA + "count";
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataV3Client.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataV3Client.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataV3Client.java
index daaf6a4..b63617d 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataV3Client.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataV3Client.java
@@ -18,6 +18,11 @@
  */
 package org.apache.olingo.client.api;
 
+import org.apache.olingo.client.api.communication.request.batch.V3BatchRequestFactory;
+import org.apache.olingo.client.api.communication.request.cud.V3CUDRequestFactory;
+import org.apache.olingo.client.api.communication.request.invoke.V3InvokeRequestFactory;
+import org.apache.olingo.client.api.communication.request.retrieve.V3RetrieveRequestFactory;
+import org.apache.olingo.client.api.communication.request.streamed.V3StreamedRequestFactory;
 import org.apache.olingo.client.api.op.ODataV3Deserializer;
 import org.apache.olingo.client.api.uri.V3URIBuilder;
 import org.apache.olingo.client.api.uri.filter.V3FilterFactory;
@@ -36,4 +41,18 @@ public interface ODataV3Client extends ODataClient {
   @Override
   ODataV3Deserializer getDeserializer();
 
+  @Override
+  V3RetrieveRequestFactory getRetrieveRequestFactory();
+
+  @Override
+  V3CUDRequestFactory getCUDRequestFactory();
+
+  @Override
+  V3StreamedRequestFactory getStreamedRequestFactory();
+
+  @Override
+  V3InvokeRequestFactory getInvokeRequestFactory();
+
+  @Override
+  V3BatchRequestFactory getBatchRequestFactory();
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataV4Client.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataV4Client.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataV4Client.java
index b427cb3..fac0f00 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataV4Client.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/ODataV4Client.java
@@ -18,6 +18,11 @@
  */
 package org.apache.olingo.client.api;
 
+import org.apache.olingo.client.api.communication.request.batch.V4BatchRequestFactory;
+import org.apache.olingo.client.api.communication.request.cud.V4CUDRequestFactory;
+import org.apache.olingo.client.api.communication.request.invoke.V4InvokeRequestFactory;
+import org.apache.olingo.client.api.communication.request.retrieve.V4RetrieveRequestFactory;
+import org.apache.olingo.client.api.communication.request.streamed.V4StreamedRequestFactory;
 import org.apache.olingo.client.api.op.ODataV4Deserializer;
 import org.apache.olingo.client.api.uri.V4URIBuilder;
 import org.apache.olingo.client.api.uri.filter.V4FilterFactory;
@@ -36,4 +41,18 @@ public interface ODataV4Client extends ODataClient {
   @Override
   ODataV4Deserializer getDeserializer();
 
+  @Override
+  V4RetrieveRequestFactory getRetrieveRequestFactory();
+
+  @Override
+  V4CUDRequestFactory getCUDRequestFactory();
+
+  @Override
+  V4StreamedRequestFactory getStreamedRequestFactory();
+
+  @Override
+  V4InvokeRequestFactory getInvokeRequestFactory();
+
+  @Override
+  V4BatchRequestFactory getBatchRequestFactory();
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataClientErrorException.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataClientErrorException.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataClientErrorException.java
new file mode 100644
index 0000000..5574e97
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataClientErrorException.java
@@ -0,0 +1,110 @@
+/*
+ * 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.api.communication;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.StatusLine;
+import org.apache.olingo.client.api.data.Error;
+
+/**
+ * Represents a client error in OData.
+ *
+ * @see ODataError
+ */
+public class ODataClientErrorException extends RuntimeException {
+
+  private static final long serialVersionUID = -2551523202755268162L;
+
+  private final StatusLine statusLine;
+
+  private final Error error;
+
+  /**
+   * Constructor.
+   *
+   * @param statusLine request status info.
+   */
+  public ODataClientErrorException(final StatusLine statusLine) {
+    super(statusLine.toString());
+
+    this.statusLine = statusLine;
+    this.error = null;
+  }
+
+  /**
+   * Constructor.
+   *
+   * @param statusLine request status info.
+   * @param error OData error to be wrapped.
+   */
+  public ODataClientErrorException(final StatusLine statusLine, final Error error) {
+    super((StringUtils.isBlank(error.getCode()) ? StringUtils.EMPTY : "(" + error.getCode() + ") ")
+            + error.getMessageValue() + " [" + statusLine.toString() + "]");
+
+    this.statusLine = statusLine;
+    this.error = error;
+
+    if (this.error.getInnerErrorType() != null && this.error.getInnerErrorMessage() != null) {
+      final RuntimeException cause =
+              new RuntimeException(this.error.getInnerErrorType() + ": " + this.error.getInnerErrorMessage());
+
+      if (this.error.getInnerErrorStacktrace() != null) {
+        List<String> stLines;
+        try {
+          stLines = IOUtils.readLines(new StringReader(this.error.getInnerErrorStacktrace()));
+        } catch (IOException e) {
+          stLines = Collections.<String>emptyList();
+        }
+        StackTraceElement[] stElements = new StackTraceElement[stLines.size()];
+        for (int i = 0; i < stLines.size(); i++) {
+          final String stLine = stLines.get(i).substring(stLines.get(i).indexOf("at ") + 3);
+          final int lastDotPos = stLine.lastIndexOf('.');
+          stElements[i] = new StackTraceElement(
+                  stLine.substring(0, lastDotPos), stLine.substring(lastDotPos + 1), null, 0);
+        }
+        cause.setStackTrace(stElements);
+      }
+
+      initCause(cause);
+    }
+  }
+
+  /**
+   * Gets request status info.
+   *
+   * @return request status info.
+   */
+  public StatusLine getStatusLine() {
+    return statusLine;
+  }
+
+  /**
+   * Gets OData error.
+   *
+   * @return OData error.
+   */
+  public Error getODataError() {
+    return error;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataServerErrorException.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataServerErrorException.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataServerErrorException.java
new file mode 100644
index 0000000..5003b3d
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/ODataServerErrorException.java
@@ -0,0 +1,38 @@
+/*
+ * 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.api.communication;
+
+import org.apache.http.StatusLine;
+
+/**
+ * Represents a server error in OData.
+ */
+public class ODataServerErrorException extends RuntimeException {
+
+  private static final long serialVersionUID = -6423014532618680135L;
+
+  /**
+   * Constructor.
+   *
+   * @param statusLine request status info.
+   */
+  public ODataServerErrorException(final StatusLine statusLine) {
+    super(statusLine.toString());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/HeaderName.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/HeaderName.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/HeaderName.java
new file mode 100644
index 0000000..b68cf3d
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/HeaderName.java
@@ -0,0 +1,147 @@
+/*
+ * 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.api.communication.header;
+
+/**
+ * Major OData request/response header names.
+ */
+public enum HeaderName {
+
+  /**
+   * The OData protocol uses the Accept request-header field, as specified in [RFC2616].
+   */
+  accept("Accept"),
+  /**
+   * The Content-Type header is used as specified in [RFC2616].
+   * <br/>
+   * OData request/response supports the following types:
+   * <ul>
+   * <li>application/atom+xml</li>
+   * <li>application/atom+xml;type=entry</li>
+   * <li>application/atom+xml;type=feed</li>
+   * <li>application/json; odata=verbose</li>
+   * <li>application/json</li>
+   * <li>application/xml</li>
+   * <li>text/plain</li>
+   * <li>text/xml</li>
+   * <li>octet/stream</li>
+   * <li>multipart/mixed</li>
+   * </ul>
+   */
+  contentType("Content-Type"),
+  /**
+   * This header is a custom HTTP header defined for protocol versioning purposes. This header MAY be present on any
+   * request or response message.
+   */
+  dataServiceVersion("DataServiceVersion"),
+  /**
+   * An ETag (entity tag) is an HTTP response header returned by an HTTP/1.1 compliant web server used to determine
+   * change in content of a resource at a given URL. The value of the header is an opaque string representing the state
+   * of the resource at the time the response was generated.
+   */
+  etag("ETag"),
+  /**
+   * The If-Match request-header field is used with a method to make it conditional. As specified in [RFC2616], "the
+   * purpose of this feature is to allow efficient updates of cached information with a minimum amount of transaction
+   * overhead. It is also used, on updating requests, to prevent inadvertent modification of the wrong version of a
+   * resource".
+   */
+  ifMatch("If-Match"),
+  /**
+   * The If-None-Match request header is used with a method to make it conditional. As specified in [RFC2616], "The
+   * purpose of this feature is to allow efficient updates of cached information with a minimum amount of transaction
+   * overhead. It is also used to prevent a method (for example, PUT) from inadvertently modifying an existing resource
+   * when the client believes that the resource does not exist."
+   */
+  ifNoneMatch("If-None-Match"),
+  /**
+   * This header is a custom HTTP request only header defined for protocol versioning purposes. This header MAY be
+   * present on any request message from client to server.
+   */
+  maxDataServiceVersion("MaxDataServiceVersion"),
+  /**
+   * This header is a custom HTTP request only header defined for protocol versioning purposes. This header MAY be
+   * present on any request message from client to server.
+   */
+  minDataServiceVersion("MinDataServiceVersion"),
+  /**
+   * A Prefer header is included in a request to state the client’s preferred, but not required, server behavior (that
+   * is, a hint to the server). The Prefer header MAY be included on any request type (within a standalone or batch
+   * request), and a server MAY honor the header for HTTP POST, PUT, PATCH, and MERGE requests. A Prefer header with a
+   * value of “return-content” MUST NOT be specified on a DELETE request, a batch request as a whole, or a PUT request
+   * to update a named stream.
+   */
+  prefer("Prefer"),
+  /**
+   * When a Prefer header value is successfully honored by the server, it MAY include a Preference-Applied response
+   * header that states which preference values were honored by the server.
+   */
+  preferenceApplied("Preference-Applied"),
+  /**
+   * The DataServiceId response header is returned by the server when the response payload for an HTTP PUT, POST, PATCH,
+   * or MERGE request is empty. The value of the header is the identifier of the entity that was acted on by the PUT,
+   * POST, PATCH, or MERGE request. The identifier, in this case, is the same identifier that would have been returned
+   * in the response payload (for example, as the value of the atom:id element for Atom responses)
+   */
+  dataServiceId("DataServiceId"),
+  /**
+   * Location header is used to specify the URL of an entity modified through a Data Modification request, or the
+   * request URL to check on the status of an asynchronous operation as described in
+   * <code>202 Accepted</code>.
+   */
+  location("Location"),
+  /**
+   * A service must include a
+   * <code>Retry-After</code> header in a
+   * <code>202 Accepted</code>.
+   */
+  retryAfter("Retry-After"),
+  dataServiceUrlConventions("DataServiceUrlConventions"),
+  slug("Slug"),
+  /**
+   * This header is a custom HTTP request header.
+   * <br/>
+   * It is possible to instruct network intermediaries (proxies, firewalls, and so on) inspecting traffic at the
+   * application protocol layer (for example, HTTP) to block requests that contain certain HTTP verbs. In practice, GET
+   * and POST verbs are rarely blocked (traditional web pages rely heavily on these HTTP methods), while, for a variety
+   * of reasons (such as security vulnerabilities in prior protocols), other HTTP methods (PUT, DELETE, and so on) are
+   * at times blocked by intermediaries. Additionally, some existing HTTP libraries do not allow creation of requests
+   * using verbs other than GET or POST. Therefore, an alternative way of specifying request types which use verbs other
+   * than GET and POST is needed to ensure that this document works well in a wide range of environments.
+   * <br/>
+   * To address this need, the X-HTTP-Method header can be added to a POST request that signals that the server MUST
+   * process the request not as a POST, but as if the HTTP verb specified as the value of the header was used as the
+   * method on the HTTP request's request line, as specified in [RFC2616] section 5.1. This technique is often referred
+   * to as "verb tunneling".
+   * <br/>
+   * This header is only valid when on POST requests.
+   */
+  xHttpMethod("X-HTTP-METHOD");
+
+  private final String headerName;
+
+  private HeaderName(final String headerName) {
+    this.headerName = headerName;
+  }
+
+  @Override
+  public String toString() {
+    return headerName;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataHeaderValues.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataHeaderValues.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataHeaderValues.java
new file mode 100644
index 0000000..37c4698
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataHeaderValues.java
@@ -0,0 +1,45 @@
+/*
+ * 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.api.communication.header;
+
+/**
+ * Constant header values class.
+ */
+public class ODataHeaderValues {
+
+  /**
+   * <code>Prefer</code> header, return content.
+   *
+   * @see ODataHeaders.HeaderName#prefer
+   */
+  public static final String preferReturnContent = "return-content";
+
+  /**
+   * <code>Prefer</code> header, return no content.
+   *
+   * @see ODataHeaders.HeaderName#prefer
+   */
+  public static final String preferReturnNoContent = "return-no-content";
+
+  /**
+   * @see ODataHeaders.HeaderName#dataServiceUrlConventions
+   */
+  public static final String keyAsSegment = "KeyAsSegment";
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataHeaders.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataHeaders.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataHeaders.java
new file mode 100644
index 0000000..51de80d
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/header/ODataHeaders.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.api.communication.header;
+
+import java.util.Collection;
+
+/**
+ * ODataHeaders wraps OData request/response headers.
+ *
+ * @see org.apache.olingo.client.core.communication.request.ODataRequest
+ * @see org.apache.olingo.client.core.communication.response.ODataResponse
+ */
+public interface ODataHeaders {
+
+  /**
+   * Gets the value of the header identified by the given name.
+   * <br/>
+   * Please note that header name is case-insensitive.
+   *
+   * @param name name of the header to be retrieved.
+   * @return header value.
+   */
+  String getHeader(final HeaderName name);
+
+  /**
+   * Gets the value of the header identified by the given name.
+   * <br/>
+   * Please note that header name is case-insensitive.
+   *
+   * @param name name of the header to be retrieved.
+   * @return header value.
+   */
+  String getHeader(final String name);
+
+  /**
+   * Gets header names.
+   * <br/>
+   * Please note that header name is case-insensitive.
+   *
+   * @return header names.
+   */
+  Collection<String> getHeaderNames();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
new file mode 100644
index 0000000..f64b233
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBasicRequest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.api.communication.request;
+
+import java.util.concurrent.Future;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+
+/**
+ * Basic OData request.
+ *
+ * @param <V> OData response type corresponding to the request implementation.
+ * @param <T> Accepted content-type formats by the request in object.
+ */
+public interface ODataBasicRequest<V extends ODataResponse, T extends Enum<T>> extends ODataRequest {
+
+  /**
+   * Request execute.
+   *
+   * @return return an OData response.
+   */
+  V execute();
+
+  /**
+   * Async request execute.
+   *
+   * @return <code>Future&lt;ODataResponse&gt;</code> about the executed request.
+   */
+  Future<V> asyncExecute();
+
+  /**
+   * Override configured request format.
+   *
+   * @param format request format.
+   * @see com.msopentech.odatajclient.engine.format.ODataFormat
+   * @see com.msopentech.odatajclient.engine.format.ODataPubFormat
+   */
+  void setFormat(T format);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBatchableRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBatchableRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBatchableRequest.java
new file mode 100644
index 0000000..0d62837
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataBatchableRequest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.api.communication.request;
+
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
+
+/**
+ * Object request that can be sent embedded into a batch request.
+ */
+public interface ODataBatchableRequest extends ODataRequest {
+
+  /**
+   * Writes (and consume) the request onto the given batch stream.
+   * <p>
+   * Please note that this method will consume the request (execution won't be possible anymore).
+   *
+   * @param req destination batch request.
+   */
+  void batch(final ODataBatchRequest req);
+
+  /**
+   * Writes (and consume) the request onto the given batch stream.
+   * <p>
+   * Please note that this method will consume the request (execution won't be possible anymore).
+   *
+   * @param req destination batch request.
+   * @param contentId ContentId header value to be added to the serialization. Use this in case of changeset items.
+   */
+  void batch(final ODataBatchRequest req, final String contentId);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataRequest.java
new file mode 100644
index 0000000..8ea098c
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataRequest.java
@@ -0,0 +1,191 @@
+/*
+ * 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.api.communication.request;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Collection;
+import org.apache.olingo.client.api.http.HttpMethod;
+
+/**
+ * Abstract representation of an OData request. Get instance by using factories.
+ *
+ * @see CUDRequestFactory
+ * @see RetrieveRequestFactory
+ * @see BatchRequestFactory
+ * @see InvokeRequestFactory
+ * @see StreamedRequestFactory
+ */
+public interface ODataRequest {
+
+  /**
+   * Returns OData request target URI.
+   *
+   * @return OData request target URI.
+   */
+  URI getURI();
+
+  /**
+   * Returns HTTP request method.
+   *
+   * @return HTTP request method.
+   */
+  HttpMethod getMethod();
+
+  /**
+   * Gets all OData request header names.
+   *
+   * @return all request header names.
+   */
+  Collection<String> getHeaderNames();
+
+  /**
+   * Gets the value of the OData request header identified by the given name.
+   *
+   * @param name name of the OData request header to be retrieved.
+   * @return header value.
+   */
+  String getHeader(final String name);
+
+  /**
+   * Adds <tt>Accept</tt> OData request header.
+   *
+   * @param value header value.
+   * @return current object
+   * @see org.apache.olingo.client.core.communication.header.ODataHeaders.HeaderName#accept
+   */
+  ODataRequest setAccept(final String value);
+
+  /**
+   * Gets <tt>Accept</tt> OData request header.
+   *
+   * @return header value.
+   * @see org.apache.olingo.client.core.communication.header.ODataHeaders.HeaderName#accept
+   */
+  String getAccept();
+
+  /**
+   * Adds <tt>If-Match</tt> OData request header.
+   *
+   * @param value header value.
+   * @return current object
+   * @see org.apache.olingo.client.core.communication.header.ODataHeaders.HeaderName#ifMatch
+   */
+  ODataRequest setIfMatch(final String value);
+
+  /**
+   * Gets <tt>If-Match</tt> OData request header.
+   *
+   * @return header value.
+   * @see org.apache.olingo.client.core.communication.header.ODataHeaders.HeaderName#ifMatch
+   */
+  String getIfMatch();
+
+  /**
+   * Adds <tt>If-None-Match</tt> OData request header.
+   *
+   * @param value header value.
+   * @return current object
+   * @see org.apache.olingo.client.core.communication.header.ODataHeaders.HeaderName#ifNoneMatch
+   */
+  ODataRequest setIfNoneMatch(final String value);
+
+  /**
+   * Gets <tt>If-None-Match</tt> OData request header.
+   *
+   * @return header value.
+   * @see org.apache.olingo.client.core.communication.header.ODataHeaders.HeaderName#ifNoneMatch
+   */
+  String getIfNoneMatch();
+
+  /**
+   * Adds <tt>Prefer</tt> OData request header.
+   *
+   * @param value header value.
+   * @return current object
+   * @see org.apache.olingo.client.core.communication.header.ODataHeaders.HeaderName#prefer
+   */
+  ODataRequest setPrefer(final String value);
+
+  /**
+   * Gets <tt>Prefer</tt> OData request header.
+   *
+   * @return header value.
+   * @see org.apache.olingo.client.core.communication.header.ODataHeaders.HeaderName#prefer
+   */
+  String getPrefer();
+
+  /**
+   * Adds <tt>contentType</tt> OData request header.
+   *
+   * @param value header value.
+   * @return current object
+   * @see org.apache.olingo.client.core.communication.header.ODataHeaders.HeaderName#contentType
+   */
+  ODataRequest setContentType(final String value);
+
+  /**
+   * Gets <tt>contentType</tt> OData request header.
+   *
+   * @return header value.
+   * @see org.apache.olingo.client.core.communication.header.ODataHeaders.HeaderName#contentType
+   */
+  String getContentType();
+
+  /**
+   * Adds <tt>Slug</tt> OData request header.
+   *
+   * @param value header value.
+   * @return current object
+   * @see org.apache.olingo.client.core.communication.header.ODataHeaders.HeaderName#slug
+   */
+  ODataRequest setSlug(final String value);
+
+  /**
+   * Adds <tt>X-HTTP-METHOD</tt> OData request header.
+   *
+   * @param value header value.
+   * @return current object
+   * @see org.apache.olingo.client.core.communication.header.ODataHeaders.HeaderName#xHttpMethod
+   */
+  ODataRequest setXHTTPMethod(final String value);
+
+  /**
+   * Adds a custom OData request header.
+   *
+   * @param name header name.
+   * @param value header value.
+   * @return current object
+   */
+  ODataRequest addCustomHeader(final String name, final String value);
+
+  /**
+   * Gets byte array representation of the full request header.
+   *
+   * @return full request header.
+   */
+  byte[] toByteArray();
+
+  /**
+   * Request raw execute.
+   *
+   * @return raw input stream response.
+   */
+  InputStream rawExecute();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataStreamManager.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataStreamManager.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataStreamManager.java
new file mode 100644
index 0000000..a371f1d
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataStreamManager.java
@@ -0,0 +1,57 @@
+/*
+ * 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.api.communication.request;
+
+import java.io.InputStream;
+import java.util.concurrent.Future;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+
+/**
+ * OData request payload management abstract class.
+ *
+ * @param <T> OData response type corresponding to the request implementation.
+ */
+public interface ODataStreamManager<T extends ODataResponse> extends ODataStreamer {
+
+  /**
+   * Gets payload stream.
+   *
+   * @return payload stream.
+   */
+  InputStream getBody();
+
+  /**
+   * Closes piped output stream.
+   */
+  void finalizeBody();
+
+  /**
+   * Closes the payload input stream and gets the OData response back.
+   *
+   * @return OData response.
+   */
+  T getResponse();
+
+  /**
+   * Closes the payload input stream and ask for an asynchronous response.
+   *
+   * @return <code>Future&lt;ODataResponse&gt;</code> about the executed request.
+   */
+  Future<T> getAsyncResponse();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataStreamedRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataStreamedRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataStreamedRequest.java
new file mode 100644
index 0000000..5a3a193
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataStreamedRequest.java
@@ -0,0 +1,38 @@
+/*
+ * 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.api.communication.request;
+
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+
+/**
+ * Streamed OData request interface.
+ *
+ * @param <V> OData response type corresponding to the request implementation.
+ * @param <T> OData request payload type corresponding to the request implementation.
+ */
+public interface ODataStreamedRequest<V extends ODataResponse, T extends ODataStreamManager<V>>
+        extends ODataRequest {
+
+    /**
+     * Streamed request execute.
+     *
+     * @return OData request payload manager object.
+     */
+    T execute();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataStreamer.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataStreamer.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataStreamer.java
new file mode 100644
index 0000000..8ec773f
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/ODataStreamer.java
@@ -0,0 +1,39 @@
+/*
+ * 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.api.communication.request;
+
+import java.io.PipedOutputStream;
+
+/**
+ * Streamer utility object.
+ */
+public interface ODataStreamer {
+
+  /**
+   * CR/LF.
+   */
+  public static final byte[] CRLF = {13, 10};
+
+  /**
+   * Gets the piped stream to be used to stream the payload.
+   *
+   * @return piped stream.
+   */
+  PipedOutputStream getBodyStreamWriter();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/UpdateType.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/UpdateType.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/UpdateType.java
new file mode 100644
index 0000000..0e6a831
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/UpdateType.java
@@ -0,0 +1,55 @@
+/*
+ * 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.api.communication.request;
+
+import org.apache.olingo.client.api.http.HttpMethod;
+
+/**
+ * Update type.
+ */
+public enum UpdateType {
+
+  /**
+   * Replace all and remove missing attributes.
+   */
+  REPLACE(HttpMethod.PUT),
+  /**
+   * Differential update with whole entity as input (non-standard). Differences will be retrieved by the server itself.
+   */
+  MERGE(HttpMethod.MERGE),
+  /**
+   * Differential update with only specified input property values to be replaced.
+   */
+  PATCH(HttpMethod.PATCH);
+
+  private final HttpMethod method;
+
+  private UpdateType(final HttpMethod method) {
+    this.method = method;
+  }
+
+  /**
+   * Gets HTTP request method.
+   *
+   * @return HTTP request method.
+   */
+  public HttpMethod getMethod() {
+    return method;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/BatchRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/BatchRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/BatchRequestFactory.java
new file mode 100644
index 0000000..065f3c8
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/BatchRequestFactory.java
@@ -0,0 +1,35 @@
+/*
+ * 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.api.communication.request.batch;
+
+import java.io.Serializable;
+
+/**
+ * OData batch request factory class.
+ */
+public interface BatchRequestFactory extends Serializable {
+
+  /**
+   * Gets a batch request object instance.
+   *
+   * @param serviceRoot service root.
+   * @return new ODataBatchRequest instance.
+   */
+  ODataBatchRequest getBatchRequest(String serviceRoot);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/BatchStreamManager.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/BatchStreamManager.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/BatchStreamManager.java
new file mode 100644
index 0000000..e448b57
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/BatchStreamManager.java
@@ -0,0 +1,42 @@
+/*
+ * 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.api.communication.request.batch;
+
+import org.apache.olingo.client.api.communication.request.ODataStreamManager;
+import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
+
+/**
+ * Batch request payload management.
+ */
+public interface BatchStreamManager extends ODataStreamManager<ODataBatchResponse> {
+
+  /**
+   * Gets a changeset batch item instance. A changeset can be submitted embedded into a batch request only.
+   *
+   * @return ODataChangeset instance.
+   */
+  ODataChangeset addChangeset();
+
+  /**
+   * Gets a retrieve batch item instance. A retrieve item can be submitted embedded into a batch request only.
+   *
+   * @return ODataRetrieve instance.
+   */
+  ODataRetrieve addRetrieve();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchLineIterator.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchLineIterator.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchLineIterator.java
new file mode 100644
index 0000000..3ca6b15
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchLineIterator.java
@@ -0,0 +1,57 @@
+/*
+ * 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.api.communication.request.batch;
+
+import java.util.Iterator;
+
+/**
+ * Batch line iterator class.
+ */
+public interface ODataBatchLineIterator extends Iterator<String> {
+
+  /**
+   * Checks if batch has next line.
+   *
+   * @return 'TRUE' if has next line; 'FALSE' otherwise.
+   */
+  @Override
+  boolean hasNext();
+
+  /**
+   * Gets next line.
+   *
+   * @return next line.
+   */
+  @Override
+  String next();
+
+  /**
+   * Gets next line.
+   *
+   * @return next line.
+   */
+  String nextLine();
+
+  /**
+   * Gets last cached line (the current one).
+   *
+   * @return last cached line; null if <code>next()</code> method never called
+   */
+  String getCurrent();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchRequest.java
new file mode 100644
index 0000000..5190b48
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchRequest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.api.communication.request.batch;
+
+import java.io.IOException;
+import java.io.PipedOutputStream;
+import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
+import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
+
+/**
+ * This class implements a batch request.
+ */
+public interface ODataBatchRequest extends ODataStreamedRequest<ODataBatchResponse, BatchStreamManager> {
+
+  /**
+   * Gets piped stream to be used to stream batch items.
+   *
+   * @return piped stream for the payload.
+   */
+  PipedOutputStream getOutputStream();
+
+  /**
+   * Appends the given byte array to the payload.
+   *
+   * @param toBeStreamed byte array to be appended.
+   * @return the current batch request.
+   * @throws IOException in case of write errors.
+   */
+  ODataBatchRequest rawAppend(final byte[] toBeStreamed) throws IOException;
+
+  /**
+   * Appends the given byte array to the payload.
+   *
+   * @param toBeStreamed byte array to be appended.
+   * @param off byte array offset.
+   * @param len number of byte to be streamed.
+   * @return the current batch request.
+   * @throws IOException in case of write errors.
+   */
+  ODataBatchRequest rawAppend(final byte[] toBeStreamed, int off, int len) throws IOException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchRequestItem.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchRequestItem.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchRequestItem.java
new file mode 100644
index 0000000..49cdbfd
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchRequestItem.java
@@ -0,0 +1,46 @@
+/*
+ * 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.api.communication.request.batch;
+
+import org.apache.olingo.client.api.communication.request.ODataStreamer;
+
+/**
+ * Abstract representation of a batch request item.
+ */
+public interface ODataBatchRequestItem extends ODataStreamer {
+
+  /**
+   * Checks if the current item is still opened.
+   *
+   * @return 'TRUE' if opened; 'FALSE' otherwise.
+   */
+  boolean isOpen();
+
+  /**
+   * Closes the item.
+   */
+  void close();
+
+  /**
+   * Checks if the streaming of the current item is started yet.
+   *
+   * @return 'TRUE' if started; 'FALSE' otherwise.
+   */
+  boolean hasStreamedSomething();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchResponseItem.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchResponseItem.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchResponseItem.java
new file mode 100644
index 0000000..982bd8e
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataBatchResponseItem.java
@@ -0,0 +1,56 @@
+/*
+ * 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.api.communication.request.batch;
+
+import java.util.Iterator;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+
+/**
+ * Abstract representation of a response item about a batch request.
+ */
+public interface ODataBatchResponseItem extends Iterator<ODataResponse> {
+
+  /**
+   * Adds the given OData response template to the current OData batch response item.
+   *
+   * @param contentId changeset contentId in case of changeset; '__RETRIEVE__' in case of retrieve item.
+   * @param res OData response template to be added.
+   */
+  void addResponse(final String contentId, final ODataResponse res);
+
+  /**
+   * Initializes ODataResponse template from batch response item part.
+   *
+   * @param batchLineIterator batch response line iterator.
+   * @param boundary batch response boundary.
+   */
+  void initFromBatch(final ODataBatchLineIterator batchLineIterator, final String boundary);
+
+  /**
+   * Checks if the current batch response item is a changeset.
+   *
+   * @return 'TRUE' if the item is a changeset; 'FALSE' otherwise.
+   */
+  boolean isChangeset();
+
+  /**
+   * Closes the current batch responses item including all wrapped OData responses.
+   */
+  void close();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataChangeset.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataChangeset.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataChangeset.java
new file mode 100644
index 0000000..ea90815
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataChangeset.java
@@ -0,0 +1,39 @@
+/*
+ * 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.api.communication.request.batch;
+
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+
+/**
+ * Changeset wrapper for the corresponding batch item.
+ */
+public interface ODataChangeset extends ODataBatchRequestItem {
+
+  int getLastContentId();
+
+  /**
+   * Serialize and send the given request.
+   * <p>
+   * An IllegalArgumentException is thrown in case of GET request.
+   *
+   * @param request request to be serialized.
+   * @return current item instance.
+   */
+  ODataChangeset addRequest(final ODataBatchableRequest request);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataRetrieve.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataRetrieve.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataRetrieve.java
new file mode 100644
index 0000000..948cdc3
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/ODataRetrieve.java
@@ -0,0 +1,37 @@
+/*
+ * 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.api.communication.request.batch;
+
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+
+/**
+ * Retrieve request wrapper for the corresponding batch item.
+ */
+public interface ODataRetrieve extends ODataBatchRequestItem {
+
+  /**
+   * Serialize and send the given request.
+   * <p>
+   * An IllegalArgumentException is thrown in case of no GET request.
+   *
+   * @param request request to be serialized.
+   * @return current item instance.
+   */
+  ODataRetrieve setRequest(final ODataBatchableRequest request);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/V3BatchRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/V3BatchRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/V3BatchRequestFactory.java
new file mode 100644
index 0000000..a55e4fa
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/V3BatchRequestFactory.java
@@ -0,0 +1,22 @@
+/*
+ * 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.api.communication.request.batch;
+
+public interface V3BatchRequestFactory extends BatchRequestFactory {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/V4BatchRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/V4BatchRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/V4BatchRequestFactory.java
new file mode 100644
index 0000000..8ec13cf
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/batch/V4BatchRequestFactory.java
@@ -0,0 +1,22 @@
+/*
+ * 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.api.communication.request.batch;
+
+public interface V4BatchRequestFactory extends BatchRequestFactory {
+}


[2/7] OLINGO-205 ODataJClient request/response layer implementation imported

Posted by fm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/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
new file mode 100644
index 0000000..d7e51d8
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataPropertyRequestImpl.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.client.core.communication.request.retrieve;
+
+import java.io.IOException;
+import java.net.URI;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataPropertyRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.domain.ODataProperty;
+import org.apache.olingo.client.api.format.ODataFormat;
+import org.apache.olingo.client.api.http.HttpClientException;
+
+/**
+ * This class implements an OData entity property query request.
+ */
+public class ODataPropertyRequestImpl extends AbstractODataRetrieveRequest<ODataProperty, ODataFormat>
+        implements ODataPropertyRequest {
+
+  /**
+   * Private constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param query query to be executed.
+   */
+  ODataPropertyRequestImpl(final ODataClient odataClient, final URI query) {
+    super(odataClient, ODataFormat.class, query);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataRetrieveResponse<ODataProperty> execute() {
+    final HttpResponse res = doExecute();
+    return new ODataPropertyResponseImpl(httpClient, res);
+  }
+
+  protected class ODataPropertyResponseImpl extends ODataRetrieveResponseImpl {
+
+    private ODataProperty property = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataPropertyResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataPropertyResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public ODataProperty getBody() {
+      if (property == null) {
+        try {
+          property = odataClient.getReader().readProperty(
+                  res.getEntity().getContent(), ODataFormat.fromString(getContentType()));
+        } catch (IOException e) {
+          throw new HttpClientException(e);
+        } finally {
+          this.close();
+        }
+      }
+      return property;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/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
new file mode 100644
index 0000000..632a96e
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataRawRequestImpl.java
@@ -0,0 +1,43 @@
+/*
+ * 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.communication.request.retrieve;
+
+import java.net.URI;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.communication.request.ODataRequestImpl;
+
+/**
+ * This class implements a generic OData request.
+ */
+public class ODataRawRequestImpl extends ODataRequestImpl<ODataPubFormat>
+        implements ODataRawRequest {
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param uri request URI.
+   */
+  ODataRawRequestImpl(final ODataClient odataClient, final URI uri) {
+    super(odataClient, ODataPubFormat.class, HttpMethod.GET, uri);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/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
new file mode 100644
index 0000000..67e240c
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataServiceDocumentRequestImpl.java
@@ -0,0 +1,93 @@
+/*
+ * 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.communication.request.retrieve;
+
+import java.net.URI;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.ODataClient;
+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.domain.ODataServiceDocument;
+import org.apache.olingo.client.api.format.ODataFormat;
+
+/**
+ * This class implements an OData service document request.
+ */
+public class ODataServiceDocumentRequestImpl extends AbstractODataRetrieveRequest<ODataServiceDocument, ODataFormat>
+        implements ODataServiceDocumentRequest {
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param uri request URI.
+   */
+  ODataServiceDocumentRequestImpl(final ODataClient odataClient, final URI uri) {
+    super(odataClient, ODataFormat.class, uri);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataRetrieveResponse<ODataServiceDocument> execute() {
+    final HttpResponse res = doExecute();
+    return new ODataServiceResponseImpl(httpClient, res);
+  }
+
+  /**
+   * Response class about an ODataServiceDocumentRequest.
+   */
+  protected class ODataServiceResponseImpl extends ODataRetrieveResponseImpl {
+
+    private ODataServiceDocument serviceDocument = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataServiceResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataServiceResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    @Override
+    public ODataServiceDocument getBody() {
+      if (serviceDocument == null) {
+        try {
+          serviceDocument = odataClient.getReader().readServiceDocument(
+                  getRawResponse(), ODataFormat.fromString(getContentType()));
+        } finally {
+          this.close();
+        }
+      }
+      return serviceDocument;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataValueRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataValueRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataValueRequestImpl.java
new file mode 100644
index 0000000..db48449
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataValueRequestImpl.java
@@ -0,0 +1,108 @@
+/*
+ * 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.communication.request.retrieve;
+
+import java.io.IOException;
+import java.net.URI;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataValueRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
+import org.apache.olingo.client.api.domain.ODataPrimitiveValue;
+import org.apache.olingo.client.api.domain.ODataValue;
+import org.apache.olingo.client.api.format.ODataValueFormat;
+import org.apache.olingo.client.api.http.HttpClientException;
+
+/**
+ * This class implements an OData entity property value query request.
+ */
+public class ODataValueRequestImpl extends AbstractODataRetrieveRequest<ODataValue, ODataValueFormat>
+        implements ODataValueRequest {
+
+  /**
+   * Private constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param query query to be executed.
+   */
+  ODataValueRequestImpl(final ODataClient odataClient, final URI query) {
+    super(odataClient, ODataValueFormat.class, query);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataRetrieveResponse<ODataValue> execute() {
+    final HttpResponse res = doExecute();
+    return new ODataValueResponseImpl(httpClient, res);
+  }
+
+  /**
+   * Response class about an ODataDeleteReODataValueRequestquest.
+   */
+  protected class ODataValueResponseImpl extends ODataRetrieveResponseImpl {
+
+    private ODataValue value = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataValueResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataValueResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public ODataValue getBody() {
+      if (value == null) {
+        final ODataValueFormat format = ODataValueFormat.fromString(getContentType());
+
+        try {
+          value = new ODataPrimitiveValue.Builder(odataClient).
+                  setType(format == ODataValueFormat.TEXT
+                  ? ODataJClientEdmPrimitiveType.String : ODataJClientEdmPrimitiveType.Stream).
+                  setText(IOUtils.toString(getRawResponse())).
+                  build();
+        } catch (IOException e) {
+          throw new HttpClientException(e);
+        } finally {
+          this.close();
+        }
+      }
+      return value;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/V3RetrieveRequestFactoryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/V3RetrieveRequestFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/V3RetrieveRequestFactoryImpl.java
new file mode 100644
index 0000000..4f91b61
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/V3RetrieveRequestFactoryImpl.java
@@ -0,0 +1,39 @@
+/*
+ * 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.communication.request.retrieve;
+
+import java.net.URI;
+import org.apache.olingo.client.api.ODataV3Client;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataLinkCollectionRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.V3RetrieveRequestFactory;
+
+public class V3RetrieveRequestFactoryImpl extends AbstractRetrieveRequestFactory
+        implements V3RetrieveRequestFactory {
+
+  private static final long serialVersionUID = 6602745001042802479L;
+
+  public V3RetrieveRequestFactoryImpl(final ODataV3Client client) {
+    super(client);
+  }
+
+  @Override
+  public ODataLinkCollectionRequest getLinkCollectionRequest(final URI targetURI, final String linkName) {
+    return new ODataLinkCollectionRequestImpl((ODataV3Client) client, targetURI, linkName);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/V4RetrieveRequestFactoryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/V4RetrieveRequestFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/V4RetrieveRequestFactoryImpl.java
new file mode 100644
index 0000000..5bb58a8
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/V4RetrieveRequestFactoryImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.communication.request.retrieve;
+
+import org.apache.olingo.client.api.ODataV4Client;
+import org.apache.olingo.client.api.communication.request.retrieve.V4RetrieveRequestFactory;
+
+public class V4RetrieveRequestFactoryImpl extends AbstractRetrieveRequestFactory
+        implements V4RetrieveRequestFactory {
+
+  private static final long serialVersionUID = 546577958047902917L;
+
+  public V4RetrieveRequestFactoryImpl(final ODataV4Client client) {
+    super(client);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java
new file mode 100644
index 0000000..02445ae
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedEntityRequest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.communication.request.streamed;
+
+import java.net.URI;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataStreamManager;
+import org.apache.olingo.client.api.communication.request.streamed.ODataStreamedEntityRequest;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+import org.apache.olingo.client.api.http.HttpMethod;
+
+/**
+ * Abstract class representing a request concerning a streamed entity.
+ *
+ * @param <V> OData response type corresponding to the request implementation.
+ * @param <T> OData request payload type corresponding to the request implementation.
+ */
+public abstract class AbstractODataStreamedEntityRequest<V extends ODataResponse, T extends ODataStreamManager<V>>
+        extends AbstractODataStreamedRequest<V, T>
+        implements ODataStreamedEntityRequest<V, T> {
+
+  private ODataPubFormat format;
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param method HTTP request method.
+   * @param uri request URI.
+   */
+  public AbstractODataStreamedEntityRequest(final ODataClient odataClient, final HttpMethod method,
+          URI uri) {
+    super(odataClient, method, uri);
+    setAccept(getFormat().toString());
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public final ODataPubFormat getFormat() {
+    return format == null ? odataClient.getConfiguration().getDefaultPubFormat() : format;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public final void setFormat(final ODataPubFormat format) {
+    this.format = format;
+    setAccept(format.toString());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedRequest.java
new file mode 100644
index 0000000..7929398
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractODataStreamedRequest.java
@@ -0,0 +1,153 @@
+/*
+ * 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.communication.request.streamed;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.http.entity.ContentType;
+import org.apache.olingo.client.api.ODataBatchConstants;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataStreamManager;
+import org.apache.olingo.client.api.communication.request.ODataStreamedRequest;
+import org.apache.olingo.client.api.communication.request.ODataStreamer;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.api.format.ODataMediaFormat;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.api.utils.URIUtils;
+import org.apache.olingo.client.core.Wrapper;
+import org.apache.olingo.client.core.communication.request.ODataRequestImpl;
+import org.apache.commons.io.IOUtils;
+
+/**
+ * Streamed OData request abstract class.
+ *
+ * @param <V> OData response type corresponding to the request implementation.
+ * @param <T> OData request payload type corresponding to the request implementation.
+ */
+public abstract class AbstractODataStreamedRequest<V extends ODataResponse, T extends ODataStreamManager<V>>
+        extends ODataRequestImpl<ODataMediaFormat> implements ODataStreamedRequest<V, T> {
+
+  /**
+   * OData payload stream manager.
+   */
+  protected ODataStreamManager<V> streamManager;
+
+  /**
+   * Wrapper for actual streamed request's future. This holds information about the HTTP request / response currently
+   * open.
+   */
+  protected final Wrapper<Future<HttpResponse>> futureWrapper = new Wrapper<Future<HttpResponse>>();
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param method OData request HTTP method.
+   * @param uri OData request URI.
+   */
+  public AbstractODataStreamedRequest(final ODataClient odataClient,
+          final HttpMethod method, final URI uri) {
+
+    super(odataClient, ODataMediaFormat.class, method, uri);
+    setAccept(ContentType.APPLICATION_OCTET_STREAM.getMimeType());
+    setContentType(ContentType.APPLICATION_OCTET_STREAM.getMimeType());
+  }
+
+  /**
+   * Gets OData request payload management object.
+   *
+   * @return OData request payload management object.
+   */
+  protected abstract T getStreamManager();
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  @SuppressWarnings("unchecked")
+  public T execute() {
+    streamManager = getStreamManager();
+
+    ((HttpEntityEnclosingRequestBase) request).setEntity(
+            URIUtils.buildInputStreamEntity(odataClient, streamManager.getBody()));
+
+    futureWrapper.setWrapped(odataClient.getConfiguration().getExecutor().submit(new Callable<HttpResponse>() {
+      @Override
+      public HttpResponse call() throws Exception {
+        return doExecute();
+      }
+    }));
+
+    // returns the stream manager object
+    return (T) streamManager;
+  }
+
+  /**
+   * Writes (and consume) the request onto the given batch stream.
+   * <p>
+   * Please note that this method will consume the request (execution won't be possible anymore).
+   *
+   * @param req destination batch request.
+   */
+  public void batch(final ODataBatchRequest req) {
+    batch(req, null);
+  }
+
+  /**
+   * Writes (and consume) the request onto the given batch stream.
+   * <p>
+   * Please note that this method will consume the request (execution won't be possible anymore).
+   *
+   * @param req destination batch request.
+   * @param contentId ContentId header value to be added to the serialization. Use this in case of changeset items.
+   */
+  public void batch(final ODataBatchRequest req, final String contentId) {
+    final InputStream input = getStreamManager().getBody();
+
+    try {
+      // finalize the body
+      getStreamManager().finalizeBody();
+
+      req.rawAppend(toByteArray());
+      if (StringUtils.isNotBlank(contentId)) {
+        req.rawAppend((ODataBatchConstants.CHANGESET_CONTENT_ID_NAME + ": " + contentId).getBytes());
+        req.rawAppend(ODataStreamer.CRLF);
+      }
+      req.rawAppend(ODataStreamer.CRLF);
+
+      try {
+        req.rawAppend(IOUtils.toByteArray(input));
+      } catch (Exception e) {
+        LOG.debug("Invalid stream", e);
+        req.rawAppend(new byte[0]);
+      }
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
+    } finally {
+      IOUtils.closeQuietly(input);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractStreamedRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractStreamedRequestFactory.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractStreamedRequestFactory.java
new file mode 100644
index 0000000..b90db57
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/AbstractStreamedRequestFactory.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.client.core.communication.request.streamed;
+
+import java.io.InputStream;
+import java.net.URI;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.streamed.ODataMediaEntityCreateRequest;
+import org.apache.olingo.client.api.communication.request.streamed.ODataMediaEntityUpdateRequest;
+import org.apache.olingo.client.api.communication.request.streamed.ODataStreamUpdateRequest;
+import org.apache.olingo.client.api.communication.request.streamed.StreamedRequestFactory;
+import org.apache.olingo.client.api.http.HttpMethod;
+
+public abstract class AbstractStreamedRequestFactory implements StreamedRequestFactory {
+
+  private static final long serialVersionUID = -2438839640443961168L;
+
+  protected final ODataClient client;
+
+  protected AbstractStreamedRequestFactory(final ODataClient client) {
+    this.client = client;
+  }
+
+  @Override
+  public ODataMediaEntityCreateRequest getMediaEntityCreateRequest(
+          final URI targetURI, final InputStream media) {
+
+    return new ODataMediaEntityCreateRequestImpl(client, targetURI, media);
+  }
+
+  @Override
+  public ODataStreamUpdateRequest getStreamUpdateRequest(final URI targetURI, final InputStream stream) {
+    final ODataStreamUpdateRequest req;
+
+    if (client.getConfiguration().isUseXHTTPMethod()) {
+      req = new ODataStreamUpdateRequestImpl(client, HttpMethod.POST, targetURI, stream);
+      req.setXHTTPMethod(HttpMethod.PUT.name());
+    } else {
+      req = new ODataStreamUpdateRequestImpl(client, HttpMethod.PUT, targetURI, stream);
+    }
+
+    return req;
+  }
+
+  @Override
+  public ODataMediaEntityUpdateRequest getMediaEntityUpdateRequest(
+          final URI editURI, final InputStream media) {
+
+    final ODataMediaEntityUpdateRequest req;
+
+    if (client.getConfiguration().isUseXHTTPMethod()) {
+      req = new ODataMediaEntityUpdateRequestImpl(client, HttpMethod.POST, editURI, media);
+      req.setXHTTPMethod(HttpMethod.PUT.name());
+    } else {
+      req = new ODataMediaEntityUpdateRequestImpl(client, HttpMethod.PUT, editURI, media);
+    }
+
+    return req;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/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
new file mode 100644
index 0000000..4523969
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityCreateRequestImpl.java
@@ -0,0 +1,134 @@
+/*
+ * 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.communication.request.streamed;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.concurrent.TimeUnit;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+import org.apache.olingo.client.api.communication.request.streamed.MediaEntityCreateStreamManager;
+import org.apache.olingo.client.api.communication.request.streamed.ODataMediaEntityCreateRequest;
+import org.apache.olingo.client.api.communication.response.ODataMediaEntityCreateResponse;
+import org.apache.olingo.client.api.domain.ODataEntity;
+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.ODataResponseImpl;
+
+/**
+ * This class implements an OData Media Entity create request. Get instance by using ODataStreamedRequestFactory.
+ */
+public class ODataMediaEntityCreateRequestImpl
+        extends AbstractODataStreamedEntityRequest<ODataMediaEntityCreateResponse, MediaEntityCreateStreamManager>
+        implements ODataMediaEntityCreateRequest, ODataBatchableRequest {
+
+  private final InputStream media;
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param targetURI target entity set.
+   * @param media media entity blob to be created.
+   */
+  ODataMediaEntityCreateRequestImpl(final ODataClient odataClient, final URI targetURI, final InputStream media) {
+    super(odataClient, HttpMethod.POST, targetURI);
+    this.media = media;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected MediaEntityCreateStreamManager getStreamManager() {
+    if (streamManager == null) {
+      streamManager = new MediaEntityCreateStreamManagerImpl(media);
+    }
+    return (MediaEntityCreateStreamManager) streamManager;
+  }
+
+  /**
+   * Media entity payload object.
+   */
+  public class MediaEntityCreateStreamManagerImpl extends AbstractODataStreamManager<ODataMediaEntityCreateResponse>
+          implements MediaEntityCreateStreamManager {
+
+    /**
+     * Private constructor.
+     *
+     * @param input media stream.
+     */
+    private MediaEntityCreateStreamManagerImpl(final InputStream input) {
+      super(ODataMediaEntityCreateRequestImpl.this.futureWrapper, input);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    protected ODataMediaEntityCreateResponse getResponse(final long timeout, final TimeUnit unit) {
+      finalizeBody();
+      return new ODataMediaEntityCreateResponseImpl(httpClient, getHttpResponse(timeout, unit));
+    }
+  }
+
+  /**
+   * Response class about an ODataMediaEntityCreateRequest.
+   */
+  private class ODataMediaEntityCreateResponseImpl extends ODataResponseImpl
+          implements ODataMediaEntityCreateResponse {
+
+    private ODataEntity entity = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataMediaEntityCreateResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataMediaEntityCreateResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public ODataEntity getBody() {
+      if (entity == null) {
+        try {
+          entity = odataClient.getReader().readEntity(getRawResponse(), getFormat());
+        } finally {
+          this.close();
+        }
+      }
+      return entity;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/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
new file mode 100644
index 0000000..dbff55a
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataMediaEntityUpdateRequestImpl.java
@@ -0,0 +1,137 @@
+/*
+ * 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.communication.request.streamed;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.concurrent.TimeUnit;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+import org.apache.olingo.client.api.communication.request.streamed.MediaEntityUpdateStreamManager;
+import org.apache.olingo.client.api.communication.request.streamed.ODataMediaEntityUpdateRequest;
+import org.apache.olingo.client.api.communication.response.ODataMediaEntityUpdateResponse;
+import org.apache.olingo.client.api.domain.ODataEntity;
+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.ODataResponseImpl;
+
+/**
+ * This class implements an OData Media Entity create request. Get instance by using ODataStreamedRequestFactory.
+ */
+public class ODataMediaEntityUpdateRequestImpl
+        extends AbstractODataStreamedEntityRequest<ODataMediaEntityUpdateResponse, MediaEntityUpdateStreamManager>
+        implements ODataMediaEntityUpdateRequest, ODataBatchableRequest {
+
+  private final InputStream media;
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param method request method.
+   * @param editURI edit URI of the entity to be updated.
+   * @param media media entity blob to be created.
+   */
+  ODataMediaEntityUpdateRequestImpl(final ODataClient odataClient,
+          final HttpMethod method, final URI editURI, final InputStream media) {
+
+    super(odataClient, method, editURI);
+    this.media = media;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected MediaEntityUpdateStreamManager getStreamManager() {
+    if (streamManager == null) {
+      streamManager = new MediaEntityUpdateStreamManagerImpl(media);
+    }
+    return (MediaEntityUpdateStreamManager) streamManager;
+  }
+
+  /**
+   * Media entity payload object.
+   */
+  public class MediaEntityUpdateStreamManagerImpl extends AbstractODataStreamManager<ODataMediaEntityUpdateResponse>
+          implements MediaEntityUpdateStreamManager {
+
+    /**
+     * Private constructor.
+     *
+     * @param input media stream.
+     */
+    private MediaEntityUpdateStreamManagerImpl(final InputStream input) {
+      super(ODataMediaEntityUpdateRequestImpl.this.futureWrapper, input);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    protected ODataMediaEntityUpdateResponse getResponse(final long timeout, final TimeUnit unit) {
+      finalizeBody();
+      return new ODataMediaEntityUpdateResponseImpl(httpClient, getHttpResponse(timeout, unit));
+    }
+  }
+
+  /**
+   * Response class about an ODataMediaEntityUpdateRequest.
+   */
+  private class ODataMediaEntityUpdateResponseImpl extends ODataResponseImpl
+          implements ODataMediaEntityUpdateResponse {
+
+    private ODataEntity entity = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataMediaEntityUpdateResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataMediaEntityUpdateResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public ODataEntity getBody() {
+      if (entity == null) {
+        try {
+          entity = odataClient.getReader().readEntity(getRawResponse(), getFormat());
+        } finally {
+          this.close();
+        }
+      }
+      return entity;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataStreamUpdateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataStreamUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataStreamUpdateRequestImpl.java
new file mode 100644
index 0000000..3d42632
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/ODataStreamUpdateRequestImpl.java
@@ -0,0 +1,132 @@
+/*
+ * 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.communication.request.streamed;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.concurrent.TimeUnit;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+import org.apache.olingo.client.api.communication.request.streamed.ODataStreamUpdateRequest;
+import org.apache.olingo.client.api.communication.request.streamed.StreamUpdateStreamManager;
+import org.apache.olingo.client.api.communication.response.ODataStreamUpdateResponse;
+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.ODataResponseImpl;
+
+/**
+ * This class implements an OData stream create/update request. Get instance by using ODataStreamedRequestFactory.
+ */
+public class ODataStreamUpdateRequestImpl
+        extends AbstractODataStreamedRequest<ODataStreamUpdateResponse, StreamUpdateStreamManager>
+        implements ODataStreamUpdateRequest, ODataBatchableRequest {
+
+  private final InputStream stream;
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param method request method.
+   * @param targetURI target URI.
+   * @param stream stream to be updated.
+   */
+  ODataStreamUpdateRequestImpl(final ODataClient odataClient,
+          final HttpMethod method, final URI targetURI, final InputStream stream) {
+
+    super(odataClient, method, targetURI);
+    this.stream = stream;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected StreamUpdateStreamManager getStreamManager() {
+    if (streamManager == null) {
+      streamManager = new StreamUpdateStreamManagerImpl(this.stream);
+    }
+
+    return (StreamUpdateStreamManager) streamManager;
+  }
+
+  public class StreamUpdateStreamManagerImpl extends AbstractODataStreamManager<ODataStreamUpdateResponse> {
+
+    /**
+     * Private constructor.
+     *
+     * @param input payload input stream.
+     */
+    private StreamUpdateStreamManagerImpl(final InputStream input) {
+      super(ODataStreamUpdateRequestImpl.this.futureWrapper, input);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    protected ODataStreamUpdateResponse getResponse(final long timeout, final TimeUnit unit) {
+      finalizeBody();
+      return new ODataStreamUpdateResponseImpl(httpClient, getHttpResponse(timeout, unit));
+    }
+  }
+
+  /**
+   * Response class about an ODataStreamUpdateRequest.
+   */
+  private class ODataStreamUpdateResponseImpl extends ODataResponseImpl implements ODataStreamUpdateResponse {
+
+    private InputStream input = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataStreamUpdateResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataStreamUpdateResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * Gets query result objects.
+     * <br/>
+     * <b>WARNING</b>: Closing this <tt>ODataResponse</tt> instance is left to the caller.
+     *
+     * @return query result objects as <tt>InputStream</tt>.
+     */
+    @Override
+    public InputStream getBody() {
+      if (input == null) {
+        input = getRawResponse();
+      }
+      return input;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/V3StreamedRequestFactoryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/V3StreamedRequestFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/V3StreamedRequestFactoryImpl.java
new file mode 100644
index 0000000..aea4fdb
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/V3StreamedRequestFactoryImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.communication.request.streamed;
+
+import org.apache.olingo.client.api.ODataV3Client;
+import org.apache.olingo.client.api.communication.request.streamed.V3StreamedRequestFactory;
+
+public class V3StreamedRequestFactoryImpl extends AbstractStreamedRequestFactory
+        implements V3StreamedRequestFactory {
+
+  private static final long serialVersionUID = 2255688283995758441L;
+
+  public V3StreamedRequestFactoryImpl(final ODataV3Client client) {
+    super(client);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/V4StreamedRequestFactoryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/V4StreamedRequestFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/V4StreamedRequestFactoryImpl.java
new file mode 100644
index 0000000..4c59364
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/streamed/V4StreamedRequestFactoryImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.communication.request.streamed;
+
+import org.apache.olingo.client.api.ODataV4Client;
+import org.apache.olingo.client.api.communication.request.streamed.V4StreamedRequestFactory;
+
+public class V4StreamedRequestFactoryImpl extends AbstractStreamedRequestFactory
+        implements V4StreamedRequestFactory {
+
+  private static final long serialVersionUID = 960862845654673053L;
+
+  public V4StreamedRequestFactoryImpl(final ODataV4Client client) {
+    super(client);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/ODataResponseImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/ODataResponseImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/ODataResponseImpl.java
new file mode 100644
index 0000000..5a86aba
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/ODataResponseImpl.java
@@ -0,0 +1,276 @@
+/*
+ * 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.communication.response;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.TreeMap;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.communication.header.HeaderName;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchLineIterator;
+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.slf4j.LoggerFactory;
+
+/**
+ * Abstract representation of an OData response.
+ */
+public abstract class ODataResponseImpl implements ODataResponse {
+
+  /**
+   * Logger.
+   */
+  protected static final org.slf4j.Logger LOG = LoggerFactory.getLogger(ODataResponse.class);
+
+  /**
+   * HTTP client.
+   */
+  protected final HttpClient client;
+
+  /**
+   * HTTP response.
+   */
+  protected final HttpResponse res;
+
+  /**
+   * Response headers.
+   */
+  protected final Map<String, Collection<String>> headers =
+          new TreeMap<String, Collection<String>>(String.CASE_INSENSITIVE_ORDER);
+
+  /**
+   * Response code.
+   */
+  private int statusCode = -1;
+
+  /**
+   * Response message.
+   */
+  private String statusMessage = null;
+
+  /**
+   * Response body/payload.
+   */
+  private InputStream payload = null;
+
+  /**
+   * Initialization check.
+   */
+  private boolean hasBeenInitialized = false;
+
+  /**
+   * Batch info (if to be batched).
+   */
+  private ODataBatchController batchInfo = null;
+
+  /**
+   * Constructor.
+   */
+  public ODataResponseImpl() {
+    this.client = null;
+    this.res = null;
+  }
+
+  /**
+   * Constructor.
+   *
+   * @param client HTTP client.
+   * @param res HTTP response.
+   */
+  public ODataResponseImpl(final HttpClient client, final HttpResponse res) {
+    this.client = client;
+    this.res = res;
+
+    try {
+      this.payload = this.res.getEntity() == null ? null : this.res.getEntity().getContent();
+    } catch (Exception e) {
+      LOG.error("Error retrieving payload", e);
+      throw new IllegalStateException(e);
+    }
+
+    this.hasBeenInitialized = true;
+
+    for (Header header : res.getAllHeaders()) {
+      final Collection<String> headerValues;
+      if (headers.containsKey(header.getName())) {
+        headerValues = headers.get(header.getName());
+      } else {
+        headerValues = new HashSet<String>();
+        headers.put(header.getName(), headerValues);
+      }
+
+      headerValues.add(header.getValue());
+    }
+
+    statusCode = res.getStatusLine().getStatusCode();
+    statusMessage = res.getStatusLine().getReasonPhrase();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Collection<String> getHeaderNames() {
+    return headers.keySet();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Collection<String> getHeader(final String name) {
+    return headers.get(name);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Collection<String> getHeader(final HeaderName name) {
+    return headers.get(name.toString());
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getEtag() {
+    final Collection<String> etag = getHeader(HeaderName.etag);
+    return etag == null || etag.isEmpty()
+            ? null
+            : etag.iterator().next();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getContentType() {
+    final Collection<String> contentTypes = getHeader(HeaderName.contentType);
+    return contentTypes == null || contentTypes.isEmpty()
+            ? null
+            : contentTypes.iterator().next();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public int getStatusCode() {
+    return statusCode;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getStatusMessage() {
+    return statusMessage;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataResponse initFromBatch(
+          final Map.Entry<Integer, String> responseLine,
+          final Map<String, Collection<String>> headers,
+          final ODataBatchLineIterator batchLineIterator,
+          final String boundary) {
+
+    if (hasBeenInitialized) {
+      throw new IllegalStateException("Request already initialized");
+    }
+
+    this.hasBeenInitialized = true;
+
+    this.batchInfo = new ODataBatchController(batchLineIterator, boundary);
+
+    this.statusCode = responseLine.getKey();
+    this.statusMessage = responseLine.getValue();
+    this.headers.putAll(headers);
+
+    return this;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public void close() {
+    if (client == null) {
+      IOUtils.closeQuietly(payload);
+    } else {
+      this.client.getConnectionManager().shutdown();
+    }
+
+    if (batchInfo != null) {
+      batchInfo.setValidBatch(false);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public InputStream getRawResponse() {
+    if (HttpStatus.SC_NO_CONTENT == getStatusCode()) {
+      throw new NoContentException();
+    }
+
+    if (payload == null && batchInfo.isValidBatch()) {
+      // get input stream till the end of item
+      payload = new PipedInputStream();
+
+      try {
+        final PipedOutputStream os = new PipedOutputStream((PipedInputStream) payload);
+
+        new Thread(new Runnable() {
+          @Override
+          public void run() {
+            try {
+              ODataBatchUtilities.readBatchPart(batchInfo, os, true);
+            } catch (Exception e) {
+              LOG.error("Error streaming batch item payload", e);
+            } finally {
+              IOUtils.closeQuietly(os);
+            }
+          }
+        }).start();
+
+      } catch (IOException e) {
+        LOG.error("Error streaming payload response", e);
+        throw new IllegalStateException(e);
+      }
+    }
+
+    return payload;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchResponseManager.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchResponseManager.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchResponseManager.java
new file mode 100644
index 0000000..a8cfd2d
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/response/batch/ODataBatchResponseManager.java
@@ -0,0 +1,151 @@
+/*
+ * 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.communication.response.batch;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.client.api.communication.header.HeaderName;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchLineIterator;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem;
+import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
+import org.apache.olingo.client.core.communication.request.batch.ODataBatchLineIteratorImpl;
+import org.apache.olingo.client.core.communication.request.batch.ODataBatchUtilities;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Batch response manager class.
+ */
+public class ODataBatchResponseManager implements Iterator<ODataBatchResponseItem> {
+
+  /**
+   * Logger.
+   */
+  private static final Logger LOG = LoggerFactory.getLogger(ODataBatchResponseManager.class);
+
+  /**
+   * Batch response line iterator.
+   */
+  private final ODataBatchLineIterator batchLineIterator;
+
+  /**
+   * Batch boundary.
+   */
+  private final String batchBoundary;
+
+  /**
+   * Expected batch response items iterator.
+   */
+  private final Iterator<ODataBatchResponseItem> expectedItemsIterator;
+
+  /**
+   * Last retrieved batch response item.
+   */
+  private ODataBatchResponseItem current = null;
+
+  /**
+   * Constructor.
+   *
+   * @param res OData batch response.
+   * @param expectedItems expected batch response items.
+   */
+  public ODataBatchResponseManager(final ODataBatchResponse res, final List<ODataBatchResponseItem> expectedItems) {
+    try {
+      this.expectedItemsIterator = expectedItems.iterator();
+      this.batchLineIterator = new ODataBatchLineIteratorImpl(
+              IOUtils.lineIterator(res.getRawResponse(), Constants.UTF8));
+
+      // search for boundary
+      batchBoundary = ODataBatchUtilities.getBoundaryFromHeader(
+              res.getHeader(HeaderName.contentType));
+      LOG.debug("Retrieved batch response bondary '{}'", batchBoundary);
+    } catch (IOException e) {
+      LOG.error("Error parsing batch response", e);
+      throw new IllegalStateException(e);
+    }
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public boolean hasNext() {
+    return expectedItemsIterator.hasNext();
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataBatchResponseItem next() {
+    if (current != null) {
+      current.close();
+    }
+
+    if (!hasNext()) {
+      throw new NoSuchElementException("No item found");
+    }
+
+    current = expectedItemsIterator.next();
+
+    final Map<String, Collection<String>> nextItemHeaders =
+            ODataBatchUtilities.nextItemHeaders(batchLineIterator, batchBoundary);
+
+    switch (ODataBatchUtilities.getItemType(nextItemHeaders)) {
+      case CHANGESET:
+        if (!current.isChangeset()) {
+          throw new IllegalStateException("Unexpected batch item");
+        }
+
+        current.initFromBatch(
+                batchLineIterator,
+                ODataBatchUtilities.getBoundaryFromHeader(
+                nextItemHeaders.get(HeaderName.contentType.toString())));
+        break;
+
+      case RETRIEVE:
+        if (current.isChangeset()) {
+          throw new IllegalStateException("Unexpected batch item");
+        }
+
+        current.initFromBatch(
+                batchLineIterator,
+                batchBoundary);
+        break;
+      default:
+        throw new IllegalStateException("Expected item not found");
+    }
+
+    return current;
+  }
+
+  /**
+   * Unsupported operation.
+   */
+  @Override
+  public void remove() {
+    throw new UnsupportedOperationException("Remove operation is not supported");
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
index 5502629..0b5e974 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
@@ -23,7 +23,7 @@ import java.net.URI;
 import java.util.List;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.client.api.ODataClient;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.domain.ODataOperation;
 import org.apache.olingo.client.api.utils.XMLUtils;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
@@ -45,26 +45,26 @@ public class AtomDeserializer {
   }
 
   private void common(final Element input, final AtomObject object) {
-    if (StringUtils.isNotBlank(input.getAttribute(ODataConstants.ATTR_XMLBASE))) {
-      object.setBaseURI(input.getAttribute(ODataConstants.ATTR_XMLBASE));
+    if (StringUtils.isNotBlank(input.getAttribute(Constants.ATTR_XMLBASE))) {
+      object.setBaseURI(input.getAttribute(Constants.ATTR_XMLBASE));
     }
 
-    final List<Element> ids = XMLUtils.getChildElements(input, ODataConstants.ATOM_ELEM_ID);
+    final List<Element> ids = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_ID);
     if (!ids.isEmpty()) {
       object.setId(ids.get(0).getTextContent());
     }
 
-    final List<Element> titles = XMLUtils.getChildElements(input, ODataConstants.ATOM_ELEM_TITLE);
+    final List<Element> titles = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_TITLE);
     if (!titles.isEmpty()) {
       object.setTitle(titles.get(0).getTextContent());
     }
 
-    final List<Element> summaries = XMLUtils.getChildElements(input, ODataConstants.ATOM_ELEM_SUMMARY);
+    final List<Element> summaries = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_SUMMARY);
     if (!summaries.isEmpty()) {
       object.setSummary(summaries.get(0).getTextContent());
     }
 
-    final List<Element> updateds = XMLUtils.getChildElements(input, ODataConstants.ATOM_ELEM_UPDATED);
+    final List<Element> updateds = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_UPDATED);
     if (!updateds.isEmpty()) {
       try {
         object.setUpdated(ISO_DATEFORMAT.parse(updateds.get(0).getTextContent()));
@@ -75,7 +75,7 @@ public class AtomDeserializer {
   }
 
   public AtomEntryImpl entry(final Element input) {
-    if (!ODataConstants.ATOM_ELEM_ENTRY.equals(input.getNodeName())) {
+    if (!Constants.ATOM_ELEM_ENTRY.equals(input.getNodeName())) {
       return null;
     }
 
@@ -83,43 +83,43 @@ public class AtomDeserializer {
 
     common(input, entry);
 
-    final String etag = input.getAttribute(ODataConstants.ATOM_ATTR_ETAG);
+    final String etag = input.getAttribute(Constants.ATOM_ATTR_ETAG);
     if (StringUtils.isNotBlank(etag)) {
       entry.setETag(etag);
     }
 
-    final List<Element> categories = XMLUtils.getChildElements(input, ODataConstants.ATOM_ELEM_CATEGORY);
+    final List<Element> categories = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_CATEGORY);
     if (!categories.isEmpty()) {
-      entry.setType(categories.get(0).getAttribute(ODataConstants.ATOM_ATTR_TERM));
+      entry.setType(categories.get(0).getAttribute(Constants.ATOM_ATTR_TERM));
     }
 
-    final List<Element> links = XMLUtils.getChildElements(input, ODataConstants.ATOM_ELEM_LINK);
+    final List<Element> links = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_LINK);
     for (Element linkElem : links) {
       final LinkImpl link = new LinkImpl();
-      link.setRel(linkElem.getAttribute(ODataConstants.ATTR_REL));
-      link.setTitle(linkElem.getAttribute(ODataConstants.ATTR_TITLE));
-      link.setHref(linkElem.getAttribute(ODataConstants.ATTR_HREF));
+      link.setRel(linkElem.getAttribute(Constants.ATTR_REL));
+      link.setTitle(linkElem.getAttribute(Constants.ATTR_TITLE));
+      link.setHref(linkElem.getAttribute(Constants.ATTR_HREF));
 
-      if (ODataConstants.SELF_LINK_REL.equals(link.getRel())) {
+      if (Constants.SELF_LINK_REL.equals(link.getRel())) {
         entry.setSelfLink(link);
-      } else if (ODataConstants.EDIT_LINK_REL.equals(link.getRel())) {
+      } else if (Constants.EDIT_LINK_REL.equals(link.getRel())) {
         entry.setEditLink(link);
       } else if (link.getRel().startsWith(
               client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NAVIGATION_LINK_REL))) {
 
-        link.setType(linkElem.getAttribute(ODataConstants.ATTR_TYPE));
+        link.setType(linkElem.getAttribute(Constants.ATTR_TYPE));
         entry.getNavigationLinks().add(link);
 
-        final List<Element> inlines = XMLUtils.getChildElements(linkElem, ODataConstants.ATOM_ELEM_INLINE);
+        final List<Element> inlines = XMLUtils.getChildElements(linkElem, Constants.ATOM_ELEM_INLINE);
         if (!inlines.isEmpty()) {
           final List<Element> entries =
-                  XMLUtils.getChildElements(inlines.get(0), ODataConstants.ATOM_ELEM_ENTRY);
+                  XMLUtils.getChildElements(inlines.get(0), Constants.ATOM_ELEM_ENTRY);
           if (!entries.isEmpty()) {
             link.setInlineEntry(entry(entries.get(0)));
           }
 
           final List<Element> feeds =
-                  XMLUtils.getChildElements(inlines.get(0), ODataConstants.ATOM_ELEM_FEED);
+                  XMLUtils.getChildElements(inlines.get(0), Constants.ATOM_ELEM_FEED);
           if (!feeds.isEmpty()) {
             link.setInlineFeed(feed(feeds.get(0)));
           }
@@ -135,15 +135,15 @@ public class AtomDeserializer {
       }
     }
 
-    final List<Element> authors = XMLUtils.getChildElements(input, ODataConstants.ATOM_ELEM_AUTHOR);
+    final List<Element> authors = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_AUTHOR);
     if (!authors.isEmpty()) {
       final AtomEntryImpl.Author author = new AtomEntryImpl.Author();
       for (Node child : XMLUtils.getChildNodes(input, Node.ELEMENT_NODE)) {
-        if (ODataConstants.ATOM_ELEM_AUTHOR_NAME.equals(XMLUtils.getSimpleName(child))) {
+        if (Constants.ATOM_ELEM_AUTHOR_NAME.equals(XMLUtils.getSimpleName(child))) {
           author.setName(child.getTextContent());
-        } else if (ODataConstants.ATOM_ELEM_AUTHOR_URI.equals(XMLUtils.getSimpleName(child))) {
+        } else if (Constants.ATOM_ELEM_AUTHOR_URI.equals(XMLUtils.getSimpleName(child))) {
           author.setUri(child.getTextContent());
-        } else if (ODataConstants.ATOM_ELEM_AUTHOR_EMAIL.equals(XMLUtils.getSimpleName(child))) {
+        } else if (Constants.ATOM_ELEM_AUTHOR_EMAIL.equals(XMLUtils.getSimpleName(child))) {
           author.setEmail(child.getTextContent());
         }
       }
@@ -152,26 +152,26 @@ public class AtomDeserializer {
       }
     }
 
-    final List<Element> actions = XMLUtils.getChildElements(input, ODataConstants.ATOM_ELEM_ACTION);
+    final List<Element> actions = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_ACTION);
     for (Element action : actions) {
       final ODataOperation operation = new ODataOperation();
-      operation.setMetadataAnchor(action.getAttribute(ODataConstants.ATTR_METADATA));
-      operation.setTitle(action.getAttribute(ODataConstants.ATTR_TITLE));
-      operation.setTarget(URI.create(action.getAttribute(ODataConstants.ATTR_TARGET)));
+      operation.setMetadataAnchor(action.getAttribute(Constants.ATTR_METADATA));
+      operation.setTitle(action.getAttribute(Constants.ATTR_TITLE));
+      operation.setTarget(URI.create(action.getAttribute(Constants.ATTR_TARGET)));
 
       entry.getOperations().add(operation);
     }
 
-    final List<Element> contents = XMLUtils.getChildElements(input, ODataConstants.ATOM_ELEM_CONTENT);
+    final List<Element> contents = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_CONTENT);
     if (!contents.isEmpty()) {
       final Element content = contents.get(0);
 
-      List<Element> props = XMLUtils.getChildElements(content, ODataConstants.ELEM_PROPERTIES);
+      List<Element> props = XMLUtils.getChildElements(content, Constants.ELEM_PROPERTIES);
       if (props.isEmpty()) {
-        entry.setMediaContentSource(content.getAttribute(ODataConstants.ATOM_ATTR_SRC));
-        entry.setMediaContentType(content.getAttribute(ODataConstants.ATTR_TYPE));
+        entry.setMediaContentSource(content.getAttribute(Constants.ATOM_ATTR_SRC));
+        entry.setMediaContentType(content.getAttribute(Constants.ATTR_TYPE));
 
-        props = XMLUtils.getChildElements(input, ODataConstants.ELEM_PROPERTIES);
+        props = XMLUtils.getChildElements(input, Constants.ELEM_PROPERTIES);
         if (!props.isEmpty()) {
           entry.setMediaEntryProperties(props.get(0));
         }
@@ -184,7 +184,7 @@ public class AtomDeserializer {
   }
 
   public AtomFeedImpl feed(final Element input) {
-    if (!ODataConstants.ATOM_ELEM_FEED.equals(input.getNodeName())) {
+    if (!Constants.ATOM_ELEM_FEED.equals(input.getNodeName())) {
       return null;
     }
 
@@ -192,19 +192,19 @@ public class AtomDeserializer {
 
     common(input, feed);
 
-    final List<Element> entries = XMLUtils.getChildElements(input, ODataConstants.ATOM_ELEM_ENTRY);
+    final List<Element> entries = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_ENTRY);
     for (Element entry : entries) {
       feed.getEntries().add(entry(entry));
     }
 
-    final List<Element> links = XMLUtils.getChildElements(input, ODataConstants.ATOM_ELEM_LINK);
+    final List<Element> links = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_LINK);
     for (Element link : links) {
-      if (ODataConstants.NEXT_LINK_REL.equals(link.getAttribute(ODataConstants.ATTR_REL))) {
-        feed.setNext(URI.create(link.getAttribute(ODataConstants.ATTR_HREF)));
+      if (Constants.NEXT_LINK_REL.equals(link.getAttribute(Constants.ATTR_REL))) {
+        feed.setNext(URI.create(link.getAttribute(Constants.ATTR_HREF)));
       }
     }
 
-    final List<Element> counts = XMLUtils.getChildElements(input, ODataConstants.ATOM_ATTR_COUNT);
+    final List<Element> counts = XMLUtils.getChildElements(input, Constants.ATOM_ATTR_COUNT);
     if (!counts.isEmpty()) {
       try {
         feed.setCount(Integer.parseInt(counts.get(0).getTextContent()));

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomSerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomSerializer.java
index 73def31..7a358dc 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomSerializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomSerializer.java
@@ -25,7 +25,7 @@ import javax.xml.parsers.ParserConfigurationException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.entity.ContentType;
 import org.apache.olingo.client.api.ODataClient;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.data.Entry;
 import org.apache.olingo.client.api.data.Link;
 import org.apache.olingo.client.api.utils.XMLUtils;
@@ -53,18 +53,18 @@ public class AtomSerializer {
 
   private void setLinks(final Element entry, final List<Link> links) throws ParserConfigurationException {
     for (Link link : links) {
-      final Element linkElem = entry.getOwnerDocument().createElement(ODataConstants.ATOM_ELEM_LINK);
+      final Element linkElem = entry.getOwnerDocument().createElement(Constants.ATOM_ELEM_LINK);
 
-      linkElem.setAttribute(ODataConstants.ATTR_REL, link.getRel());
-      linkElem.setAttribute(ODataConstants.ATTR_TITLE, link.getTitle());
-      linkElem.setAttribute(ODataConstants.ATTR_HREF, link.getHref());
+      linkElem.setAttribute(Constants.ATTR_REL, link.getRel());
+      linkElem.setAttribute(Constants.ATTR_TITLE, link.getTitle());
+      linkElem.setAttribute(Constants.ATTR_HREF, link.getHref());
 
       if (StringUtils.isNotBlank(link.getType())) {
-        linkElem.setAttribute(ODataConstants.ATTR_TYPE, link.getType());
+        linkElem.setAttribute(Constants.ATTR_TYPE, link.getType());
       }
 
       if (link.getInlineEntry() != null || link.getInlineFeed() != null) {
-        final Element inline = entry.getOwnerDocument().createElement(ODataConstants.ATOM_ELEM_INLINE);
+        final Element inline = entry.getOwnerDocument().createElement(Constants.ATOM_ELEM_INLINE);
         linkElem.appendChild(inline);
 
         if (link.getInlineEntry() != null) {
@@ -85,33 +85,33 @@ public class AtomSerializer {
     final DocumentBuilder builder = XMLUtils.DOC_BUILDER_FACTORY.newDocumentBuilder();
     final Document doc = builder.newDocument();
 
-    final Element entryElem = doc.createElement(ODataConstants.ATOM_ELEM_ENTRY);
-    entryElem.setAttribute(XMLConstants.XMLNS_ATTRIBUTE, ODataConstants.NS_ATOM);
-    entryElem.setAttribute(ODataConstants.XMLNS_METADATA,
+    final Element entryElem = doc.createElement(Constants.ATOM_ELEM_ENTRY);
+    entryElem.setAttribute(XMLConstants.XMLNS_ATTRIBUTE, Constants.NS_ATOM);
+    entryElem.setAttribute(Constants.XMLNS_METADATA,
             client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA));
-    entryElem.setAttribute(ODataConstants.XMLNS_DATASERVICES,
+    entryElem.setAttribute(Constants.XMLNS_DATASERVICES,
             client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES));
-    entryElem.setAttribute(ODataConstants.XMLNS_GML, ODataConstants.NS_GML);
-    entryElem.setAttribute(ODataConstants.XMLNS_GEORSS, ODataConstants.NS_GEORSS);
+    entryElem.setAttribute(Constants.XMLNS_GML, Constants.NS_GML);
+    entryElem.setAttribute(Constants.XMLNS_GEORSS, Constants.NS_GEORSS);
     if (entry.getBaseURI() != null) {
-      entryElem.setAttribute(ODataConstants.ATTR_XMLBASE, entry.getBaseURI().toASCIIString());
+      entryElem.setAttribute(Constants.ATTR_XMLBASE, entry.getBaseURI().toASCIIString());
     }
     doc.appendChild(entryElem);
 
-    final Element category = doc.createElement(ODataConstants.ATOM_ELEM_CATEGORY);
-    category.setAttribute(ODataConstants.ATOM_ATTR_TERM, entry.getType());
-    category.setAttribute(ODataConstants.ATOM_ATTR_SCHEME,
+    final Element category = doc.createElement(Constants.ATOM_ELEM_CATEGORY);
+    category.setAttribute(Constants.ATOM_ATTR_TERM, entry.getType());
+    category.setAttribute(Constants.ATOM_ATTR_SCHEME,
             client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_SCHEME));
     entryElem.appendChild(category);
 
     if (StringUtils.isNotBlank(entry.getTitle())) {
-      final Element title = doc.createElement(ODataConstants.ATOM_ELEM_TITLE);
+      final Element title = doc.createElement(Constants.ATOM_ELEM_TITLE);
       title.appendChild(doc.createTextNode(entry.getTitle()));
       entryElem.appendChild(title);
     }
 
     if (StringUtils.isNotBlank(entry.getSummary())) {
-      final Element summary = doc.createElement(ODataConstants.ATOM_ELEM_SUMMARY);
+      final Element summary = doc.createElement(Constants.ATOM_ELEM_SUMMARY);
       summary.appendChild(doc.createTextNode(entry.getSummary()));
       entryElem.appendChild(summary);
     }
@@ -120,13 +120,13 @@ public class AtomSerializer {
     setLinks(entryElem, entry.getNavigationLinks());
     setLinks(entryElem, entry.getMediaEditLinks());
 
-    final Element content = doc.createElement(ODataConstants.ATOM_ELEM_CONTENT);
+    final Element content = doc.createElement(Constants.ATOM_ELEM_CONTENT);
     if (entry.isMediaEntry()) {
       if (StringUtils.isNotBlank(entry.getMediaContentType())) {
-        content.setAttribute(ODataConstants.ATTR_TYPE, entry.getMediaContentType());
+        content.setAttribute(Constants.ATTR_TYPE, entry.getMediaContentType());
       }
       if (StringUtils.isNotBlank(entry.getMediaContentSource())) {
-        content.setAttribute(ODataConstants.ATOM_ATTR_SRC, entry.getMediaContentSource());
+        content.setAttribute(Constants.ATOM_ATTR_SRC, entry.getMediaContentSource());
       }
       if (content.getAttributes().getLength() > 0) {
         entryElem.appendChild(content);
@@ -136,7 +136,7 @@ public class AtomSerializer {
         entryElem.appendChild(doc.importNode(entry.getMediaEntryProperties(), true));
       }
     } else {
-      content.setAttribute(ODataConstants.ATTR_TYPE, ContentType.APPLICATION_XML.getMimeType());
+      content.setAttribute(Constants.ATTR_TYPE, ContentType.APPLICATION_XML.getMimeType());
       if (entry.getContent() != null) {
         content.appendChild(doc.importNode(entry.getContent(), true));
       }
@@ -150,27 +150,27 @@ public class AtomSerializer {
     final DocumentBuilder builder = XMLUtils.DOC_BUILDER_FACTORY.newDocumentBuilder();
     final Document doc = builder.newDocument();
 
-    final Element feedElem = doc.createElement(ODataConstants.ATOM_ELEM_FEED);
-    feedElem.setAttribute(XMLConstants.XMLNS_ATTRIBUTE, ODataConstants.NS_ATOM);
-    feedElem.setAttribute(ODataConstants.XMLNS_METADATA,
+    final Element feedElem = doc.createElement(Constants.ATOM_ELEM_FEED);
+    feedElem.setAttribute(XMLConstants.XMLNS_ATTRIBUTE, Constants.NS_ATOM);
+    feedElem.setAttribute(Constants.XMLNS_METADATA,
             client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_METADATA));
-    feedElem.setAttribute(ODataConstants.XMLNS_DATASERVICES,
+    feedElem.setAttribute(Constants.XMLNS_DATASERVICES,
             client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES));
-    feedElem.setAttribute(ODataConstants.XMLNS_GML, ODataConstants.NS_GML);
-    feedElem.setAttribute(ODataConstants.XMLNS_GEORSS, ODataConstants.NS_GEORSS);
+    feedElem.setAttribute(Constants.XMLNS_GML, Constants.NS_GML);
+    feedElem.setAttribute(Constants.XMLNS_GEORSS, Constants.NS_GEORSS);
     if (feed.getBaseURI() != null) {
-      feedElem.setAttribute(ODataConstants.ATTR_XMLBASE, feed.getBaseURI().toASCIIString());
+      feedElem.setAttribute(Constants.ATTR_XMLBASE, feed.getBaseURI().toASCIIString());
     }
     doc.appendChild(feedElem);
 
     if (StringUtils.isNotBlank(feed.getTitle())) {
-      final Element title = doc.createElement(ODataConstants.ATOM_ELEM_TITLE);
+      final Element title = doc.createElement(Constants.ATOM_ELEM_TITLE);
       title.appendChild(doc.createTextNode(feed.getTitle()));
       feedElem.appendChild(title);
     }
 
     if (StringUtils.isNotBlank(feed.getSummary())) {
-      final Element summary = doc.createElement(ODataConstants.ATOM_ELEM_SUMMARY);
+      final Element summary = doc.createElement(Constants.ATOM_ELEM_SUMMARY);
       summary.appendChild(doc.createTextNode(feed.getSummary()));
       feedElem.appendChild(summary);
     }


[4/7] OLINGO-205 ODataJClient request/response layer implementation imported

Posted by fm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
new file mode 100644
index 0000000..b4ae74e
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
@@ -0,0 +1,483 @@
+/*
+ * 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.communication.request;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.net.URI;
+import java.util.Collection;
+import java.util.Collections;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.impl.client.DecompressingHttpClient;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.V3Configuration;
+import org.apache.olingo.client.api.communication.ODataClientErrorException;
+import org.apache.olingo.client.api.communication.ODataServerErrorException;
+import org.apache.olingo.client.api.communication.header.HeaderName;
+import org.apache.olingo.client.api.communication.header.ODataHeaderValues;
+import org.apache.olingo.client.api.communication.header.ODataHeaders;
+import org.apache.olingo.client.api.communication.request.ODataRequest;
+import org.apache.olingo.client.api.communication.request.ODataStreamer;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.api.format.ODataMediaFormat;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+import org.apache.olingo.client.api.format.ODataValueFormat;
+import org.apache.olingo.client.api.http.HttpClientException;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.data.JSONErrorImpl;
+import org.apache.olingo.client.core.data.XMLErrorImpl;
+import org.apache.olingo.client.api.data.Error;
+import org.apache.olingo.client.core.communication.header.ODataHeadersImpl;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract representation of an OData request. Get instance by using factories.
+ *
+ * @param <T> Accepted content-type formats by the request in object.
+ *
+ * @see CUDRequestFactory
+ * @see BatchRequestFactory
+ * @see InvokeRequestFactory
+ * @see StreamedRequestFactory
+ */
+public class ODataRequestImpl<T extends Enum<T>> implements ODataRequest {
+
+  /**
+   * Logger.
+   */
+  protected static final Logger LOG = LoggerFactory.getLogger(ODataRequest.class);
+
+  protected final ODataClient odataClient;
+
+  protected final Class<T> formatRef;
+
+  /**
+   * OData request method.
+   */
+  protected final HttpMethod method;
+
+  /**
+   * OData request header.
+   */
+  protected final ODataHeadersImpl odataHeaders;
+
+  /**
+   * Target URI.
+   */
+  protected final URI uri;
+
+  /**
+   * HTTP client.
+   */
+  protected final HttpClient httpClient;
+
+  /**
+   * HTTP request.
+   */
+  protected final HttpUriRequest request;
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param formatRef reference class for the format being used
+   * @param method HTTP request method. If configured X-HTTP-METHOD header will be used.
+   * @param uri OData request URI.
+   */
+  protected ODataRequestImpl(final ODataClient odataClient,
+          final Class<T> formatRef, final HttpMethod method, final URI uri) {
+
+    this.odataClient = odataClient;
+
+    this.formatRef = formatRef;
+    this.method = method;
+
+    // initialize default headers
+    this.odataHeaders = (ODataHeadersImpl) odataClient.getVersionHeaders();
+
+    // target uri
+    this.uri = uri;
+
+    HttpClient _httpClient = odataClient.getConfiguration().getHttpClientFactory().
+            createHttpClient(this.method, this.uri);
+    if (odataClient.getConfiguration().isGzipCompression()) {
+      _httpClient = new DecompressingHttpClient(_httpClient);
+    }
+    this.httpClient = _httpClient;
+
+    this.request = odataClient.getConfiguration().getHttpUriRequestFactory().
+            createHttpUriRequest(this.method, this.uri);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @SuppressWarnings("unchecked")
+  public T getDefaultFormat() {
+    return (T) (formatRef.equals(ODataPubFormat.class)
+            ? odataClient.getConfiguration().getDefaultPubFormat()
+            : (formatRef.equals(ODataValueFormat.class)
+            ? odataClient.getConfiguration().getDefaultValueFormat()
+            : (formatRef.equals(ODataMediaFormat.class)
+            ? odataClient.getConfiguration().getDefaultMediaFormat()
+            : odataClient.getConfiguration().getDefaultFormat())));
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public URI getURI() {
+    return uri;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Collection<String> getHeaderNames() {
+    return odataHeaders.getHeaderNames();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getHeader(final String name) {
+    return odataHeaders.getHeader(name);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest setAccept(final String value) {
+    odataHeaders.setHeader(HeaderName.accept, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest setIfMatch(final String value) {
+    odataHeaders.setHeader(HeaderName.ifMatch, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest setIfNoneMatch(final String value) {
+    odataHeaders.setHeader(HeaderName.ifNoneMatch, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest setPrefer(final String value) {
+    odataHeaders.setHeader(HeaderName.prefer, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest setXHTTPMethod(final String value) {
+    odataHeaders.setHeader(HeaderName.xHttpMethod, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest setContentType(final String value) {
+    odataHeaders.setHeader(HeaderName.contentType, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest setSlug(final String value) {
+    odataHeaders.setHeader(HeaderName.slug, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataRequest addCustomHeader(final String name, final String value) {
+    odataHeaders.setHeader(name, value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getAccept() {
+    final String acceptHead = odataHeaders.getHeader(HeaderName.accept);
+    return StringUtils.isBlank(acceptHead) ? getDefaultFormat().toString() : acceptHead;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getIfMatch() {
+    return odataHeaders.getHeader(HeaderName.ifMatch);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getIfNoneMatch() {
+    return odataHeaders.getHeader(HeaderName.ifNoneMatch);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getPrefer() {
+    return odataHeaders.getHeader(HeaderName.prefer);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String getContentType() {
+    final String contentTypeHead = odataHeaders.getHeader(HeaderName.contentType);
+    return StringUtils.isBlank(contentTypeHead) ? getDefaultFormat().toString() : contentTypeHead;
+  }
+
+  /**
+   * ${@inheritDoc }
+   */
+  @Override
+  public HttpMethod getMethod() {
+    return method;
+  }
+
+  /**
+   * Gets request headers.
+   *
+   * @return request headers.
+   */
+  public ODataHeaders getHeader() {
+    return odataHeaders;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public byte[] toByteArray() {
+    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    try {
+      final StringBuilder requestBuilder = new StringBuilder();
+      requestBuilder.append(getMethod().toString()).append(" ").
+              append(uri.toString()).append(" ").append("HTTP/1.1");
+
+      baos.write(requestBuilder.toString().getBytes());
+
+      baos.write(ODataStreamer.CRLF);
+
+      // Set Content-Type and Accept headers with default values, if not yet set
+      if (StringUtils.isBlank(odataHeaders.getHeader(HeaderName.contentType))) {
+        setContentType(getContentType());
+      }
+      if (StringUtils.isBlank(odataHeaders.getHeader(HeaderName.accept))) {
+        setAccept(getAccept());
+      }
+
+      for (String name : getHeaderNames()) {
+        final String value = getHeader(name);
+
+        if (StringUtils.isNotBlank(value)) {
+          baos.write((name + ": " + value).getBytes());
+          baos.write(ODataStreamer.CRLF);
+        }
+      }
+
+      return baos.toByteArray();
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
+    } finally {
+      IOUtils.closeQuietly(baos);
+    }
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public InputStream rawExecute() {
+    try {
+      final HttpEntity httpEntity = doExecute().getEntity();
+      return httpEntity == null ? null : httpEntity.getContent();
+    } catch (IOException e) {
+      throw new HttpClientException(e);
+    } catch (RuntimeException e) {
+      this.request.abort();
+      throw new HttpClientException(e);
+    }
+  }
+
+  /**
+   * Builds the request and execute it.
+   *
+   * @return HttpReponse object.
+   */
+  protected HttpResponse doExecute() {
+    // Set Content-Type and Accept headers with default values, if not yet set
+    if (StringUtils.isBlank(odataHeaders.getHeader(HeaderName.contentType))) {
+      setContentType(getContentType());
+    }
+    if (StringUtils.isBlank(odataHeaders.getHeader(HeaderName.accept))) {
+      setAccept(getAccept());
+    }
+
+    // Add header for KeyAsSegment management
+    if (odataClient.getServiceVersion() == ODataServiceVersion.V30
+            && ((V3Configuration) odataClient.getConfiguration()).isKeyAsSegment()) {
+      addCustomHeader(
+              HeaderName.dataServiceUrlConventions.toString(), ODataHeaderValues.keyAsSegment);
+    }
+
+    // Add all available headers
+    for (String key : getHeaderNames()) {
+      this.request.addHeader(key, odataHeaders.getHeader(key));
+    }
+
+    if (LOG.isDebugEnabled()) {
+      for (Header header : this.request.getAllHeaders()) {
+        LOG.debug("HTTP header being sent: " + header);
+      }
+    }
+
+    final HttpResponse response;
+    try {
+      response = this.httpClient.execute(this.request);
+    } catch (IOException e) {
+      throw new HttpClientException(e);
+    } catch (RuntimeException e) {
+      this.request.abort();
+      throw new HttpClientException(e);
+    }
+
+    if (response.getStatusLine().getStatusCode() >= 500) {
+      throw new ODataServerErrorException(response.getStatusLine());
+    } else if (response.getStatusLine().getStatusCode() >= 400) {
+      try {
+        final HttpEntity httpEntity = response.getEntity();
+        if (httpEntity == null) {
+          throw new ODataClientErrorException(response.getStatusLine());
+        } else {
+          final boolean isXML = getAccept().indexOf("json") == -1;
+          Error error;
+
+          try {
+            error = odataClient.getReader().readError(httpEntity.getContent(), isXML);
+          } catch (IllegalArgumentException e) {
+            LOG.warn("Error deserializing error response", e);
+            error = getGenericError(
+                    response.getStatusLine().getStatusCode(),
+                    response.getStatusLine().getReasonPhrase(),
+                    isXML);
+          }
+
+          throw new ODataClientErrorException(response.getStatusLine(), error);
+        }
+      } catch (IOException e) {
+        throw new HttpClientException(
+                "Received '" + response.getStatusLine() + "' but could not extract error body", e);
+      }
+    }
+
+    return response;
+  }
+
+  /**
+   * Gets an empty response that can be initialized by a stream.
+   * <p>
+   * This method has to be used to build response items about a batch request.
+   *
+   * @param <V> ODataResppnse type.
+   * @return empty OData response instance.
+   */
+  @SuppressWarnings("unchecked")
+  public <V extends ODataResponse> V getResponseTemplate() {
+
+    for (Class<?> clazz : this.getClass().getDeclaredClasses()) {
+      if (ODataResponse.class.isAssignableFrom(clazz)) {
+        try {
+          final Constructor<?> constructor = clazz.getDeclaredConstructor(this.getClass());
+          constructor.setAccessible(true);
+          return (V) constructor.newInstance(this);
+        } catch (Exception e) {
+          LOG.error("Error retrieving response class template instance", e);
+        }
+      }
+    }
+
+    throw new IllegalStateException("No response class template has been found");
+  }
+
+  private Error getGenericError(final int code, final String errorMsg, final boolean isXML) {
+    final Error error;
+    if (isXML) {
+      error = new XMLErrorImpl();
+      final XMLErrorImpl.Message msg = new XMLErrorImpl.Message(
+              Collections.singletonMap("", (Object) errorMsg));
+
+      ((XMLErrorImpl) error).setMessage(msg);
+      ((XMLErrorImpl) error).setCode(String.valueOf(code));
+    } else {
+      error = new JSONErrorImpl();
+      final JSONErrorImpl.Message msg = new JSONErrorImpl.Message();
+      msg.setValue(errorMsg);
+
+      ((JSONErrorImpl) error).setMessage(msg);
+      ((JSONErrorImpl) error).setCode(String.valueOf(code));
+    }
+
+    return error;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractBatchRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractBatchRequestFactory.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractBatchRequestFactory.java
new file mode 100644
index 0000000..c92a243
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractBatchRequestFactory.java
@@ -0,0 +1,36 @@
+/**
+ * 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.communication.request.batch;
+
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.batch.BatchRequestFactory;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
+
+/**
+ * OData batch request factory class.
+ */
+public abstract class AbstractBatchRequestFactory implements BatchRequestFactory {
+
+  private static final long serialVersionUID = -3875283254713404483L;
+
+  protected final ODataClient client;
+
+  protected AbstractBatchRequestFactory(final ODataClient client) {
+    this.client = client;
+  }
+
+  @Override
+  public ODataBatchRequest getBatchRequest(final String serviceRoot) {
+    return new ODataBatchRequestImpl(client, client.getURIBuilder(serviceRoot).appendBatchSegment().build());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchRequestItem.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchRequestItem.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchRequestItem.java
new file mode 100644
index 0000000..e85ce36
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchRequestItem.java
@@ -0,0 +1,124 @@
+/*
+ * 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.communication.request.batch;
+
+import org.apache.olingo.client.api.ODataBatchConstants;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequestItem;
+import org.apache.olingo.client.core.communication.request.AbstractODataStreamer;
+
+/**
+ * Abstract representation of a batch request item.
+ */
+public abstract class AbstractODataBatchRequestItem extends AbstractODataStreamer
+        implements ODataBatchRequestItem {
+
+  /**
+   * Stream started check.
+   */
+  protected boolean hasStreamedSomething = false;
+
+  /**
+   * Stream open check.
+   */
+  private boolean open = false;
+
+  /**
+   * OData batch request.
+   */
+  protected ODataBatchRequest req;
+
+  /**
+   * Constructor.
+   *
+   * @param req OData batch request.
+   */
+  public AbstractODataBatchRequestItem(final ODataBatchRequest req) {
+    super(req.getOutputStream());
+    this.open = true;
+    this.req = req;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean isOpen() {
+    return open;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void close() {
+    closeItem();
+    open = false;
+  }
+
+  /**
+   * Stream the given request header.
+   * <p>
+   * Use this method to stream changeset items.
+   *
+   * @param request request to be batched.
+   * @param contentId changeset item id.
+   */
+  protected void streamRequestHeader(final ODataBatchableRequest request, final int contentId) {
+    //stream batch content type
+    stream(ODataBatchConstants.ITEM_CONTENT_TYPE_LINE.getBytes());
+    newLine();
+    stream(ODataBatchConstants.ITEM_TRANSFER_ENCODING_LINE.getBytes());
+    newLine();
+    stream((ODataBatchConstants.CHANGESET_CONTENT_ID_NAME + ":" + contentId).getBytes());
+    newLine();
+    newLine();
+  }
+
+  /**
+   * Stream the given request header.
+   *
+   * @param request request to be batched.
+   */
+  protected void streamRequestHeader(final ODataBatchableRequest request) {
+    //stream batch content type
+    stream(ODataBatchConstants.ITEM_CONTENT_TYPE_LINE.getBytes());
+    newLine();
+    stream(ODataBatchConstants.ITEM_TRANSFER_ENCODING_LINE.getBytes());
+    newLine();
+    newLine();
+
+    stream(request.toByteArray());
+    newLine();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean hasStreamedSomething() {
+    return hasStreamedSomething;
+  }
+
+  /**
+   * Closes the current item.
+   */
+  protected abstract void closeItem();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchResponseItem.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchResponseItem.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchResponseItem.java
new file mode 100644
index 0000000..b0a9ce9
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchResponseItem.java
@@ -0,0 +1,146 @@
+/*
+ * 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.communication.request.batch;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchLineIterator;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract representation of a response item about a batch request.
+ */
+public abstract class AbstractODataBatchResponseItem implements ODataBatchResponseItem {
+
+  /**
+   * Logger.
+   */
+  protected static final Logger LOG = LoggerFactory.getLogger(ODataBatchResponseItem.class);
+
+  /**
+   * Expected OData responses for the current batch response item.
+   */
+  protected final Map<String, ODataResponse> responses = new HashMap<String, ODataResponse>();
+
+  /**
+   * Expected OData responses iterator.
+   */
+  protected Iterator<ODataResponse> expectedItemsIterator;
+
+  /**
+   * Changeset controller. Gives more information about the type of batch item.
+   */
+  private final boolean changeset;
+
+  /**
+   * Batch response line iterator.
+   */
+  protected ODataBatchLineIterator batchLineIterator;
+
+  /**
+   * Batch boundary.
+   */
+  protected String boundary;
+
+  /**
+   * Gives information about the batch response item status.
+   */
+  protected boolean closed = false;
+
+  /**
+   * Constructor.
+   *
+   * @param isChangeset 'TRUE' if the current batch response item is a changeset.
+   */
+  public AbstractODataBatchResponseItem(boolean isChangeset) {
+    this.changeset = isChangeset;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public void addResponse(final String contentId, final ODataResponse res) {
+    if (closed) {
+      throw new IllegalStateException("Invalid batch item because explicitely closed");
+    }
+    responses.put(contentId, res);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public void initFromBatch(final ODataBatchLineIterator batchLineIterator, final String boundary) {
+    if (closed) {
+      throw new IllegalStateException("Invalid batch item because explicitely closed");
+    }
+    LOG.debug("Init from batch - boundary '{}'", boundary);
+    this.batchLineIterator = batchLineIterator;
+    this.boundary = boundary;
+  }
+
+  /**
+   * Gets response about the given contentId.
+   *
+   * @param contentId response identifier (a specific contentId in case of changeset item).
+   * @return ODataResponse corresponding to the given contentId.
+   */
+  protected ODataResponse getResponse(final String contentId) {
+    if (closed) {
+      throw new IllegalStateException("Invalid batch item because explicitely closed");
+    }
+    return responses.get(contentId);
+  }
+
+  /**
+   * Gets OData responses iterator.
+   *
+   * @return OData responses iterator.
+   */
+  protected Iterator<ODataResponse> getResponseIterator() {
+    if (closed) {
+      throw new IllegalStateException("Invalid batch item because explicitely closed");
+    }
+    return responses.values().iterator();
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public final boolean isChangeset() {
+    return changeset;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public void close() {
+    for (ODataResponse response : responses.values()) {
+      response.close();
+    }
+    closed = true;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchController.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchController.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchController.java
new file mode 100644
index 0000000..c2377d8
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchController.java
@@ -0,0 +1,89 @@
+/*
+ * 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.communication.request.batch;
+
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchLineIterator;
+
+/**
+ * Utility class used to communicate batch info.
+ */
+public class ODataBatchController {
+
+  /**
+   * Batch validity.
+   */
+  private boolean validBatch = true;
+
+  /**
+   * Batch boundary.
+   */
+  private final String boundary;
+
+  /**
+   * Batch line iterator.
+   */
+  private final ODataBatchLineIterator batchLineIterator;
+
+  /**
+   * Constructor.
+   *
+   * @param batchLineIterator batch line iterator.
+   * @param boundary batch boundary.
+   */
+  public ODataBatchController(final ODataBatchLineIterator batchLineIterator, final String boundary) {
+    this.batchLineIterator = batchLineIterator;
+    this.boundary = boundary;
+  }
+
+  /**
+   * Checks if batch is valid.
+   *
+   * @return batch validity.
+   */
+  public boolean isValidBatch() {
+    return validBatch;
+  }
+
+  /**
+   * Sets batch validity.
+   *
+   * @param validBatch validity.
+   */
+  public void setValidBatch(final boolean validBatch) {
+    this.validBatch = validBatch;
+  }
+
+  /**
+   * Gest batch boundary.
+   *
+   * @return batch boundary.
+   */
+  public String getBoundary() {
+    return boundary;
+  }
+
+  /**
+   * Gest batch line iterator.
+   *
+   * @return batch line iterator.
+   */
+  public ODataBatchLineIterator getBatchLineIterator() {
+    return batchLineIterator;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchLineIteratorImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchLineIteratorImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchLineIteratorImpl.java
new file mode 100644
index 0000000..34d621a
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchLineIteratorImpl.java
@@ -0,0 +1,93 @@
+/*
+ * 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.communication.request.batch;
+
+import org.apache.commons.io.LineIterator;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchLineIterator;
+
+/**
+ * Batch line iterator class.
+ */
+public class ODataBatchLineIteratorImpl implements ODataBatchLineIterator {
+
+  /**
+   * Stream line iterator.
+   */
+  private final LineIterator batchLineIterator;
+
+  /**
+   * Last cached line.
+   */
+  private String current;
+
+  /**
+   * Constructor.
+   *
+   * @param batchLineIterator stream line iterator.
+   */
+  public ODataBatchLineIteratorImpl(final LineIterator batchLineIterator) {
+    this.batchLineIterator = batchLineIterator;
+    this.current = null;
+  }
+
+  /**
+   * Checks if batch has next line.
+   *
+   * @return 'TRUE' if has next line; 'FALSE' otherwise.
+   */
+  @Override
+  public boolean hasNext() {
+    return batchLineIterator.hasNext();
+  }
+
+  /**
+   * Gets next line.
+   *
+   * @return next line.
+   */
+  @Override
+  public String next() {
+    return nextLine();
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public String nextLine() {
+    current = batchLineIterator.nextLine();
+    return current;
+  }
+
+  /**
+   * Unsupported operation.
+   */
+  @Override
+  public void remove() {
+    throw new UnsupportedOperationException("Unsupported operation");
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public String getCurrent() {
+    return current;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchRequestImpl.java
new file mode 100644
index 0000000..054f467
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchRequestImpl.java
@@ -0,0 +1,255 @@
+/*
+ * 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.communication.request.batch;
+
+import java.io.IOException;
+import java.io.PipedOutputStream;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.ODataBatchConstants;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.batch.BatchStreamManager;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequestItem;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchResponseItem;
+import org.apache.olingo.client.api.communication.request.batch.ODataChangeset;
+import org.apache.olingo.client.api.communication.request.batch.ODataRetrieve;
+import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.communication.request.AbstractODataStreamManager;
+import org.apache.olingo.client.core.communication.request.streamed.AbstractODataStreamedRequest;
+import org.apache.olingo.client.core.communication.response.ODataResponseImpl;
+import org.apache.olingo.client.core.communication.response.batch.ODataBatchResponseManager;
+
+/**
+ * This class implements a batch request.
+ */
+public class ODataBatchRequestImpl extends AbstractODataStreamedRequest<ODataBatchResponse, BatchStreamManager>
+        implements ODataBatchRequest {
+
+  /**
+   * Batch request boundary.
+   */
+  private final String boundary;
+
+  /**
+   * Expected batch response items.
+   */
+  private final List<ODataBatchResponseItem> expectedResItems = new ArrayList<ODataBatchResponseItem>();
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param uri batch request URI (http://serviceRoot/$batch)
+   */
+  ODataBatchRequestImpl(final ODataClient odataClient, final URI uri) {
+    super(odataClient, HttpMethod.POST, uri);
+
+    // create a random UUID value for boundary
+    boundary = "batch_" + UUID.randomUUID().toString();
+
+    // specify the contentType header
+    setContentType(ODataBatchConstants.MULTIPART_CONTENT_TYPE + ";" + ODataBatchConstants.BOUNDARY + "=" + boundary);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected BatchStreamManager getStreamManager() {
+    if (streamManager == null) {
+      streamManager = new BatchStreamManagerImpl(this);
+    }
+    return (BatchStreamManager) streamManager;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public PipedOutputStream getOutputStream() {
+    return getStreamManager().getBodyStreamWriter();
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataBatchRequestImpl rawAppend(final byte[] toBeStreamed) throws IOException {
+    getStreamManager().getBodyStreamWriter().write(toBeStreamed);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataBatchRequestImpl rawAppend(final byte[] toBeStreamed, int off, int len) throws IOException {
+    getStreamManager().getBodyStreamWriter().write(toBeStreamed, off, len);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc}
+   * <p>
+   * This operation is unsupported by a batch request.
+   */
+  @Override
+  public void batch(ODataBatchRequest req) {
+    throw new UnsupportedOperationException("A batch request is not batchable");
+  }
+
+  /**
+   * This class implements a response to a batch request.
+   *
+   * @see com.msopentech.odatajclient.engine.communication.request.ODataBatchRequest
+   */
+  private class ODataBatchResponseImpl extends ODataResponseImpl implements ODataBatchResponse {
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataBatchResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Iterator<ODataBatchResponseItem> getBody() {
+      return new ODataBatchResponseManager(this, expectedResItems);
+    }
+  }
+
+  /**
+   * Batch request payload management.
+   */
+  public class BatchStreamManagerImpl extends AbstractODataStreamManager<ODataBatchResponse> {
+
+    /**
+     * Batch request current item.
+     */
+    private ODataBatchRequestItem currentItem = null;
+
+    /**
+     * batch request reference.
+     */
+    private final ODataBatchRequest req;
+
+    /**
+     * Private constructor.
+     *
+     * @param req batch request reference.
+     */
+    private BatchStreamManagerImpl(final ODataBatchRequest req) {
+      super(ODataBatchRequestImpl.this.futureWrapper);
+      this.req = req;
+    }
+
+    /**
+     * Gets a changeset batch item instance. A changeset can be submitted embedded into a batch request only.
+     *
+     * @return ODataChangeset instance.
+     */
+    public ODataChangeset addChangeset() {
+      closeCurrentItem();
+
+      // stream dash boundary
+      streamDashBoundary();
+
+      final ODataChangesetResponseItem expectedResItem = new ODataChangesetResponseItem();
+      expectedResItems.add(expectedResItem);
+
+      currentItem = new ODataChangesetImpl(req, expectedResItem);
+
+      return (ODataChangeset) currentItem;
+    }
+
+    /**
+     * Gets a retrieve batch item instance. A retrieve item can be submitted embedded into a batch request only.
+     *
+     * @return ODataRetrieve instance.
+     */
+    public ODataRetrieve addRetrieve() {
+      closeCurrentItem();
+
+      // stream dash boundary
+      streamDashBoundary();
+
+      final ODataRetrieveResponseItem expectedResItem = new ODataRetrieveResponseItem();
+      currentItem = new ODataRetrieveImpl(req, expectedResItem);
+
+      expectedResItems.add(expectedResItem);
+
+      return (ODataRetrieve) currentItem;
+    }
+
+    /**
+     * Close the current streamed item.
+     */
+    private void closeCurrentItem() {
+      if (currentItem != null) {
+        currentItem.close();
+      }
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    protected ODataBatchResponse getResponse(final long timeout, final TimeUnit unit) {
+      closeCurrentItem();
+      streamCloseDelimiter();
+      finalizeBody();
+      return new ODataBatchResponseImpl(httpClient, getHttpResponse(timeout, unit));
+    }
+
+    /**
+     * Streams dash boundary.
+     */
+    private void streamDashBoundary() {
+      // preamble
+      newLine();
+
+      // stream batch-boundary
+      stream(("--" + boundary).getBytes());
+      newLine();
+    }
+
+    /**
+     * Streams close delimiter.
+     */
+    private void streamCloseDelimiter() {
+      // stream close-delimiter
+      newLine();
+      stream(("--" + boundary + "--").getBytes());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchUtilities.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchUtilities.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchUtilities.java
new file mode 100644
index 0000000..a33f7cb
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataBatchUtilities.java
@@ -0,0 +1,329 @@
+/*
+ * 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.communication.request.batch;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.AbstractMap;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.LineIterator;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.client.api.ODataBatchConstants;
+import org.apache.olingo.client.api.communication.header.HeaderName;
+import org.apache.olingo.client.api.communication.request.ODataStreamer;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchLineIterator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility class for batch requests and responses.
+ */
+public class ODataBatchUtilities {
+
+  public static enum BatchItemType {
+
+    NONE,
+    CHANGESET,
+    RETRIEVE
+
+  }
+  /**
+   * Logger.
+   */
+  private static final Logger LOG = LoggerFactory.getLogger(ODataBatchUtilities.class);
+
+  /**
+   * Response line syntax.
+   */
+  private static final Pattern RESPONSE_PATTERN =
+          Pattern.compile("HTTP/\\d\\.\\d (\\d+) (.*)", Pattern.CASE_INSENSITIVE);
+
+  /**
+   * Reads batch part taking source and delimiter (boundary) from given batch controller.
+   * <p>
+   * Usually used to consume/discard useless lines.
+   *
+   * @param batchController batch controller.
+   * @param checkCurrent if 'TRUE' the current line will be included into the delimiter verification.
+   * @return latest read line.
+   */
+  public static String readBatchPart(final ODataBatchController batchController, final boolean checkCurrent) {
+    return readBatchPart(batchController, null, -1, checkCurrent);
+  }
+
+  /**
+   * Reads the given number of line from the given batch wrapped into the batch controller.
+   * <p>
+   * Usually used to consume/discard useless lines.
+   *
+   * @param batchController batch controller.
+   * @param count number of batch line to be read.
+   * @return latest read line.
+   */
+  public static String readBatchPart(final ODataBatchController batchController, final int count) {
+    return readBatchPart(batchController, null, count, true);
+  }
+
+  /**
+   * Reads batch part taking source and delimiter (boundary) from given batch controller.
+   * <p>
+   * Usually used to read an entire batch part.
+   *
+   * @param batchController batch controller.
+   * @param os destination stream of batch part (null to discard).
+   * @param checkCurrent if 'TRUE' the current line will be included into the delimiter verification.
+   * @return latest read line.
+   */
+  public static String readBatchPart(
+          final ODataBatchController controller, final OutputStream os, final boolean checkCurrent) {
+
+    return readBatchPart(controller, os, -1, checkCurrent);
+  }
+
+  /**
+   * Reads batch part taking source and delimiter (boundary) from given batch controller.
+   * <p>
+   * Usually used to read an entire batch part.
+   *
+   * @param batchController batch controller.
+   * @param os destination stream of batch part (null to discard).
+   * @param count number of batch line to be read.
+   * @param checkCurrent if 'TRUE' the current line will be included into the delimiter verification.
+   * @return latest read line.
+   */
+  public static String readBatchPart(
+          final ODataBatchController controller, final OutputStream os, final int count, final boolean checkCurrent) {
+
+    String currentLine;
+
+    synchronized (controller.getBatchLineIterator()) {
+      currentLine = checkCurrent ? controller.getBatchLineIterator().getCurrent() : null;
+
+      if (count < 0) {
+        try {
+
+          boolean notEndLine = isNotEndLine(controller, currentLine);
+
+          while (controller.isValidBatch() && notEndLine && controller.getBatchLineIterator().hasNext()) {
+
+            currentLine = controller.getBatchLineIterator().nextLine();
+            LOG.debug("Read line '{}' (end-line '{}')", currentLine, controller.getBoundary());
+
+            notEndLine = isNotEndLine(controller, currentLine);
+
+            if (notEndLine && os != null) {
+              os.write(currentLine.getBytes(Constants.UTF8));
+              os.write(ODataStreamer.CRLF);
+            }
+          }
+
+        } catch (IOException e) {
+          LOG.error("Error reading batch part", e);
+          throw new IllegalStateException(e);
+        }
+
+      } else {
+        for (int i = 0;
+                controller.isValidBatch() && controller.getBatchLineIterator().hasNext() && i < count; i++) {
+          currentLine = controller.getBatchLineIterator().nextLine();
+        }
+      }
+    }
+
+    return currentLine;
+  }
+
+  /**
+   * Reads headers from the batch starting from the given position.
+   *
+   * @param iterator batch iterator.
+   * @return Map of header name in header values.
+   */
+  public static Map<String, Collection<String>> readHeaders(final ODataBatchLineIterator iterator) {
+    final Map<String, Collection<String>> target =
+            new TreeMap<String, Collection<String>>(String.CASE_INSENSITIVE_ORDER);
+
+    readHeaders(iterator, target);
+    return target;
+  }
+
+  /**
+   * Reads headers from the batch starting from the given position.
+   * <p>
+   * Retrieved headers will be added to the map given by target parameter.
+   *
+   * @param iterator batch iterator.
+   * @param target destination of the retrieved headers.
+   */
+  public static void readHeaders(
+          final ODataBatchLineIterator iterator, final Map<String, Collection<String>> target) {
+
+    try {
+      final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      readBatchPart(new ODataBatchController(iterator, null), baos, true);
+
+      final LineIterator headers = IOUtils.lineIterator(new ByteArrayInputStream(baos.toByteArray()), Constants.UTF8);
+      while (headers.hasNext()) {
+        final String line = headers.nextLine().trim();
+        if (StringUtils.isNotBlank(line)) {
+          addHeaderLine(line, target);
+        }
+      }
+    } catch (Exception e) {
+      LOG.error("Error retrieving headers", e);
+      throw new IllegalStateException(e);
+    }
+  }
+
+  /**
+   * Parses and adds the given header line to the given target map.
+   *
+   * @param headerLine header line to be added.
+   * @param targetMap target map.
+   */
+  public static void addHeaderLine(final String headerLine, final Map<String, Collection<String>> targetMap) {
+    final int sep = headerLine.indexOf(':');
+    if (sep > 0 && sep < headerLine.length() - 1) {
+      final String key = headerLine.substring(0, sep).trim();
+      final Collection<String> value;
+      if (targetMap.containsKey(key)) {
+        value = targetMap.get(key);
+      } else {
+        value = new HashSet<String>();
+        targetMap.put(key, value);
+      }
+      value.add(headerLine.substring(sep + 1, headerLine.length()).trim());
+    }
+  }
+
+  /**
+   * Retrieved batch boundary from the given content-type header values.
+   *
+   * @param contentType content-types.
+   * @return batch boundary.
+   */
+  public static String getBoundaryFromHeader(final Collection<String> contentType) {
+    final String boundaryKey = ODataBatchConstants.BOUNDARY + "=";
+
+    if (contentType == null || contentType.isEmpty() || !contentType.toString().contains(boundaryKey)) {
+      throw new IllegalArgumentException("Invalid content type");
+    }
+
+    final String headerValue = contentType.toString();
+
+    final int start = headerValue.indexOf(boundaryKey) + boundaryKey.length();
+    int end = headerValue.indexOf(';', start);
+
+    if (end < 0) {
+      end = headerValue.indexOf(']', start);
+    }
+
+    final String res = headerValue.substring(start, end);
+    return res.startsWith("--") ? res : "--" + res;
+  }
+
+  /**
+   * Retrieves response line from the given position.
+   *
+   * @param iterator batch iterator.
+   * @return retrieved response line.
+   */
+  public static Map.Entry<Integer, String> readResponseLine(final ODataBatchLineIterator iterator) {
+    final String line = readBatchPart(new ODataBatchController(iterator, null), 1);
+    LOG.debug("Response line '{}'", line);
+
+    final Matcher matcher = RESPONSE_PATTERN.matcher(line.trim());
+
+    if (matcher.matches()) {
+      return new AbstractMap.SimpleEntry<Integer, String>(Integer.valueOf(matcher.group(1)), matcher.group(2));
+    }
+
+    throw new IllegalArgumentException("Invalid response line '" + line + "'");
+  }
+
+  /**
+   * Retrieves headers of the next batch item.
+   *
+   * @param iterator batch line iterator.
+   * @param boundary batch boundary.
+   * @return batch item headers.
+   */
+  public static Map<String, Collection<String>> nextItemHeaders(
+          final ODataBatchLineIterator iterator, final String boundary) {
+
+    final Map<String, Collection<String>> headers =
+            new TreeMap<String, Collection<String>>(String.CASE_INSENSITIVE_ORDER);
+
+    final String line = ODataBatchUtilities.readBatchPart(new ODataBatchController(iterator, boundary), true);
+
+    if (line != null && line.trim().equals(boundary)) {
+      ODataBatchUtilities.readHeaders(iterator, headers);
+    }
+
+    LOG.debug("Retrieved batch item headers {}", headers);
+    return headers;
+  }
+
+  /**
+   * Retrieves item type from item headers.
+   *
+   * @param headers batch item headers.
+   * @return batch item type.
+   */
+  public static BatchItemType getItemType(final Map<String, Collection<String>> headers) {
+
+    final BatchItemType nextItemType;
+
+    final String contentType = headers.containsKey(HeaderName.contentType.toString())
+            ? headers.get(HeaderName.contentType.toString()).toString() : StringUtils.EMPTY;
+
+    if (contentType.contains(ODataBatchConstants.MULTIPART_CONTENT_TYPE)) {
+      nextItemType = BatchItemType.CHANGESET;
+    } else if (contentType.contains(ODataBatchConstants.ITEM_CONTENT_TYPE)) {
+      nextItemType = BatchItemType.RETRIEVE;
+    } else {
+      nextItemType = BatchItemType.NONE;
+    }
+
+    LOG.debug("Retrieved next item type {}", nextItemType);
+    return nextItemType;
+  }
+
+  /**
+   * Checks if the given line is the expected end-line.
+   *
+   * @param controller batch controller.
+   * @param line line to be checked.
+   * @return 'TRUE' if the line is not the end-line; 'FALSE' otherwise.
+   */
+  private static boolean isNotEndLine(final ODataBatchController controller, final String line) {
+    return line == null
+            || (StringUtils.isBlank(controller.getBoundary()) && StringUtils.isNotBlank(line))
+            || (StringUtils.isNotBlank(controller.getBoundary()) && !line.startsWith(controller.getBoundary()));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataChangesetImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataChangesetImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataChangesetImpl.java
new file mode 100644
index 0000000..4bb486e
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataChangesetImpl.java
@@ -0,0 +1,128 @@
+/*
+ * 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.communication.request.batch;
+
+import java.util.UUID;
+import org.apache.olingo.client.api.ODataBatchConstants;
+import org.apache.olingo.client.api.communication.header.HeaderName;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
+import org.apache.olingo.client.api.communication.request.batch.ODataChangeset;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.communication.request.ODataRequestImpl;
+
+/**
+ * Changeset wrapper for the corresponding batch item.
+ */
+public class ODataChangesetImpl extends AbstractODataBatchRequestItem
+        implements ODataChangeset {
+
+  /**
+   * ContentId.
+   */
+  private int contentId = 0;
+
+  /**
+   * Changeset boundary.
+   */
+  private final String boundary;
+
+  /**
+   * Expected changeset response items.
+   */
+  private final ODataChangesetResponseItem expectedResItem;
+
+  /**
+   * Constructor.
+   *
+   * @param req batch request.
+   * @param expectedResItem expected OData response items.
+   */
+  ODataChangesetImpl(final ODataBatchRequest req, final ODataChangesetResponseItem expectedResItem) {
+    super(req);
+    this.expectedResItem = expectedResItem;
+
+    // create a random UUID value for boundary
+    boundary = "changeset_" + UUID.randomUUID().toString();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public int getLastContentId() {
+    return contentId;
+  }
+
+  /**
+   * Close changeset item an send changeset request footer.
+   */
+  @Override
+  protected void closeItem() {
+    // stream close-delimiter
+    if (hasStreamedSomething) {
+      newLine();
+      stream(("--" + boundary + "--").getBytes());
+      newLine();
+      newLine();
+    }
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataChangeset addRequest(final ODataBatchableRequest request) {
+    if (!isOpen()) {
+      throw new IllegalStateException("Current batch item is closed");
+    }
+
+    if (request.getMethod() == HttpMethod.GET) {
+      throw new IllegalArgumentException("Invalid request. GET method not allowed in changeset");
+    }
+
+    if (!hasStreamedSomething) {
+      stream((HeaderName.contentType.toString() + ": "
+              + ODataBatchConstants.MULTIPART_CONTENT_TYPE + ";boundary=" + boundary).getBytes());
+
+      newLine();
+      newLine();
+
+      hasStreamedSomething = true;
+    }
+
+    contentId++;
+
+    // preamble
+    newLine();
+
+    // stream batch-boundary
+    stream(("--" + boundary).getBytes());
+    newLine();
+
+    // stream the request
+    streamRequestHeader(request, contentId);
+
+    request.batch(req, String.valueOf(contentId));
+
+    // add request to the list
+    expectedResItem.addResponse(String.valueOf(contentId), ((ODataRequestImpl) request).getResponseTemplate());
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataChangesetResponseItem.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataChangesetResponseItem.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataChangesetResponseItem.java
new file mode 100644
index 0000000..4a077b5
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataChangesetResponseItem.java
@@ -0,0 +1,129 @@
+/*
+ * 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.communication.request.batch;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import org.apache.olingo.client.api.ODataBatchConstants;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+
+/**
+ * Changeset wrapper for the corresponding batch item.
+ */
+public class ODataChangesetResponseItem extends AbstractODataBatchResponseItem {
+
+  /**
+   * Last cached OData response.
+   */
+  private ODataResponse current = null;
+
+  /**
+   * Constructor.
+   */
+  public ODataChangesetResponseItem() {
+    super(true);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public boolean hasNext() {
+    if (closed) {
+      throw new IllegalStateException("Invalid request - the item has been closed");
+    }
+
+    if (expectedItemsIterator == null) {
+      expectedItemsIterator = responses.values().iterator();
+    }
+
+    return expectedItemsIterator.hasNext();
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataResponse next() {
+
+    if (current != null) {
+      current.close();
+    }
+
+    if (closed) {
+      throw new IllegalStateException("Invalid request - the item has been closed");
+    }
+
+    if (hasNext()) {
+      // consume item for condition above (like a counter ...)
+      expectedItemsIterator.next();
+    } else {
+      throw new NoSuchElementException("No item found");
+    }
+
+    final Map<String, Collection<String>> nextItemHeaders =
+            ODataBatchUtilities.nextItemHeaders(batchLineIterator, boundary);
+
+    if (nextItemHeaders.isEmpty()) {
+      throw new IllegalStateException("Expected item not found");
+    }
+
+    final Map.Entry<Integer, String> responseLine = ODataBatchUtilities.readResponseLine(batchLineIterator);
+    LOG.debug("Retrieved item response {}", responseLine);
+
+    final Map<String, Collection<String>> headers = ODataBatchUtilities.readHeaders(batchLineIterator);
+    LOG.debug("Retrieved item headers {}", headers);
+
+    Collection<String> contentId = nextItemHeaders.get(ODataBatchConstants.CHANGESET_CONTENT_ID_NAME);
+
+    if (contentId == null || contentId.isEmpty()) {
+      contentId = headers.get(ODataBatchConstants.CHANGESET_CONTENT_ID_NAME);
+
+      if (contentId == null || contentId.isEmpty()) {
+        throw new IllegalStateException("Content-ID is missing");
+      }
+    }
+
+    current = getResponse(contentId.iterator().next());
+
+    if (current == null) {
+      throw new IllegalStateException("Unexpected '" + contentId + "' item found");
+    }
+
+    current.initFromBatch(responseLine, headers, batchLineIterator, boundary);
+
+    if (current.getStatusCode() >= 400) {
+      // found error .... consume expeted items
+      while (expectedItemsIterator.hasNext()) {
+        expectedItemsIterator.next();
+      }
+    }
+
+    return current;
+  }
+
+  /**
+   * Unsupported operation.
+   */
+  @Override
+  public void remove() {
+    throw new UnsupportedOperationException("Not supported operation.");
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataRetrieveImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataRetrieveImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataRetrieveImpl.java
new file mode 100644
index 0000000..fb348a4
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataRetrieveImpl.java
@@ -0,0 +1,81 @@
+/*
+ * 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.communication.request.batch;
+
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
+import org.apache.olingo.client.api.communication.request.batch.ODataRetrieve;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.communication.request.ODataRequestImpl;
+
+/**
+ * Retrieve request wrapper for the corresponding batch item.
+ */
+public class ODataRetrieveImpl extends AbstractODataBatchRequestItem
+        implements ODataRetrieve {
+
+  private final ODataRetrieveResponseItem expectedResItem;
+
+  /**
+   * Constructor.
+   *
+   * @param req batch request.
+   * @param expectedResItem expected batch response item.
+   */
+  ODataRetrieveImpl(final ODataBatchRequest req, final ODataRetrieveResponseItem expectedResItem) {
+    super(req);
+    this.expectedResItem = expectedResItem;
+  }
+
+  /**
+   * Close item.
+   */
+  @Override
+  protected void closeItem() {
+    // nop
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataRetrieve setRequest(final ODataBatchableRequest request) {
+    if (!isOpen()) {
+      throw new IllegalStateException("Current batch item is closed");
+    }
+
+    if (((ODataRequestImpl) request).getMethod() != HttpMethod.GET) {
+      throw new IllegalArgumentException("Invalid request. Only GET method is allowed");
+    }
+
+    hasStreamedSomething = true;
+
+    // stream the request
+    streamRequestHeader(request);
+
+    // close before in order to avoid any further setRequest calls.
+    close();
+
+    // add request to the list
+    expectedResItem.addResponse(
+            ODataRetrieveResponseItem.RETRIEVE_CONTENT_ID, ((ODataRequestImpl) request).getResponseTemplate());
+
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataRetrieveResponseItem.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataRetrieveResponseItem.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataRetrieveResponseItem.java
new file mode 100644
index 0000000..4a30e2e
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/ODataRetrieveResponseItem.java
@@ -0,0 +1,85 @@
+/*
+ * 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.communication.request.batch;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+
+/**
+ * Retrieve response wrapper for the corresponding batch item.
+ */
+public class ODataRetrieveResponseItem extends AbstractODataBatchResponseItem {
+
+  public static final String RETRIEVE_CONTENT_ID = "__RETRIEVE__";
+
+  /**
+   * Constructor.
+   */
+  public ODataRetrieveResponseItem() {
+    super(false);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public boolean hasNext() {
+    if (closed) {
+      throw new IllegalStateException("Invalid request - the item has been closed");
+    }
+
+    if (expectedItemsIterator == null) {
+      expectedItemsIterator = responses.values().iterator();
+    }
+
+    return expectedItemsIterator.hasNext();
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataResponse next() {
+    if (closed) {
+      throw new IllegalStateException("Invalid request - the item has been closed");
+    }
+
+    if (!hasNext()) {
+      throw new NoSuchElementException("No item found");
+    }
+
+    final Map.Entry<Integer, String> responseLine = ODataBatchUtilities.readResponseLine(batchLineIterator);
+    LOG.debug("Retrieved item response {}", responseLine);
+
+    final Map<String, Collection<String>> headers = ODataBatchUtilities.readHeaders(batchLineIterator);
+    LOG.debug("Retrieved item headers {}", headers);
+
+    return expectedItemsIterator.next().initFromBatch(responseLine, headers, batchLineIterator, boundary);
+  }
+
+  /**
+   * Unsupported operation.
+   */
+  @Override
+  public void remove() {
+    throw new UnsupportedOperationException("Operation not supported.");
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/V3BatchRequestFactoryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/V3BatchRequestFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/V3BatchRequestFactoryImpl.java
new file mode 100644
index 0000000..865de64
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/V3BatchRequestFactoryImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.communication.request.batch;
+
+import org.apache.olingo.client.api.ODataV3Client;
+import org.apache.olingo.client.api.communication.request.batch.V3BatchRequestFactory;
+
+public class V3BatchRequestFactoryImpl extends AbstractBatchRequestFactory
+        implements V3BatchRequestFactory {
+
+  private static final long serialVersionUID = -6271567229804128570L;
+
+  public V3BatchRequestFactoryImpl(final ODataV3Client client) {
+    super(client);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/V4BatchRequestFactoryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/V4BatchRequestFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/V4BatchRequestFactoryImpl.java
new file mode 100644
index 0000000..0e61d4c
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/V4BatchRequestFactoryImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.communication.request.batch;
+
+import org.apache.olingo.client.api.ODataV4Client;
+import org.apache.olingo.client.api.communication.request.batch.V4BatchRequestFactory;
+
+public class V4BatchRequestFactoryImpl extends AbstractBatchRequestFactory
+        implements V4BatchRequestFactory {
+
+  private static final long serialVersionUID = 788349446729208639L;
+
+  public V4BatchRequestFactoryImpl(final ODataV4Client client) {
+    super(client);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/AbstractCUDRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/AbstractCUDRequestFactory.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/AbstractCUDRequestFactory.java
new file mode 100644
index 0000000..b5128e6
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/AbstractCUDRequestFactory.java
@@ -0,0 +1,197 @@
+/*
+ * 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.communication.request.cud;
+
+import java.net.URI;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.UpdateType;
+import org.apache.olingo.client.api.communication.request.cud.CUDRequestFactory;
+import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
+import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest;
+import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
+import org.apache.olingo.client.api.communication.request.cud.ODataLinkCreateRequest;
+import org.apache.olingo.client.api.communication.request.cud.ODataLinkUpdateRequest;
+import org.apache.olingo.client.api.communication.request.cud.ODataPropertyUpdateRequest;
+import org.apache.olingo.client.api.communication.request.cud.ODataValueUpdateRequest;
+import org.apache.olingo.client.api.domain.ODataEntity;
+import org.apache.olingo.client.api.domain.ODataLink;
+import org.apache.olingo.client.api.domain.ODataPrimitiveValue;
+import org.apache.olingo.client.api.domain.ODataProperty;
+import org.apache.olingo.client.api.http.HttpMethod;
+
+public abstract class AbstractCUDRequestFactory implements CUDRequestFactory {
+
+  private static final long serialVersionUID = -2723641791198745990L;
+
+  protected final ODataClient client;
+
+  protected AbstractCUDRequestFactory(final ODataClient client) {
+    this.client = client;
+  }
+
+  @Override
+  public ODataEntityCreateRequest getEntityCreateRequest(final URI targetURI, final ODataEntity entity) {
+    return new ODataEntityCreateRequestImpl(client, targetURI, entity);
+  }
+
+  @Override
+  public ODataEntityUpdateRequest getEntityUpdateRequest(
+          final URI targetURI, final UpdateType type, final ODataEntity changes) {
+
+    final ODataEntityUpdateRequest req;
+
+    if (client.getConfiguration().isUseXHTTPMethod()) {
+      req = new ODataEntityUpdateRequestImpl(client, HttpMethod.POST, targetURI, changes);
+      req.setXHTTPMethod(type.getMethod().name());
+    } else {
+      req = new ODataEntityUpdateRequestImpl(client, type.getMethod(), targetURI, changes);
+    }
+
+    return req;
+  }
+
+  @Override
+  public ODataEntityUpdateRequest getEntityUpdateRequest(final UpdateType type, final ODataEntity entity) {
+    if (entity.getEditLink() == null) {
+      throw new IllegalArgumentException("No edit link found");
+    }
+
+    final ODataEntityUpdateRequest req;
+
+    if (client.getConfiguration().isUseXHTTPMethod()) {
+      req = new ODataEntityUpdateRequestImpl(client, HttpMethod.POST, entity.getEditLink(), entity);
+      req.setXHTTPMethod(type.getMethod().name());
+    } else {
+      req = new ODataEntityUpdateRequestImpl(client, type.getMethod(), entity.getEditLink(), entity);
+    }
+
+    return req;
+  }
+
+  @Override
+  public ODataValueUpdateRequest getValueUpdateRequest(
+          final URI targetURI, final UpdateType type, final ODataPrimitiveValue value) {
+
+    final ODataValueUpdateRequest req;
+
+    if (client.getConfiguration().isUseXHTTPMethod()) {
+      req = new ODataValueUpdateRequestImpl(client, HttpMethod.POST, targetURI, value);
+      req.setXHTTPMethod(type.getMethod().name());
+    } else {
+      req = new ODataValueUpdateRequestImpl(client, type.getMethod(), targetURI, value);
+    }
+
+    return req;
+  }
+
+  @Override
+  public ODataPropertyUpdateRequest getPropertyPrimitiveValueUpdateRequest(
+          final URI targetURI, final ODataProperty property) {
+
+    if (!property.hasPrimitiveValue()) {
+      throw new IllegalArgumentException("A primitive value is required");
+    }
+
+    final ODataPropertyUpdateRequest req;
+
+    if (client.getConfiguration().isUseXHTTPMethod()) {
+      req = new ODataPropertyUpdateRequestImpl(client, HttpMethod.POST, targetURI, property);
+      req.setXHTTPMethod(HttpMethod.PUT.name());
+    } else {
+      req = new ODataPropertyUpdateRequestImpl(client, HttpMethod.PUT, targetURI, property);
+    }
+
+    return req;
+  }
+
+  @Override
+  public ODataPropertyUpdateRequest getPropertyComplexValueUpdateRequest(
+          final URI targetURI, final UpdateType type, final ODataProperty property) {
+
+    if (!property.hasComplexValue()) {
+      throw new IllegalArgumentException("A complex value is required");
+    }
+
+    final ODataPropertyUpdateRequest req;
+
+    if (client.getConfiguration().isUseXHTTPMethod()) {
+      req = new ODataPropertyUpdateRequestImpl(client, HttpMethod.POST, targetURI, property);
+      req.setXHTTPMethod(type.getMethod().name());
+    } else {
+      req = new ODataPropertyUpdateRequestImpl(client, type.getMethod(), targetURI, property);
+    }
+
+    return req;
+  }
+
+  @Override
+  public ODataPropertyUpdateRequest getPropertyCollectionValueUpdateRequest(
+          final URI targetURI, final ODataProperty property) {
+
+    if (!property.hasCollectionValue()) {
+      throw new IllegalArgumentException("A collection value is required");
+    }
+
+    final ODataPropertyUpdateRequest req;
+
+    if (client.getConfiguration().isUseXHTTPMethod()) {
+      req = new ODataPropertyUpdateRequestImpl(client, HttpMethod.POST, targetURI, property);
+      req.setXHTTPMethod(HttpMethod.PUT.name());
+    } else {
+      req = new ODataPropertyUpdateRequestImpl(client, HttpMethod.PUT, targetURI, property);
+    }
+
+    return req;
+  }
+
+  @Override
+  public ODataLinkCreateRequest getLinkCreateRequest(final URI targetURI, final ODataLink link) {
+    return new ODataLinkCreateRequestImpl(client, targetURI, link);
+  }
+
+  @Override
+  public ODataLinkUpdateRequest getLinkUpdateRequest(
+          final URI targetURI, final UpdateType type, final ODataLink link) {
+
+    final ODataLinkUpdateRequest req;
+
+    if (client.getConfiguration().isUseXHTTPMethod()) {
+      req = new ODataLinkUpdateRequestImpl(client, HttpMethod.POST, targetURI, link);
+      req.setXHTTPMethod(type.getMethod().name());
+    } else {
+      req = new ODataLinkUpdateRequestImpl(client, type.getMethod(), targetURI, link);
+    }
+
+    return req;
+  }
+
+  @Override
+  public ODataDeleteRequest getDeleteRequest(final URI targetURI) {
+    final ODataDeleteRequest req;
+
+    if (client.getConfiguration().isUseXHTTPMethod()) {
+      req = new ODataDeleteRequestImpl(client, HttpMethod.POST, targetURI);
+      req.setXHTTPMethod(HttpMethod.DELETE.name());
+    } else {
+      req = new ODataDeleteRequestImpl(client, HttpMethod.DELETE, targetURI);
+    }
+
+    return req;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataDeleteRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataDeleteRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataDeleteRequestImpl.java
new file mode 100644
index 0000000..3010867
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataDeleteRequestImpl.java
@@ -0,0 +1,93 @@
+/*
+ * 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.communication.request.cud;
+
+import java.io.InputStream;
+import java.net.URI;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+import org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
+import org.apache.olingo.client.api.communication.response.ODataDeleteResponse;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
+import org.apache.olingo.client.core.communication.response.ODataResponseImpl;
+
+/**
+ * This class implements an OData delete request.
+ */
+public class ODataDeleteRequestImpl extends AbstractODataBasicRequest<ODataDeleteResponse, ODataPubFormat>
+        implements ODataDeleteRequest, ODataBatchableRequest {
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param method HTTP method to be used
+   * @param uri URI of the entity to be deleted.
+   */
+  ODataDeleteRequestImpl(final ODataClient odataClient, final HttpMethod method, final URI uri) {
+    super(odataClient, ODataPubFormat.class, method, uri);
+  }
+
+  /**
+   * {@inheritDoc }
+   * <p>
+   * No payload: null will be returned.
+   */
+  @Override
+  protected InputStream getPayload() {
+    return null;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataDeleteResponse execute() {
+    return new ODataDeleteResponseImpl(httpClient, doExecute());
+  }
+
+  /**
+   * Response class about an ODataDeleteRequest.
+   */
+  private class ODataDeleteResponseImpl extends ODataResponseImpl implements ODataDeleteResponse {
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataDeleteResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataDeleteResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+      this.close();
+    }
+  }
+}


[5/7] OLINGO-205 ODataJClient request/response layer implementation imported

Posted by fm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataDeleteResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataDeleteResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataDeleteResponse.java
new file mode 100644
index 0000000..f7b3944
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataDeleteResponse.java
@@ -0,0 +1,27 @@
+/*
+ * 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.api.communication.response;
+
+/**
+ * This class implements the response to an OData delete request.
+ *
+ * @see com.msopentech.odatajclient.engine.communication.request.cud.ODataDeleteRequest
+ */
+public interface ODataDeleteResponse extends ODataResponse {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataEntityCreateResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataEntityCreateResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataEntityCreateResponse.java
new file mode 100644
index 0000000..9b53f73
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataEntityCreateResponse.java
@@ -0,0 +1,36 @@
+/*
+ * 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.api.communication.response;
+
+import org.apache.olingo.client.api.domain.ODataEntity;
+
+/**
+ * This class implements the response to an OData entity create request.
+ *
+ * @see com.msopentech.odatajclient.engine.communication.request.cud.ODataEntityCreateRequest
+ */
+public interface ODataEntityCreateResponse extends ODataResponse {
+
+  /**
+   * Gets created object.
+   *
+   * @return created object.
+   */
+  ODataEntity getBody();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataEntityUpdateResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataEntityUpdateResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataEntityUpdateResponse.java
new file mode 100644
index 0000000..e78363f
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataEntityUpdateResponse.java
@@ -0,0 +1,36 @@
+/*
+ * 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.api.communication.response;
+
+import org.apache.olingo.client.api.domain.ODataEntity;
+
+/**
+ * This class implements the response to an OData update request.
+ *
+ * @see com.msopentech.odatajclient.engine.communication.request.cud.ODataEntityUpdateRequest
+ */
+public interface ODataEntityUpdateResponse extends ODataResponse {
+
+  /**
+   * Gets updated object.
+   *
+   * @return updated object.
+   */
+  ODataEntity getBody();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataInvokeResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataInvokeResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataInvokeResponse.java
new file mode 100644
index 0000000..a26c262
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataInvokeResponse.java
@@ -0,0 +1,36 @@
+/*
+ * 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.api.communication.response;
+
+import org.apache.olingo.client.api.domain.ODataInvokeResult;
+
+/**
+ * This class implements a response to a specific invoke request.
+ *
+ * @see com.msopentech.odatajclient.engine.communication.request.invoke.ODataInvokeRequest
+ */
+public interface ODataInvokeResponse<T extends ODataInvokeResult> extends ODataResponse {
+
+    /**
+     * Gets operation return value if exists.
+     *
+     * @return operation return value.
+     */
+    T getBody();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataLinkOperationResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataLinkOperationResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataLinkOperationResponse.java
new file mode 100644
index 0000000..aa967b1
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataLinkOperationResponse.java
@@ -0,0 +1,28 @@
+/*
+ * 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.api.communication.response;
+
+/**
+ * This interface defines the response to an OData link operation request.
+ *
+ * @see com.msopentech.odatajclient.engine.communication.request.cud.ODataLinkCreateRequest
+ * @see com.msopentech.odatajclient.engine.communication.request.cud.ODataLinkUpdateRequest
+ */
+public interface ODataLinkOperationResponse extends ODataResponse {
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataMediaEntityCreateResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataMediaEntityCreateResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataMediaEntityCreateResponse.java
new file mode 100644
index 0000000..2d41a43
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataMediaEntityCreateResponse.java
@@ -0,0 +1,36 @@
+/*
+ * 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.api.communication.response;
+
+import org.apache.olingo.client.api.domain.ODataEntity;
+
+/**
+ * This class implements the response to an Odata media entity create request.
+ *
+ * @see com.msopentech.odatajclient.engine.communication.request.streamed.ODataMediaEntityCreateRequest
+ */
+public interface ODataMediaEntityCreateResponse extends ODataResponse {
+
+  /**
+   * Gets created object.
+   *
+   * @return created object.
+   */
+  ODataEntity getBody();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataMediaEntityUpdateResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataMediaEntityUpdateResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataMediaEntityUpdateResponse.java
new file mode 100644
index 0000000..5d626d4
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataMediaEntityUpdateResponse.java
@@ -0,0 +1,36 @@
+/*
+ * 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.api.communication.response;
+
+import org.apache.olingo.client.api.domain.ODataEntity;
+
+/**
+ * This class implements the response to an Odata media entity update request.
+ *
+ * @see com.msopentech.odatajclient.engine.communication.request.streamed.ODataMediaEntityUpdateRequest
+ */
+public interface ODataMediaEntityUpdateResponse extends ODataResponse {
+
+  /**
+   * Gets updated object.
+   *
+   * @return updated object.
+   */
+  ODataEntity getBody();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataPropertyUpdateResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataPropertyUpdateResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataPropertyUpdateResponse.java
new file mode 100644
index 0000000..cb775c3
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataPropertyUpdateResponse.java
@@ -0,0 +1,36 @@
+/*
+ * 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.api.communication.response;
+
+import org.apache.olingo.client.api.domain.ODataProperty;
+
+/**
+ * This class implements the response to an OData update entity property request.
+ *
+ * @see com.msopentech.odatajclient.engine.communication.request.cud.ODataPropertyUpdateRequest
+ */
+public interface ODataPropertyUpdateResponse extends ODataResponse {
+
+  /**
+   * Gets updated object.
+   *
+   * @return updated object.
+   */
+  ODataProperty getBody();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/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
new file mode 100644
index 0000000..65434ec
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
@@ -0,0 +1,117 @@
+/*
+ * 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.api.communication.response;
+
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Map;
+import org.apache.olingo.client.api.communication.header.HeaderName;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchLineIterator;
+
+/**
+ * Abstract representation of an OData response.
+ */
+public interface ODataResponse {
+
+  /**
+   * Gets header names.
+   *
+   * @return response header names.
+   */
+  Collection<String> getHeaderNames();
+
+  /**
+   * Gets header value of the given header.
+   *
+   * @param name header to be retrieved.
+   * @return response header value.
+   */
+  Collection<String> getHeader(final String name);
+
+  /**
+   * Gets header value of the given header.
+   *
+   * @param name header to be retrieved.
+   * @return response header value.
+   */
+  Collection<String> getHeader(final HeaderName name);
+
+  /**
+   * Gets 'ETag' header value.
+   *
+   * @return ETag header value, if provided
+   */
+  String getEtag();
+
+  /**
+   * Gets the content type.
+   *
+   * @return content type
+   */
+  String getContentType();
+
+  /**
+   * Gets status code.
+   *
+   * @return status code.
+   */
+  int getStatusCode();
+
+  /**
+   * Gets status message.
+   *
+   * @return status message.
+   */
+  String getStatusMessage();
+
+  /**
+   * Gets response body as InputStream.
+   *
+   * @return response body input stream.
+   */
+  InputStream getRawResponse();
+
+  /**
+   * Initializes response from batch response item.
+   *
+   * @param responseLine response line.
+   * @param headers response headers.
+   * @param batchLineIterator batch line iterator.
+   * @param boundary batch boundary.
+   */
+  ODataResponse initFromBatch(
+          final Map.Entry<Integer, String> responseLine,
+          final Map<String, Collection<String>> headers,
+          final ODataBatchLineIterator batchLineIterator,
+          final String boundary);
+
+  /**
+   * Close the underlying message entity input stream (if available and open) as well as releases any other resources
+   * associated with the response.
+   * <p>
+   * This operation is idempotent, i.e. it can be invoked multiple times with the same effect which also means that
+   * calling the close() method on an already closed message instance is legal and has no further effect.
+   * <p>
+   * The close() method should be invoked on all instances that contain an un-consumed entity input stream to ensure the
+   * resources associated with the instance are properly cleaned-up and prevent potential memory leaks. This is typical
+   * for client-side scenarios where application layer code processes only the response headers and ignores the response
+   * entity.
+   */
+  void close();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataRetrieveResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataRetrieveResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataRetrieveResponse.java
new file mode 100644
index 0000000..1018ca4
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataRetrieveResponse.java
@@ -0,0 +1,34 @@
+/*
+ * 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.api.communication.response;
+
+/**
+ * This class implements a response to a specific query request.
+ *
+ * @see com.msopentech.odatajclient.engine.communication.request.retrieve.ODataRetrieveRequest
+ */
+public interface ODataRetrieveResponse<T> extends ODataResponse {
+
+  /**
+   * Gets query result objects.
+   *
+   * @return query result objects.
+   */
+  T getBody();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataStreamUpdateResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataStreamUpdateResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataStreamUpdateResponse.java
new file mode 100644
index 0000000..891f5a3
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataStreamUpdateResponse.java
@@ -0,0 +1,36 @@
+/*
+ * 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.api.communication.response;
+
+import java.io.InputStream;
+
+/**
+ * This class implements the response to an Odata stream create/update request.
+ *
+ * @see com.msopentech.odatajclient.engine.communication.request.streamed.ODataStreamUpdateRequest
+ */
+public interface ODataStreamUpdateResponse extends ODataResponse {
+
+  /**
+   * Gets created/updated object.
+   *
+   * @return created/updated object.
+   */
+  InputStream getBody();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataValueUpdateResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataValueUpdateResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataValueUpdateResponse.java
new file mode 100644
index 0000000..7b58952
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataValueUpdateResponse.java
@@ -0,0 +1,36 @@
+/*
+ * 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.api.communication.response;
+
+import org.apache.olingo.client.api.domain.ODataValue;
+
+/**
+ * This class implements the response to an OData update entity property request.
+ *
+ * @see com.msopentech.odatajclient.engine.communication.request.cud.ODataPropertyUpdateRequest
+ */
+public interface ODataValueUpdateResponse extends ODataResponse {
+
+  /**
+   * Gets updated object.
+   *
+   * @return updated object.
+   */
+  ODataValue getBody();
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/data/ObjectWrapper.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/data/ObjectWrapper.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/data/ObjectWrapper.java
new file mode 100644
index 0000000..ededff9
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/data/ObjectWrapper.java
@@ -0,0 +1,149 @@
+/*
+ * 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.api.data;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.client.api.domain.ODataEntity;
+import org.apache.olingo.client.api.domain.ODataEntitySet;
+import org.apache.olingo.client.api.domain.ODataEntitySetIterator;
+import org.apache.olingo.client.api.domain.ODataLinkCollection;
+import org.apache.olingo.client.api.domain.ODataProperty;
+import org.apache.olingo.client.api.domain.ODataServiceDocument;
+import org.apache.olingo.client.api.domain.ODataValue;
+import org.apache.olingo.client.api.edm.xml.XMLMetadata;
+import org.apache.olingo.client.api.op.ODataReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ObjectWrapper {
+
+  /**
+   * Logger.
+   */
+  protected static final Logger LOG = LoggerFactory.getLogger(ObjectWrapper.class);
+
+  private final ODataReader reader;
+
+  private final byte[] obj;
+
+  private final String format;
+
+  /**
+   * Constructor.
+   *
+   * @param is source input stream.
+   * @param format source format (<tt>ODataPubFormat</tt>, <tt>ODataFormat</tt>, <tt>ODataValueFormat</tt>,
+   * <tt>ODataServiceDocumentFormat</tt>).
+   */
+  public ObjectWrapper(final ODataReader reader, final InputStream is, final String format) {
+    this.reader = reader;
+    try {
+      this.obj = IOUtils.toByteArray(is);
+      this.format = format;
+    } catch (IOException e) {
+      throw new IllegalArgumentException(e);
+    }
+  }
+
+  /**
+   * Parses stream as <tt>ODataEntitySetIterator</tt>.
+   *
+   * I
+   *
+   * @return <tt>ODataEntitySetIterator</tt> if success; null otherwise.
+   */
+  public ODataEntitySetIterator getODataEntitySetIterator() {
+    return reader.read(new ByteArrayInputStream(obj), format, ODataEntitySetIterator.class);
+  }
+
+  /**
+   * Parses stream as <tt>ODataEntitySet</tt>.
+   *
+   * @return <tt>ODataEntitySet</tt> if success; null otherwise.
+   */
+  public ODataEntitySet getODataEntitySet() {
+    return reader.read(new ByteArrayInputStream(obj), format, ODataEntitySet.class);
+  }
+
+  /**
+   * Parses stream as <tt>ODataEntity</tt>.
+   *
+   * @return <tt>ODataEntity</tt> if success; null otherwise.
+   */
+  public ODataEntity getODataEntity() {
+    return reader.read(new ByteArrayInputStream(obj), format, ODataEntity.class);
+  }
+
+  /**
+   * Parses stream as <tt>ODataProperty</tt>.
+   *
+   * @return <tt>ODataProperty</tt> if success; null otherwise.
+   */
+  public ODataProperty getODataProperty() {
+    return reader.read(new ByteArrayInputStream(obj), format, ODataProperty.class);
+  }
+
+  /**
+   * Parses stream as <tt>ODataLinkCollection</tt>.
+   *
+   * @return <tt>ODataLinkCollection</tt> if success; null otherwise.
+   */
+  public ODataLinkCollection getODataLinkCollection() {
+    return reader.read(new ByteArrayInputStream(obj), format, ODataLinkCollection.class);
+  }
+
+  /**
+   * Parses stream as <tt>ODataValue</tt>.
+   *
+   * @return <tt>ODataValue</tt> if success; null otherwise.
+   */
+  public ODataValue getODataValue() {
+    return reader.read(new ByteArrayInputStream(obj), format, ODataValue.class);
+  }
+
+  /**
+   * Parses stream as <tt>EdmMetadata</tt>.
+   *
+   * @return <tt>EdmMetadata</tt> if success; null otherwise.
+   */
+  public XMLMetadata getEdmMetadata() {
+    return reader.read(new ByteArrayInputStream(obj), null, XMLMetadata.class);
+  }
+
+  /**
+   * Parses stream as <tt>ODataServiceDocument</tt>.
+   *
+   * @return <tt>ODataServiceDocument</tt> if success; null otherwise.
+   */
+  public ODataServiceDocument getODataServiceDocument() {
+    return reader.read(new ByteArrayInputStream(obj), format, ODataServiceDocument.class);
+  }
+
+  /**
+   * Parses stream as <tt>ODataError</tt>.
+   *
+   * @return <tt>ODataError</tt> if success; null otherwise.
+   */
+  public Error getODataError() {
+    return reader.read(new ByteArrayInputStream(obj), null, Error.class);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySet.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySet.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySet.java
index dc4282d..22aff1f 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySet.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySet.java
@@ -21,7 +21,6 @@ package org.apache.olingo.client.api.domain;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
-import org.apache.olingo.client.api.domain.ODataInvokeResult;
 
 /**
  * OData entity collection. If pagination was used to get this instance, forward page navigation URI will be available.

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/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
new file mode 100644
index 0000000..8c10c10
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/domain/ODataEntitySetIterator.java
@@ -0,0 +1,307 @@
+/*
+ * 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.api.domain;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.client.api.data.Entry;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * OData entity set iterator class.
+ * <br/>
+ * <b>Please don't forget to call the <tt>close()>/<tt> method when not needed any more.</b>
+ */
+public class ODataEntitySetIterator implements Iterator<ODataEntity> {
+
+  /**
+   * Logger.
+   */
+  private static final Logger LOG = LoggerFactory.getLogger(ODataEntitySetIterator.class);
+
+  private static final long serialVersionUID = 9039605899821494025L;
+
+  private final ODataClient odataClient;
+
+  private final InputStream stream;
+
+  private final ODataPubFormat format;
+
+  private Entry cached;
+
+  private ODataEntitySet entitySet;
+
+  private final ByteArrayOutputStream osFeed;
+
+  private final String namespaces;
+
+  private boolean available = true;
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param stream source stream.
+   * @param format OData format.
+   */
+  public ODataEntitySetIterator(final ODataClient odataClient, final InputStream stream, final ODataPubFormat format) {
+    this.odataClient = odataClient;
+    this.stream = stream;
+    this.format = format;
+    this.osFeed = new ByteArrayOutputStream();
+
+    if (format == ODataPubFormat.ATOM) {
+      namespaces = getAllElementAttributes(stream, "feed", osFeed);
+    } else {
+      namespaces = null;
+      try {
+        if (consume(stream, "\"value\":", osFeed, true) >= 0) {
+          int c = 0;
+          while (c != '[' && (c = stream.read()) >= 0) {
+            osFeed.write(c);
+          }
+        }
+      } catch (IOException e) {
+        LOG.error("Error parsing feed", e);
+        throw new IllegalStateException(e);
+      }
+    }
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public boolean hasNext() {
+    if (available && cached == null) {
+      if (format == ODataPubFormat.ATOM) {
+        cached = nextAtomEntryFromFeed(stream, osFeed, namespaces);
+      } else {
+        cached = nextJsonEntryFromFeed(stream, osFeed);
+      }
+
+      if (cached == null) {
+        available = false;
+        entitySet = odataClient.getReader().
+                readEntitySet(new ByteArrayInputStream(osFeed.toByteArray()), format);
+        close();
+      }
+    }
+
+    return available;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataEntity next() {
+    if (hasNext()) {
+      final ODataEntity res = odataClient.getBinder().getODataEntity(cached);
+      cached = null;
+      return res;
+    }
+
+    throw new NoSuchElementException("No entity found");
+  }
+
+  /**
+   * Unsupported operation.
+   */
+  @Override
+  public void remove() {
+    throw new UnsupportedOperationException("Operation not supported");
+  }
+
+  /**
+   * Closes the current iterator.
+   */
+  public void close() {
+    IOUtils.closeQuietly(stream);
+    IOUtils.closeQuietly(osFeed);
+  }
+
+  /**
+   * Gets the next link if exists.
+   *
+   * @return next link if exists; null otherwise.
+   */
+  public URI getNext() {
+    if (entitySet == null) {
+      throw new IllegalStateException("Iteration must be completed in order to retrieve the link for next page");
+    }
+    return entitySet.getNext();
+  }
+
+  private Entry nextJsonEntryFromFeed(final InputStream input, final OutputStream osFeed) {
+    final ByteArrayOutputStream entry = new ByteArrayOutputStream();
+
+    Entry jsonEntry = null;
+    try {
+      int c = 0;
+
+      boolean foundNewOne = false;
+
+      do {
+        c = input.read();
+        if (c == '{') {
+          entry.write(c);
+          c = -1;
+          foundNewOne = true;
+        }
+        if (c == ']') {
+          osFeed.write(c);
+          c = -1;
+        }
+      } while (c >= 0);
+
+      if (foundNewOne) {
+        int count = 1;
+        c = 0;
+
+        while (count > 0 && c >= 0) {
+          c = input.read();
+          if (c == '{') {
+            count++;
+          } else if (c == '}') {
+            count--;
+          }
+          entry.write(c);
+        }
+
+        if (c >= 0) {
+          jsonEntry = odataClient.getDeserializer().toEntry(
+                  new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.JSON);
+        }
+      } else {
+        while ((c = input.read()) >= 0) {
+          osFeed.write(c);
+        }
+      }
+    } catch (Exception e) {
+      LOG.error("Error retrieving entities from EntitySet", e);
+    }
+
+    return jsonEntry;
+  }
+
+  /**
+   * De-Serializes a stream into an OData entity set.
+   *
+   * @param input stream to de-serialize.
+   * @param format de-serialize as AtomFeed or JSONFeed
+   * @return de-serialized entity set.
+   */
+  private Entry nextAtomEntryFromFeed(final InputStream input, final OutputStream osFeed, final String namespaces) {
+    final ByteArrayOutputStream entry = new ByteArrayOutputStream();
+
+    Entry atomEntry = null;
+
+    try {
+      if (consume(input, "<entry>", osFeed, false) >= 0) {
+        entry.write("<entry ".getBytes(Constants.UTF8));
+        entry.write(namespaces.getBytes(Constants.UTF8));
+        entry.write(">".getBytes(Constants.UTF8));
+
+        if (consume(input, "</entry>", entry, true) >= 0) {
+          atomEntry = odataClient.getDeserializer().
+                  toEntry(new ByteArrayInputStream(entry.toByteArray()), ODataPubFormat.ATOM);
+        }
+      }
+    } catch (Exception e) {
+      LOG.error("Error retrieving entities from EntitySet", e);
+    }
+
+    return atomEntry;
+  }
+
+  private String getAllElementAttributes(final InputStream input, final String name, final OutputStream os) {
+    final ByteArrayOutputStream attrs = new ByteArrayOutputStream();
+
+    String res;
+
+    try {
+      byte[] attrsDeclaration = null;
+
+      final String key = "<" + name + " ";
+      if (consume(input, key, os, true) >= 0 && consume(input, ">", attrs, false) >= 0) {
+        attrsDeclaration = attrs.toByteArray();
+        os.write(attrsDeclaration);
+        os.write('>');
+      }
+
+      res = attrsDeclaration == null
+              ? StringUtils.EMPTY
+              : new String(attrsDeclaration, Constants.UTF8).trim();
+    } catch (Exception e) {
+      LOG.error("Error retrieving entities from EntitySet", e);
+      res = StringUtils.EMPTY;
+    }
+
+    return res.endsWith("/") ? res.substring(0, res.length() - 1) : res;
+  }
+
+  private int consume(
+          final InputStream input, final String end, final OutputStream os, final boolean includeEndKey)
+          throws IOException {
+
+    final char[] endKey = end.toCharArray();
+    final char[] endLowerKey = end.toLowerCase().toCharArray();
+    final char[] endUpperKey = end.toUpperCase().toCharArray();
+
+    int pos = 0;
+    int c = 0;
+    while (pos < endKey.length && (c = input.read()) >= 0) {
+      if (c == endLowerKey[pos] || c == endUpperKey[pos]) {
+        pos++;
+        if (includeEndKey && os != null) {
+          os.write(c);
+        }
+      } else if (pos > 0) {
+        if (!includeEndKey && os != null) {
+          for (int i = 0; i < pos; i++) {
+            os.write(endKey[i]);
+          }
+        }
+        if (os != null) {
+          os.write(c);
+        }
+        pos = 0;
+      } else {
+        if (os != null) {
+          os.write(c);
+        }
+      }
+    }
+
+    return c;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/URIUtils.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/URIUtils.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/URIUtils.java
index e277736..0d52740 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/URIUtils.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/URIUtils.java
@@ -18,6 +18,9 @@
  */
 package org.apache.olingo.client.api.utils;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.math.BigDecimal;
 import java.net.URI;
 import java.net.URLEncoder;
@@ -25,7 +28,10 @@ import java.text.DecimalFormat;
 import java.util.UUID;
 
 import org.apache.commons.codec.binary.Hex;
-import org.apache.olingo.client.api.ODataConstants;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.entity.InputStreamEntity;
+import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
 import org.apache.olingo.client.api.domain.ODataDuration;
 import org.apache.olingo.client.api.domain.ODataTimestamp;
@@ -144,9 +150,9 @@ public final class URIUtils {
               : (obj instanceof byte[])
               ? "X'" + Hex.encodeHexString((byte[]) obj) + "'"
               : ((obj instanceof ODataTimestamp) && ((ODataTimestamp) obj).getTimezone() == null)
-              ? "datetime'" + URLEncoder.encode(((ODataTimestamp) obj).toString(), ODataConstants.UTF8) + "'"
+              ? "datetime'" + URLEncoder.encode(((ODataTimestamp) obj).toString(), Constants.UTF8) + "'"
               : ((obj instanceof ODataTimestamp) && ((ODataTimestamp) obj).getTimezone() != null)
-              ? "datetimeoffset'" + URLEncoder.encode(((ODataTimestamp) obj).toString(), ODataConstants.UTF8)
+              ? "datetimeoffset'" + URLEncoder.encode(((ODataTimestamp) obj).toString(), Constants.UTF8)
               + "'"
               : (obj instanceof ODataDuration)
               ? "time'" + ((ODataDuration) obj).toString() + "'"
@@ -159,7 +165,7 @@ public final class URIUtils {
               : (obj instanceof Long)
               ? ((Long) obj).toString() + "L"
               : (obj instanceof String)
-              ? "'" + URLEncoder.encode((String) obj, ODataConstants.UTF8) + "'"
+              ? "'" + URLEncoder.encode((String) obj, Constants.UTF8) + "'"
               : obj.toString();
     } catch (Exception e) {
       LOG.warn("While escaping '{}', using toString()", obj, e);
@@ -168,4 +174,23 @@ public final class URIUtils {
 
     return value;
   }
+
+  public static InputStreamEntity buildInputStreamEntity(final ODataClient client, final InputStream input) {
+    InputStreamEntity entity;
+    if (client.getConfiguration().isUseChuncked()) {
+      entity = new InputStreamEntity(input, -1);
+    } else {
+      byte[] bytes = new byte[0];
+      try {
+        bytes = IOUtils.toByteArray(input);
+      } catch (IOException e) {
+        LOG.error("While reading input for not chunked encoding", e);
+      }
+
+      entity = new InputStreamEntity(new ByteArrayInputStream(bytes), bytes.length);
+    }
+    entity.setChunked(client.getConfiguration().isUseChuncked());
+
+    return entity;
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/pom.xml
----------------------------------------------------------------------
diff --git a/lib/client-core/pom.xml b/lib/client-core/pom.xml
index 88b1763..f5d21e4 100644
--- a/lib/client-core/pom.xml
+++ b/lib/client-core/pom.xml
@@ -47,20 +47,6 @@
     </dependency>
 
     <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-lang3</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpclient</artifactId>
-    </dependency>
-                 
-    <dependency>
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-core</artifactId>
     </dependency>
@@ -82,11 +68,6 @@
     </dependency>
       
     <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-          
-    <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
     </dependency>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/AbstractConfiguration.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/AbstractConfiguration.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/AbstractConfiguration.java
index 78d0e9e..eba44e3 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/AbstractConfiguration.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/AbstractConfiguration.java
@@ -51,6 +51,8 @@ public abstract class AbstractConfiguration implements Configuration {
 
   private static final String CHUNKING = "chunking";
 
+  private static final long serialVersionUID = 1L;
+
   private final Map<String, Object> CONF = new HashMap<String, Object>();
 
   private transient ExecutorService executor = Executors.newFixedThreadPool(10);
@@ -194,5 +196,4 @@ public abstract class AbstractConfiguration implements Configuration {
   public void setExecutor(final ExecutorService executorService) {
     executor = executorService;
   }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataV3ClientImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataV3ClientImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataV3ClientImpl.java
index 782d0e2..1146c94 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataV3ClientImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataV3ClientImpl.java
@@ -20,12 +20,25 @@ package org.apache.olingo.client.core;
 
 import org.apache.olingo.client.api.ODataV3Client;
 import org.apache.olingo.client.api.V3Configuration;
+import org.apache.olingo.client.api.communication.header.HeaderName;
+import org.apache.olingo.client.api.communication.header.ODataHeaders;
+import org.apache.olingo.client.api.communication.request.batch.V3BatchRequestFactory;
+import org.apache.olingo.client.api.communication.request.cud.V3CUDRequestFactory;
+import org.apache.olingo.client.api.communication.request.invoke.V3InvokeRequestFactory;
+import org.apache.olingo.client.api.communication.request.retrieve.V3RetrieveRequestFactory;
+import org.apache.olingo.client.api.communication.request.streamed.V3StreamedRequestFactory;
 import org.apache.olingo.client.api.op.ODataBinder;
 import org.apache.olingo.client.api.op.ODataReader;
 import org.apache.olingo.client.api.op.ODataSerializer;
 import org.apache.olingo.client.api.op.ODataV3Deserializer;
 import org.apache.olingo.client.api.uri.V3URIBuilder;
 import org.apache.olingo.client.api.uri.filter.V3FilterFactory;
+import org.apache.olingo.client.core.communication.header.ODataHeadersImpl;
+import org.apache.olingo.client.core.communication.request.batch.V3BatchRequestFactoryImpl;
+import org.apache.olingo.client.core.communication.request.cud.V3CUDRequestFactoryImpl;
+import org.apache.olingo.client.core.communication.request.invoke.V3InvokeRequestFactoryImpl;
+import org.apache.olingo.client.core.communication.request.retrieve.V3RetrieveRequestFactoryImpl;
+import org.apache.olingo.client.core.communication.request.streamed.V3StreamedRequestFactoryImpl;
 import org.apache.olingo.client.core.op.impl.ODataV3BinderImpl;
 import org.apache.olingo.client.core.op.impl.ODataV3DeserializerImpl;
 import org.apache.olingo.client.core.op.impl.ODataV3ReaderImpl;
@@ -50,28 +63,30 @@ public class ODataV3ClientImpl extends AbstractODataClient implements ODataV3Cli
 
   private final ODataBinder binder = new ODataV3BinderImpl(this);
 
-//  private final V3RetrieveRequestFactory retrieveReqFact = new V3RetrieveRequestFactory(this);
-//
-//  private final V3CUDRequestFactory cudReqFact = new V3CUDRequestFactory(this);
-//
-//  private final V3StreamedRequestFactory streamedReqFact = new V3StreamedRequestFactory(this);
-//
-//  private final V3InvokeRequestFactory invokeReqFact = new V3InvokeRequestFactory(this);
-//
-//  private final V3BatchRequestFactory batchReqFact = new V3BatchRequestFactory(this);
+  private final V3RetrieveRequestFactory retrieveReqFact = new V3RetrieveRequestFactoryImpl(this);
+
+  private final V3CUDRequestFactory cudReqFact = new V3CUDRequestFactoryImpl(this);
+
+  private final V3StreamedRequestFactory streamedReqFact = new V3StreamedRequestFactoryImpl(this);
+
+  private final V3InvokeRequestFactory invokeReqFact = new V3InvokeRequestFactoryImpl(this);
+
+  private final V3BatchRequestFactory batchReqFact = new V3BatchRequestFactoryImpl(this);
+
   @Override
   public ODataServiceVersion getServiceVersion() {
     return ODataServiceVersion.V30;
   }
 
-//  @Override
-//  public ODataHeaders getVersionHeaders() {
-//    final ODataHeaders odataHeaders = new ODataHeaders();
-//    odataHeaders.setHeader(ODataHeaders.HeaderName.minDataServiceVersion, ODataVersion.V3.toString());
-//    odataHeaders.setHeader(ODataHeaders.HeaderName.maxDataServiceVersion, ODataVersion.V3.toString());
-//    odataHeaders.setHeader(ODataHeaders.HeaderName.dataServiceVersion, ODataVersion.V3.toString());
-//    return odataHeaders;
-//  }
+  @Override
+  public ODataHeaders getVersionHeaders() {
+    final ODataHeadersImpl odataHeaders = new ODataHeadersImpl();
+    odataHeaders.setHeader(HeaderName.minDataServiceVersion, ODataServiceVersion.V30.toString());
+    odataHeaders.setHeader(HeaderName.maxDataServiceVersion, ODataServiceVersion.V30.toString());
+    odataHeaders.setHeader(HeaderName.dataServiceVersion, ODataServiceVersion.V30.toString());
+    return odataHeaders;
+  }
+
   @Override
   public V3Configuration getConfiguration() {
     return configuration;
@@ -107,28 +122,28 @@ public class ODataV3ClientImpl extends AbstractODataClient implements ODataV3Cli
     return binder;
   }
 
-//  @Override
-//  public V3RetrieveRequestFactory getRetrieveRequestFactory() {
-//    return retrieveReqFact;
-//  }
-//
-//  @Override
-//  public V3CUDRequestFactory getCUDRequestFactory() {
-//    return cudReqFact;
-//  }
-//
-//  @Override
-//  public V3StreamedRequestFactory getStreamedRequestFactory() {
-//    return streamedReqFact;
-//  }
-//
-//  @Override
-//  public V3InvokeRequestFactory getInvokeRequestFactory() {
-//    return invokeReqFact;
-//  }
-//
-//  @Override
-//  public V3BatchRequestFactory getBatchRequestFactory() {
-//    return batchReqFact;
-//  }
+  @Override
+  public V3RetrieveRequestFactory getRetrieveRequestFactory() {
+    return retrieveReqFact;
+  }
+
+  @Override
+  public V3CUDRequestFactory getCUDRequestFactory() {
+    return cudReqFact;
+  }
+
+  @Override
+  public V3StreamedRequestFactory getStreamedRequestFactory() {
+    return streamedReqFact;
+  }
+
+  @Override
+  public V3InvokeRequestFactory getInvokeRequestFactory() {
+    return invokeReqFact;
+  }
+
+  @Override
+  public V3BatchRequestFactory getBatchRequestFactory() {
+    return batchReqFact;
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataV4ClientImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataV4ClientImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataV4ClientImpl.java
index 62e75be..2d5f6bf 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataV4ClientImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/ODataV4ClientImpl.java
@@ -20,12 +20,25 @@ package org.apache.olingo.client.core;
 
 import org.apache.olingo.client.api.ODataV4Client;
 import org.apache.olingo.client.api.V4Configuration;
+import org.apache.olingo.client.api.communication.header.HeaderName;
+import org.apache.olingo.client.api.communication.header.ODataHeaders;
+import org.apache.olingo.client.api.communication.request.batch.V4BatchRequestFactory;
+import org.apache.olingo.client.api.communication.request.cud.V4CUDRequestFactory;
+import org.apache.olingo.client.api.communication.request.invoke.V4InvokeRequestFactory;
+import org.apache.olingo.client.api.communication.request.retrieve.V4RetrieveRequestFactory;
+import org.apache.olingo.client.api.communication.request.streamed.V4StreamedRequestFactory;
 import org.apache.olingo.client.api.op.ODataBinder;
 import org.apache.olingo.client.api.op.ODataReader;
 import org.apache.olingo.client.api.op.ODataSerializer;
 import org.apache.olingo.client.api.op.ODataV4Deserializer;
 import org.apache.olingo.client.api.uri.V4URIBuilder;
 import org.apache.olingo.client.api.uri.filter.V4FilterFactory;
+import org.apache.olingo.client.core.communication.header.ODataHeadersImpl;
+import org.apache.olingo.client.core.communication.request.batch.V4BatchRequestFactoryImpl;
+import org.apache.olingo.client.core.communication.request.cud.V4CUDRequestFactoryImpl;
+import org.apache.olingo.client.core.communication.request.invoke.V4InvokeRequestFactoryImpl;
+import org.apache.olingo.client.core.communication.request.retrieve.V4RetrieveRequestFactoryImpl;
+import org.apache.olingo.client.core.communication.request.streamed.V4StreamedRequestFactoryImpl;
 import org.apache.olingo.client.core.op.impl.ODataV4BinderImpl;
 import org.apache.olingo.client.core.op.impl.ODataV4DeserializerImpl;
 import org.apache.olingo.client.core.op.impl.ODataV4ReaderImpl;
@@ -50,27 +63,28 @@ public class ODataV4ClientImpl extends AbstractODataClient implements ODataV4Cli
 
   private final ODataBinder binder = new ODataV4BinderImpl(this);
 
-//    private final V4RetrieveRequestFactory retrieveReqFact = new V4RetrieveRequestFactory(this);
-//
-//    private final V4CUDRequestFactory cudReqFact = new V4CUDRequestFactory(this);
-//
-//    private final V4StreamedRequestFactory streamedReqFact = new V4StreamedRequestFactory(this);
-//
-//    private final V4InvokeRequestFactory invokeReqFact = new V4InvokeRequestFactory(this);
-//
-//    private final V4BatchRequestFactory batchReqFact = new V4BatchRequestFactory(this);
+  private final V4RetrieveRequestFactory retrieveReqFact = new V4RetrieveRequestFactoryImpl(this);
+
+  private final V4CUDRequestFactory cudReqFact = new V4CUDRequestFactoryImpl(this);
+
+  private final V4StreamedRequestFactory streamedReqFact = new V4StreamedRequestFactoryImpl(this);
+
+  private final V4InvokeRequestFactory invokeReqFact = new V4InvokeRequestFactoryImpl(this);
+
+  private final V4BatchRequestFactory batchReqFact = new V4BatchRequestFactoryImpl(this);
+
   @Override
   public ODataServiceVersion getServiceVersion() {
     return ODataServiceVersion.V40;
   }
-//
-//    @Override
-//    public ODataHeaders getVersionHeaders() {
-//        final ODataHeaders odataHeaders = new ODataHeaders();
-//        odataHeaders.setHeader(ODataHeaders.HeaderName.maxDataServiceVersion, ODataVersion.V4.toString());
-//        odataHeaders.setHeader(ODataHeaders.HeaderName.dataServiceVersion, ODataVersion.V4.toString());
-//        return odataHeaders;
-//    }
+
+  @Override
+  public ODataHeaders getVersionHeaders() {
+    final ODataHeadersImpl odataHeaders = new ODataHeadersImpl();
+    odataHeaders.setHeader(HeaderName.maxDataServiceVersion, ODataServiceVersion.V40.toString());
+    odataHeaders.setHeader(HeaderName.dataServiceVersion, ODataServiceVersion.V40.toString());
+    return odataHeaders;
+  }
 
   @Override
   public V4Configuration getConfiguration() {
@@ -107,28 +121,28 @@ public class ODataV4ClientImpl extends AbstractODataClient implements ODataV4Cli
     return binder;
   }
 
-//    @Override
-//    public V4RetrieveRequestFactory getRetrieveRequestFactory() {
-//        return retrieveReqFact;
-//    }
-//
-//    @Override
-//    public V4CUDRequestFactory getCUDRequestFactory() {
-//        return cudReqFact;
-//    }
-//
-//    @Override
-//    public V4StreamedRequestFactory getStreamedRequestFactory() {
-//        return streamedReqFact;
-//    }
-//
-//    @Override
-//    public V4InvokeRequestFactory getInvokeRequestFactory() {
-//        return invokeReqFact;
-//    }
-//
-//    @Override
-//    public V4BatchRequestFactory getBatchRequestFactory() {
-//        return batchReqFact;
-//    }
+  @Override
+  public V4RetrieveRequestFactory getRetrieveRequestFactory() {
+    return retrieveReqFact;
+  }
+
+  @Override
+  public V4CUDRequestFactory getCUDRequestFactory() {
+    return cudReqFact;
+  }
+
+  @Override
+  public V4StreamedRequestFactory getStreamedRequestFactory() {
+    return streamedReqFact;
+  }
+
+  @Override
+  public V4InvokeRequestFactory getInvokeRequestFactory() {
+    return invokeReqFact;
+  }
+
+  @Override
+  public V4BatchRequestFactory getBatchRequestFactory() {
+    return batchReqFact;
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/Wrapper.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/Wrapper.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/Wrapper.java
new file mode 100644
index 0000000..1237a2f
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/Wrapper.java
@@ -0,0 +1,41 @@
+/*
+ * 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;
+
+/**
+ * Generic wrapper class.
+ *
+ * @param <T>
+ */
+public class Wrapper<T> {
+
+  private T wrapped;
+
+  public void setWrapped(final T wrapped) {
+    this.wrapped = wrapped;
+  }
+
+  public T getWrapped() {
+    if (wrapped == null) {
+      throw new IllegalStateException("Wrapped object not set");
+    }
+
+    return wrapped;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/header/ODataHeadersImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/header/ODataHeadersImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/header/ODataHeadersImpl.java
new file mode 100644
index 0000000..ace190e
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/header/ODataHeadersImpl.java
@@ -0,0 +1,111 @@
+/*
+ * 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.communication.header;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.TreeMap;
+import org.apache.olingo.client.api.communication.header.HeaderName;
+import org.apache.olingo.client.api.communication.header.ODataHeaders;
+
+/**
+ * ODataHeaders wraps OData request/response headers.
+ *
+ * @see org.apache.olingo.client.core.communication.request.ODataRequest
+ * @see org.apache.olingo.client.core.communication.response.ODataResponse
+ */
+public class ODataHeadersImpl implements ODataHeaders {
+
+  /**
+   * OData request/response header key/value pairs.
+   */
+  private final Map<String, String> headers = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+
+  /**
+   * Add the specified (custom) header (header name is case-insensitive).
+   *
+   * @param name header key.
+   * @param value header value.
+   * @return the current updated header instance.
+   */
+  public ODataHeaders setHeader(final String name, final String value) {
+    headers.put(name, value);
+    return this;
+  }
+
+  /**
+   * Add the specified header.
+   *
+   * @param name header key.
+   * @param value header value.
+   * @return the current updated header instance.
+   */
+  public ODataHeaders setHeader(final HeaderName name, final String value) {
+    headers.put(name.toString(), value);
+    return this;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public String getHeader(final HeaderName name) {
+    return headers.get(name.toString());
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public String getHeader(final String name) {
+    return headers.get(name);
+  }
+
+  /**
+   * Removes the header identified by the given name.
+   * <br/>
+   * Please note that header name is case-insensitive.
+   *
+   * @param name name of the header to be retrieved.
+   * @return header name (if found).
+   */
+  public String removeHeader(final HeaderName name) {
+    return headers.remove(name.toString());
+  }
+
+  /**
+   * Removes the header identified by the given name.
+   * <br/>
+   * Please note that header name is case-insensitive.
+   *
+   * @param name name of the header to be retrieved.
+   * @return header name (if found).
+   */
+  public String removeHeader(final String name) {
+    return headers.remove(name);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public Collection<String> getHeaderNames() {
+    return headers.keySet();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
new file mode 100644
index 0000000..84135eb
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.communication.request;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.client.api.ODataBatchConstants;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.request.ODataStreamer;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.api.http.HttpMethod;
+
+/**
+ * Basic request abstract implementation.
+ *
+ * @param <V> OData response type corresponding to the request implementation.
+ * @param <T> OData format being used.
+ */
+public abstract class AbstractODataBasicRequest<V extends ODataResponse, T extends Enum<T>>
+        extends ODataRequestImpl<T>
+        implements ODataBasicRequest<V, T> {
+
+    /**
+     * Constructor.
+     *
+     * @param odataClient client instance getting this request
+     * @param formatRef reference class for the format being used
+     * @param method request method.
+     * @param uri OData request URI.
+     */
+    public AbstractODataBasicRequest(final ODataClient odataClient,
+            final Class<T> formatRef, final HttpMethod method, final URI uri) {
+
+        super(odataClient, formatRef, method, uri);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setFormat(final T format) {
+        if (format != null) {
+            setAccept(format.toString());
+            setContentType(format.toString());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public final Future<V> asyncExecute() {
+        return odataClient.getConfiguration().getExecutor().submit(new Callable<V>() {
+
+            @Override
+            public V call() throws Exception {
+                return execute();
+            }
+        });
+    }
+
+    /**
+     * Gets payload as an InputStream.
+     *
+     * @return InputStream for entire payload.
+     */
+    protected abstract InputStream getPayload();
+
+    /**
+     * Serializes the full request into the given batch request.
+     *
+     * @param req destination batch request.
+     */
+    public void batch(final ODataBatchRequest req) {
+        batch(req, null);
+    }
+
+    /**
+     * Serializes the full request into the given batch request.
+     * <p>
+     * This method have to be used to serialize a changeset item with the specified contentId.
+     *
+     * @param req destination batch request.
+     * @param contentId contentId of the changeset item.
+     */
+    public void batch(final ODataBatchRequest req, final String contentId) {
+        try {
+            req.rawAppend(toByteArray());
+            if (StringUtils.isNotBlank(contentId)) {
+                req.rawAppend((ODataBatchConstants.CHANGESET_CONTENT_ID_NAME + ": " + contentId).getBytes());
+                req.rawAppend(ODataStreamer.CRLF);
+            }
+            req.rawAppend(ODataStreamer.CRLF);
+
+            final InputStream payload = getPayload();
+            if (payload != null) {
+                req.rawAppend(IOUtils.toByteArray(getPayload()));
+            }
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataStreamManager.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataStreamManager.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataStreamManager.java
new file mode 100644
index 0000000..2c59ff0
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataStreamManager.java
@@ -0,0 +1,183 @@
+/*
+ * 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.communication.request;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.olingo.client.api.communication.request.ODataStreamManager;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.api.http.HttpClientException;
+import org.apache.olingo.client.core.Wrapper;
+
+/**
+ * OData request payload management abstract class.
+ *
+ * @param <T> OData response type corresponding to the request implementation.
+ */
+public abstract class AbstractODataStreamManager<T extends ODataResponse> extends AbstractODataStreamer
+        implements ODataStreamManager<T> {
+
+  /**
+   * Body input stream.
+   */
+  private final PipedInputStream body;
+
+  /**
+   * Default body input stream.
+   */
+  private final InputStream defaultBody;
+
+  /**
+   * Wrapper for actual streamed request's future.
+   */
+  private final Wrapper<Future<HttpResponse>> futureWrap;
+
+  /**
+   * Constructor.
+   *
+   * @param futureWrap wrapper of the Future object of the HttpResponse.
+   */
+  public AbstractODataStreamManager(final Wrapper<Future<HttpResponse>> futureWrap) {
+    this(futureWrap, new PipedOutputStream());
+  }
+
+  /**
+   * Constructor.
+   *
+   * @param futureWrap wrapper of the Future object of the HttpResponse.
+   * @param output stream to be piped to retrieve the payload.
+   */
+  public AbstractODataStreamManager(final Wrapper<Future<HttpResponse>> futureWrap, final PipedOutputStream output) {
+    super(output);
+
+    this.futureWrap = futureWrap;
+    try {
+      this.body = new PipedInputStream(getBodyStreamWriter());
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
+    }
+    this.defaultBody = this.body;
+  }
+
+  /**
+   * Constructor.
+   *
+   * @param futureWrap wrapper of the Future object of the HttpResponse.
+   * @param input stream to be used to retrieve the content.
+   */
+  public AbstractODataStreamManager(final Wrapper<Future<HttpResponse>> futureWrap, final InputStream input) {
+    super(null);
+
+    this.futureWrap = futureWrap;
+    this.body = null;
+    this.defaultBody = input;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public InputStream getBody() {
+    return this.body == null ? this.defaultBody : this.body;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void finalizeBody() {
+    IOUtils.closeQuietly(getBodyStreamWriter());
+  }
+
+  /**
+   * Gets HttpResponse.
+   *
+   * @param timeout maximum delay after which the request must be aborted.
+   * @param unit time unit.
+   * @return HttpResponse.
+   */
+  protected HttpResponse getHttpResponse(final long timeout, final TimeUnit unit) {
+    try {
+      return futureWrap.getWrapped().get(timeout, unit);
+    } catch (Exception e) {
+      LOG.error("Failure executing request");
+      throw new HttpClientException(e);
+    }
+  }
+
+  /**
+   * Gets OData response.
+   *
+   * @param timeout maximum delay after which the request must be aborted.
+   * @param unit time unit.
+   * @return ODataResponse instance.
+   */
+  protected abstract T getResponse(long timeout, TimeUnit unit);
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public final T getResponse() {
+    return getResponse(30, TimeUnit.SECONDS);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public final Future<T> getAsyncResponse() {
+    return new Future<T>() {
+      @Override
+      public boolean cancel(final boolean mayInterruptIfRunning) {
+        return futureWrap.getWrapped().cancel(mayInterruptIfRunning);
+      }
+
+      @Override
+      public boolean isCancelled() {
+        return futureWrap.getWrapped().isCancelled();
+      }
+
+      @Override
+      public boolean isDone() {
+        return futureWrap.getWrapped().isDone();
+      }
+
+      @Override
+      public T get() throws InterruptedException, ExecutionException {
+        return getResponse(0, TimeUnit.SECONDS);
+      }
+
+      @Override
+      public T get(final long timeout, final TimeUnit unit)
+              throws InterruptedException, ExecutionException, TimeoutException {
+
+        return getResponse(timeout, unit);
+      }
+    };
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataStreamer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataStreamer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataStreamer.java
new file mode 100644
index 0000000..b3fac1b
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataStreamer.java
@@ -0,0 +1,101 @@
+/*
+ * 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.communication.request;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PipedOutputStream;
+import org.apache.olingo.client.api.communication.request.ODataStreamer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Streamer utility object.
+ */
+public abstract class AbstractODataStreamer implements ODataStreamer {
+
+  /**
+   * Logger.
+   */
+  protected static final Logger LOG = LoggerFactory.getLogger(AbstractODataStreamer.class);
+
+  /**
+   * OutputStream to be used to write objects to the stream.
+   */
+  private final PipedOutputStream bodyStreamWriter;
+
+  /**
+   * Constructor.
+   *
+   * @param bodyStreamWriter piped stream to be used to retrieve the payload.
+   */
+  public AbstractODataStreamer(final PipedOutputStream bodyStreamWriter) {
+    this.bodyStreamWriter = bodyStreamWriter;
+  }
+
+  /**
+   * Writes the gibe byte array onto the output stream provided at instantiation time.
+   *
+   * @param src byte array to be written.
+   */
+  protected void stream(final byte[] src) {
+    new Writer(src, bodyStreamWriter).run();
+  }
+
+  /**
+   * Stream CR/LF.
+   */
+  protected void newLine() {
+    stream(CRLF);
+  }
+
+  /**
+   * Gets the piped stream to be used to stream the payload.
+   *
+   * @return piped stream.
+   */
+  @Override
+  public PipedOutputStream getBodyStreamWriter() {
+    return bodyStreamWriter;
+  }
+
+  /**
+   * Writer thread.
+   */
+  private class Writer implements Runnable {
+
+    final OutputStream os;
+
+    final byte[] src;
+
+    public Writer(final byte[] src, final OutputStream os) {
+      this.os = os;
+      this.src = src;
+    }
+
+    @Override
+    public void run() {
+      try {
+        os.write(src);
+      } catch (IOException e) {
+        LOG.error("Error streaming object", e);
+      }
+    }
+  }
+}


[3/7] OLINGO-205 ODataJClient request/response layer implementation imported

Posted by fm...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java
new file mode 100644
index 0000000..2c0e737
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityCreateRequestImpl.java
@@ -0,0 +1,125 @@
+/*
+ * 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.communication.request.cud;
+
+import java.io.InputStream;
+import java.net.URI;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest;
+import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
+import org.apache.olingo.client.api.domain.ODataEntity;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.api.utils.URIUtils;
+import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
+import org.apache.olingo.client.core.communication.response.ODataResponseImpl;
+
+/**
+ * This class implements an OData create request.
+ */
+public class ODataEntityCreateRequestImpl extends AbstractODataBasicRequest<ODataEntityCreateResponse, ODataPubFormat>
+        implements ODataEntityCreateRequest, ODataBatchableRequest {
+
+  /**
+   * Entity to be created.
+   */
+  private final ODataEntity entity;
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param targetURI entity set URI.
+   * @param entity entity to be created.
+   */
+  ODataEntityCreateRequestImpl(final ODataClient odataClient, final URI targetURI, final ODataEntity entity) {
+    super(odataClient, ODataPubFormat.class, HttpMethod.POST, targetURI);
+    this.entity = entity;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected InputStream getPayload() {
+    return odataClient.getWriter().writeEntity(entity, ODataPubFormat.fromString(getContentType()));
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataEntityCreateResponse execute() {
+    final InputStream input = getPayload();
+    ((HttpPost) request).setEntity(URIUtils.buildInputStreamEntity(odataClient, input));
+
+    try {
+      return new ODataEntityCreateResponseImpl(httpClient, doExecute());
+    } finally {
+      IOUtils.closeQuietly(input);
+    }
+  }
+
+  /**
+   * Response class about an ODataEntityCreateRequest.
+   */
+  private class ODataEntityCreateResponseImpl extends ODataResponseImpl implements ODataEntityCreateResponse {
+
+    private ODataEntity entity = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataEntityCreateResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataEntityCreateResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public ODataEntity getBody() {
+      if (entity == null) {
+        try {
+          entity = odataClient.getReader().
+                  readEntity(getRawResponse(), ODataPubFormat.fromString(getAccept()));
+        } finally {
+          this.close();
+        }
+      }
+      return entity;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java
new file mode 100644
index 0000000..7c36d8d
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataEntityUpdateRequestImpl.java
@@ -0,0 +1,131 @@
+/*
+ * 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.communication.request.cud;
+
+import java.io.InputStream;
+import java.net.URI;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
+import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
+import org.apache.olingo.client.api.domain.ODataEntity;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.api.utils.URIUtils;
+import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
+import org.apache.olingo.client.core.communication.response.ODataResponseImpl;
+
+/**
+ * This class implements an OData update request.
+ */
+public class ODataEntityUpdateRequestImpl extends AbstractODataBasicRequest<ODataEntityUpdateResponse, ODataPubFormat>
+        implements ODataEntityUpdateRequest, ODataBatchableRequest {
+
+  /**
+   * Changes to be applied.
+   */
+  private final ODataEntity changes;
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param method request method.
+   * @param uri URI of the entity to be updated.
+   * @param changes changes to be applied.
+   */
+  ODataEntityUpdateRequestImpl(final ODataClient odataClient,
+          final HttpMethod method, final URI uri, final ODataEntity changes) {
+
+    super(odataClient, ODataPubFormat.class, method, uri);
+    this.changes = changes;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataEntityUpdateResponse execute() {
+    final InputStream input = getPayload();
+    ((HttpEntityEnclosingRequestBase) request).setEntity(URIUtils.buildInputStreamEntity(odataClient, input));
+
+    try {
+      return new ODataEntityUpdateResponseImpl(httpClient, doExecute());
+    } finally {
+      IOUtils.closeQuietly(input);
+    }
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected InputStream getPayload() {
+    return odataClient.getWriter().writeEntity(changes, ODataPubFormat.fromString(getContentType()));
+  }
+
+  /**
+   * Response class about an ODataEntityUpdateRequest.
+   */
+  private class ODataEntityUpdateResponseImpl extends ODataResponseImpl implements ODataEntityUpdateResponse {
+
+    /**
+     * Changes.
+     */
+    private ODataEntity entity = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataEntityUpdateResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataEntityUpdateResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc ]
+     */
+    @Override
+    public ODataEntity getBody() {
+      if (entity == null) {
+        try {
+          entity = odataClient.getReader().
+                  readEntity(getRawResponse(), ODataPubFormat.fromString(getAccept()));
+        } finally {
+          this.close();
+        }
+      }
+      return entity;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataLinkCreateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataLinkCreateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataLinkCreateRequestImpl.java
new file mode 100644
index 0000000..fc52e93
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataLinkCreateRequestImpl.java
@@ -0,0 +1,108 @@
+/*
+ * 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.communication.request.cud;
+
+import java.io.InputStream;
+import java.net.URI;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+import org.apache.olingo.client.api.communication.request.cud.ODataLinkCreateRequest;
+import org.apache.olingo.client.api.communication.response.ODataLinkOperationResponse;
+import org.apache.olingo.client.api.domain.ODataLink;
+import org.apache.olingo.client.api.format.ODataFormat;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.api.utils.URIUtils;
+import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
+import org.apache.olingo.client.core.communication.response.ODataResponseImpl;
+
+/**
+ * This class implements an insert link OData request.
+ */
+public class ODataLinkCreateRequestImpl extends AbstractODataBasicRequest<ODataLinkOperationResponse, ODataFormat>
+        implements ODataLinkCreateRequest, ODataBatchableRequest {
+
+  /**
+   * OData entity to be linked.
+   */
+  private final ODataLink link;
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param targetURI entity set URI.
+   * @param link entity to be linked.
+   */
+  ODataLinkCreateRequestImpl(final ODataClient odataClient, final URI targetURI, final ODataLink link) {
+    super(odataClient, ODataFormat.class, HttpMethod.POST, targetURI);
+    // set request body
+    this.link = link;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ODataLinkOperationResponse execute() {
+    final InputStream input = getPayload();
+    ((HttpPost) request).setEntity(URIUtils.buildInputStreamEntity(odataClient, input));
+
+    try {
+      return new ODataLinkCreateResponseImpl(httpClient, doExecute());
+    } finally {
+      IOUtils.closeQuietly(input);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  protected InputStream getPayload() {
+    return odataClient.getWriter().writeLink(link, ODataFormat.fromString(getContentType()));
+  }
+
+  /**
+   * This class implements the response to an OData link operation request.
+   */
+  private class ODataLinkCreateResponseImpl extends ODataResponseImpl implements ODataLinkOperationResponse {
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataLinkCreateResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataLinkCreateResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataLinkUpdateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataLinkUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataLinkUpdateRequestImpl.java
new file mode 100644
index 0000000..c7c1bc8
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataLinkUpdateRequestImpl.java
@@ -0,0 +1,111 @@
+/*
+ * 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.communication.request.cud;
+
+import java.io.InputStream;
+import java.net.URI;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+import org.apache.olingo.client.api.communication.request.cud.ODataLinkUpdateRequest;
+import org.apache.olingo.client.api.communication.response.ODataLinkOperationResponse;
+import org.apache.olingo.client.api.domain.ODataLink;
+import org.apache.olingo.client.api.format.ODataFormat;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.api.utils.URIUtils;
+import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
+import org.apache.olingo.client.core.communication.response.ODataResponseImpl;
+
+/**
+ * This class implements an update link OData request.
+ */
+public class ODataLinkUpdateRequestImpl extends AbstractODataBasicRequest<ODataLinkOperationResponse, ODataFormat>
+        implements ODataLinkUpdateRequest, ODataBatchableRequest {
+
+  /**
+   * Entity to be linked.
+   */
+  private final ODataLink link;
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param method request method.
+   * @param targetURI entity URI.
+   * @param link entity to be linked.
+   */
+  ODataLinkUpdateRequestImpl(final ODataClient odataClient,
+          final HttpMethod method, final URI targetURI, final ODataLink link) {
+
+    super(odataClient, ODataFormat.class, method, targetURI);
+    // set request body
+    this.link = link;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataLinkOperationResponse execute() {
+    final InputStream input = getPayload();
+    ((HttpEntityEnclosingRequestBase) request).setEntity(URIUtils.buildInputStreamEntity(odataClient, input));
+
+    try {
+      return new ODataLinkUpdateResponseImpl(httpClient, doExecute());
+    } finally {
+      IOUtils.closeQuietly(input);
+    }
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected InputStream getPayload() {
+    return odataClient.getWriter().writeLink(link, ODataFormat.fromString(getContentType()));
+  }
+
+  /**
+   * This class implements the response to an OData link operation request.
+   */
+  public class ODataLinkUpdateResponseImpl extends ODataResponseImpl implements ODataLinkOperationResponse {
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataLinkUpdateResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    public ODataLinkUpdateResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java
new file mode 100644
index 0000000..597c6dd
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataPropertyUpdateRequestImpl.java
@@ -0,0 +1,129 @@
+/*
+ * 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.communication.request.cud;
+
+import java.io.InputStream;
+import java.net.URI;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+import org.apache.olingo.client.api.communication.request.cud.ODataPropertyUpdateRequest;
+import org.apache.olingo.client.api.communication.response.ODataPropertyUpdateResponse;
+import org.apache.olingo.client.api.domain.ODataProperty;
+import org.apache.olingo.client.api.format.ODataFormat;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.api.utils.URIUtils;
+import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
+import org.apache.olingo.client.core.communication.response.ODataResponseImpl;
+
+/**
+ * This class implements an OData update entity property request.
+ */
+public class ODataPropertyUpdateRequestImpl extends AbstractODataBasicRequest<ODataPropertyUpdateResponse, ODataFormat>
+        implements ODataPropertyUpdateRequest, ODataBatchableRequest {
+
+  /**
+   * Value to be created.
+   */
+  private final ODataProperty property;
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param method request method.
+   * @param targetURI entity set or entity or entity property URI.
+   * @param property value to be created.
+   */
+  ODataPropertyUpdateRequestImpl(final ODataClient odataClient,
+          final HttpMethod method, final URI targetURI, final ODataProperty property) {
+
+    super(odataClient, ODataFormat.class, method, targetURI);
+    // set request body
+    this.property = property;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataPropertyUpdateResponse execute() {
+    final InputStream input = getPayload();
+    ((HttpEntityEnclosingRequestBase) request).setEntity(URIUtils.buildInputStreamEntity(odataClient, input));
+
+    try {
+      return new ODataPropertyUpdateResponseImpl(httpClient, doExecute());
+    } finally {
+      IOUtils.closeQuietly(input);
+    }
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected InputStream getPayload() {
+    return odataClient.getWriter().writeProperty(property, ODataFormat.fromString(getContentType()));
+  }
+
+  /**
+   * Response class about an ODataPropertyUpdateRequest.
+   */
+  private class ODataPropertyUpdateResponseImpl extends ODataResponseImpl implements ODataPropertyUpdateResponse {
+
+    private ODataProperty property = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataPropertyUpdateResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataPropertyUpdateResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public ODataProperty getBody() {
+      if (property == null) {
+        try {
+          property = odataClient.getReader().
+                  readProperty(getRawResponse(), ODataFormat.fromString(getAccept()));
+        } finally {
+          this.close();
+        }
+      }
+      return property;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataValueUpdateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataValueUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataValueUpdateRequestImpl.java
new file mode 100644
index 0000000..90d3f37
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/ODataValueUpdateRequestImpl.java
@@ -0,0 +1,140 @@
+/*
+ * 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.communication.request.cud;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+import org.apache.olingo.client.api.communication.request.cud.ODataValueUpdateRequest;
+import org.apache.olingo.client.api.communication.response.ODataValueUpdateResponse;
+import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
+import org.apache.olingo.client.api.domain.ODataPrimitiveValue;
+import org.apache.olingo.client.api.domain.ODataValue;
+import org.apache.olingo.client.api.format.ODataValueFormat;
+import org.apache.olingo.client.api.http.HttpClientException;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.api.utils.URIUtils;
+import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
+import org.apache.olingo.client.core.communication.response.ODataResponseImpl;
+
+/**
+ * This class implements an OData update entity property value request.
+ */
+public class ODataValueUpdateRequestImpl extends AbstractODataBasicRequest<ODataValueUpdateResponse, ODataValueFormat>
+        implements ODataValueUpdateRequest, ODataBatchableRequest {
+
+  /**
+   * Value to be created.
+   */
+  private final ODataValue value;
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param method request method.
+   * @param targetURI entity set or entity or entity property URI.
+   * @param value value to be created.
+   */
+  ODataValueUpdateRequestImpl(final ODataClient odataClient,
+          final HttpMethod method, final URI targetURI, final ODataValue value) {
+
+    super(odataClient, ODataValueFormat.class, method, targetURI);
+    // set request body
+    this.value = value;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataValueUpdateResponse execute() {
+    final InputStream input = getPayload();
+    ((HttpEntityEnclosingRequestBase) request).setEntity(URIUtils.buildInputStreamEntity(odataClient, input));
+
+    try {
+      return new ODataValueUpdateResponseImpl(httpClient, doExecute());
+    } finally {
+      IOUtils.closeQuietly(input);
+    }
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected InputStream getPayload() {
+    return IOUtils.toInputStream(value.toString());
+  }
+
+  /**
+   * Response class about an ODataValueUpdateRequest.
+   */
+  private class ODataValueUpdateResponseImpl extends ODataResponseImpl implements ODataValueUpdateResponse {
+
+    private ODataValue value = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataValueUpdateResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataValueUpdateResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public ODataValue getBody() {
+      if (value == null) {
+        final ODataValueFormat format = ODataValueFormat.fromString(getAccept());
+
+        try {
+          value = new ODataPrimitiveValue.Builder(odataClient).
+                  setType(format == ODataValueFormat.TEXT
+                  ? ODataJClientEdmPrimitiveType.String : ODataJClientEdmPrimitiveType.Stream).
+                  setText(IOUtils.toString(getRawResponse())).
+                  build();
+        } catch (IOException e) {
+          throw new HttpClientException(e);
+        } finally {
+          this.close();
+        }
+      }
+      return value;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/V3CUDRequestFactoryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/V3CUDRequestFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/V3CUDRequestFactoryImpl.java
new file mode 100644
index 0000000..a4d06b5
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/V3CUDRequestFactoryImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.communication.request.cud;
+
+import org.apache.olingo.client.api.ODataV3Client;
+import org.apache.olingo.client.api.communication.request.cud.V3CUDRequestFactory;
+
+public class V3CUDRequestFactoryImpl extends AbstractCUDRequestFactory
+        implements V3CUDRequestFactory {
+
+  private static final long serialVersionUID = 109196636064983035L;
+
+  public V3CUDRequestFactoryImpl(final ODataV3Client client) {
+    super(client);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/V4CUDRequestFactoryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/V4CUDRequestFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/V4CUDRequestFactoryImpl.java
new file mode 100644
index 0000000..fbbde56
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/V4CUDRequestFactoryImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.communication.request.cud;
+
+import org.apache.olingo.client.api.ODataV4Client;
+import org.apache.olingo.client.api.communication.request.cud.V4CUDRequestFactory;
+
+public class V4CUDRequestFactoryImpl extends AbstractCUDRequestFactory
+        implements V4CUDRequestFactory {
+
+  private static final long serialVersionUID = 3080623853913380425L;
+
+  public V4CUDRequestFactoryImpl(final ODataV4Client client) {
+    super(client);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/AbstractInvokeRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/AbstractInvokeRequestFactory.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/AbstractInvokeRequestFactory.java
new file mode 100644
index 0000000..c006ed1
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/AbstractInvokeRequestFactory.java
@@ -0,0 +1,51 @@
+/*
+ * 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.communication.request.invoke;
+
+import java.net.URI;
+import java.util.Map;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.invoke.InvokeRequestFactory;
+import org.apache.olingo.client.api.communication.request.invoke.ODataInvokeRequest;
+import org.apache.olingo.client.api.domain.ODataInvokeResult;
+import org.apache.olingo.client.api.domain.ODataValue;
+import org.apache.olingo.client.api.edm.xml.CommonFunctionImport;
+import org.apache.olingo.client.api.edm.xml.XMLMetadata;
+
+abstract class AbstractInvokeRequestFactory<FI extends CommonFunctionImport> implements InvokeRequestFactory<FI> {
+
+  private static final long serialVersionUID = -906760270085197249L;
+
+  protected final ODataClient client;
+
+  protected AbstractInvokeRequestFactory(final ODataClient client) {
+    this.client = client;
+  }
+
+  @Override
+  public <RES extends ODataInvokeResult> ODataInvokeRequest<RES> getInvokeRequest(
+          final URI uri,
+          final XMLMetadata metadata,
+          final FI functionImport,
+          final Map<String, ODataValue> parameters) {
+    final ODataInvokeRequest<RES> result = getInvokeRequest(uri, metadata, functionImport);
+    result.setParameters(parameters);
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java
new file mode 100644
index 0000000..b03e623
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/ODataInvokeRequestImpl.java
@@ -0,0 +1,235 @@
+/*
+ * 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.communication.request.invoke;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+import org.apache.olingo.client.api.communication.request.invoke.ODataInvokeRequest;
+import org.apache.olingo.client.api.communication.request.invoke.ODataNoContent;
+import org.apache.olingo.client.api.communication.response.ODataInvokeResponse;
+import org.apache.olingo.client.api.domain.ODataEntity;
+import org.apache.olingo.client.api.domain.ODataEntitySet;
+import org.apache.olingo.client.api.domain.ODataInvokeResult;
+import org.apache.olingo.client.api.domain.ODataProperty;
+import org.apache.olingo.client.api.domain.ODataValue;
+import org.apache.olingo.client.api.format.ODataFormat;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+import org.apache.olingo.client.api.http.HttpClientException;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.api.utils.URIUtils;
+import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
+import org.apache.olingo.client.core.communication.response.ODataResponseImpl;
+
+/**
+ * This class implements an OData invoke operation request.
+ */
+public class ODataInvokeRequestImpl<T extends ODataInvokeResult>
+        extends AbstractODataBasicRequest<ODataInvokeResponse<T>, ODataPubFormat>
+        implements ODataInvokeRequest<T>, ODataBatchableRequest {
+
+  private final Class<T> reference;
+
+  /**
+   * Function parameters.
+   */
+  private Map<String, ODataValue> parameters;
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param reference reference class for invoke result
+   * @param method HTTP method of the request.
+   * @param uri URI that identifies the operation.
+   */
+  ODataInvokeRequestImpl(
+          final ODataClient odataClient,
+          final Class<T> reference,
+          final HttpMethod method,
+          final URI uri) {
+
+    super(odataClient, ODataPubFormat.class, method, uri);
+
+    this.reference = reference;
+    this.parameters = new LinkedHashMap<String, ODataValue>();
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public void setParameters(final Map<String, ODataValue> parameters) {
+    this.parameters.clear();
+    if (parameters != null && !parameters.isEmpty()) {
+      this.parameters.putAll(parameters);
+    }
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public void setFormat(final ODataPubFormat format) {
+    final String _format = (reference.isAssignableFrom(ODataProperty.class) && format == ODataPubFormat.ATOM)
+            ? ODataFormat.XML.toString()
+            : format.toString();
+    setAccept(_format);
+    setContentType(_format);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  protected InputStream getPayload() {
+    if (!this.parameters.isEmpty() && this.method == HttpMethod.POST) {
+      // Additional, non-binding parameters MUST be sent as JSON
+      final ODataEntity tmp = odataClient.getObjectFactory().newEntity("");
+      for (Map.Entry<String, ODataValue> param : parameters.entrySet()) {
+        ODataProperty property = null;
+
+        if (param.getValue().isPrimitive()) {
+          property = odataClient.getObjectFactory().
+                  newPrimitiveProperty(param.getKey(), param.getValue().asPrimitive());
+        } else if (param.getValue().isComplex()) {
+          property = odataClient.getObjectFactory().
+                  newComplexProperty(param.getKey(), param.getValue().asComplex());
+        } else if (param.getValue().isCollection()) {
+          property = odataClient.getObjectFactory().
+                  newCollectionProperty(param.getKey(), param.getValue().asCollection());
+        }
+
+        if (property != null) {
+          tmp.getProperties().add(property);
+        }
+      }
+
+      return odataClient.getWriter().writeEntity(tmp, ODataPubFormat.JSON, false);
+    }
+
+    return null;
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataInvokeResponse<T> execute() {
+    final InputStream input = getPayload();
+
+    if (!this.parameters.isEmpty()) {
+      if (this.method == HttpMethod.GET) {
+        final URIBuilder uriBuilder = new URIBuilder(this.uri);
+        for (Map.Entry<String, ODataValue> param : parameters.entrySet()) {
+          if (!param.getValue().isPrimitive()) {
+            throw new IllegalArgumentException("Only primitive values can be passed via GET");
+          }
+
+          uriBuilder.addParameter(param.getKey(), param.getValue().toString());
+        }
+        try {
+          ((HttpRequestBase) this.request).setURI(uriBuilder.build());
+        } catch (URISyntaxException e) {
+          throw new IllegalArgumentException("While adding GET parameters", e);
+        }
+      } else if (this.method == HttpMethod.POST) {
+        ((HttpPost) request).setEntity(URIUtils.buildInputStreamEntity(odataClient, input));
+
+        setContentType(ODataPubFormat.JSON.toString());
+      }
+    }
+
+    try {
+      return new ODataInvokeResponseImpl(httpClient, doExecute());
+    } finally {
+      IOUtils.closeQuietly(input);
+    }
+  }
+
+  /**
+   * Response class about an ODataInvokeRequest.
+   */
+  protected class ODataInvokeResponseImpl extends ODataResponseImpl implements ODataInvokeResponse<T> {
+
+    private T invokeResult = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataInvokeResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataInvokeResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public T getBody() {
+      if (invokeResult == null) {
+        if (reference.isAssignableFrom(ODataNoContent.class)) {
+          invokeResult = (T) new ODataNoContent();
+        }
+
+        try {
+          if (reference.isAssignableFrom(ODataEntitySet.class)) {
+            invokeResult = (T) odataClient.getReader().readEntitySet(res.getEntity().getContent(),
+                    ODataPubFormat.fromString(getContentType()));
+          }
+          if (reference.isAssignableFrom(ODataEntity.class)) {
+            invokeResult = (T) odataClient.getReader().readEntity(res.getEntity().getContent(),
+                    ODataPubFormat.fromString(getContentType()));
+          }
+          if (reference.isAssignableFrom(ODataProperty.class)) {
+            invokeResult = (T) odataClient.getReader().readProperty(res.getEntity().getContent(),
+                    ODataFormat.fromString(getContentType()));
+          }
+        } catch (IOException e) {
+          throw new HttpClientException(e);
+        } finally {
+          this.close();
+        }
+      }
+      return invokeResult;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/V3InvokeRequestFactoryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/V3InvokeRequestFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/V3InvokeRequestFactoryImpl.java
new file mode 100644
index 0000000..34203de
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/V3InvokeRequestFactoryImpl.java
@@ -0,0 +1,89 @@
+/*
+ * 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.communication.request.invoke;
+
+import java.net.URI;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.client.api.ODataV3Client;
+import org.apache.olingo.client.api.communication.request.invoke.ODataInvokeRequest;
+import org.apache.olingo.client.api.communication.request.invoke.ODataNoContent;
+import org.apache.olingo.client.api.communication.request.invoke.V3InvokeRequestFactory;
+import org.apache.olingo.client.api.domain.ODataEntity;
+import org.apache.olingo.client.api.domain.ODataEntitySet;
+import org.apache.olingo.client.api.domain.ODataInvokeResult;
+import org.apache.olingo.client.api.domain.ODataJClientEdmType;
+import org.apache.olingo.client.api.domain.ODataProperty;
+import org.apache.olingo.client.api.edm.xml.XMLMetadata;
+import org.apache.olingo.client.api.edm.xml.v3.FunctionImport;
+import org.apache.olingo.client.api.http.HttpMethod;
+
+public class V3InvokeRequestFactoryImpl extends AbstractInvokeRequestFactory<FunctionImport>
+        implements V3InvokeRequestFactory {
+
+  private static final long serialVersionUID = -659256862901915496L;
+
+  public V3InvokeRequestFactoryImpl(final ODataV3Client client) {
+    super(client);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  @SuppressWarnings("unchecked")
+  public <RES extends ODataInvokeResult> ODataInvokeRequest<RES> getInvokeRequest(
+          final URI uri,
+          final XMLMetadata metadata,
+          final FunctionImport functionImport) {
+
+    HttpMethod method = null;
+    if (HttpMethod.GET.name().equals(functionImport.getHttpMethod())) {
+      method = HttpMethod.GET;
+    } else if (HttpMethod.POST.name().equals(functionImport.getHttpMethod())) {
+      method = HttpMethod.POST;
+    } else if (functionImport.getHttpMethod() == null) {
+      if (functionImport.isSideEffecting()) {
+        method = HttpMethod.POST;
+      } else {
+        method = HttpMethod.GET;
+      }
+    }
+
+    ODataInvokeRequest<RES> result;
+    if (StringUtils.isBlank(functionImport.getReturnType())) {
+      result = (ODataInvokeRequest<RES>) new ODataInvokeRequestImpl<ODataNoContent>(
+              client, ODataNoContent.class, method, uri);
+    } else {
+      final ODataJClientEdmType returnType = new ODataJClientEdmType(metadata, functionImport.getReturnType());
+
+      if (returnType.isCollection() && returnType.isEntityType()) {
+        result = (ODataInvokeRequest<RES>) new ODataInvokeRequestImpl<ODataEntitySet>(
+                client, ODataEntitySet.class, method, uri);
+      } else if (!returnType.isCollection() && returnType.isEntityType()) {
+        result = (ODataInvokeRequest<RES>) new ODataInvokeRequestImpl<ODataEntity>(
+                client, ODataEntity.class, method, uri);
+      } else {
+        result = (ODataInvokeRequest<RES>) new ODataInvokeRequestImpl<ODataProperty>(
+                client, ODataProperty.class, method, uri);
+      }
+    }
+
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/V4InvokeRequestFactoryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/V4InvokeRequestFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/V4InvokeRequestFactoryImpl.java
new file mode 100644
index 0000000..4bbfb56
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/V4InvokeRequestFactoryImpl.java
@@ -0,0 +1,43 @@
+/*
+ * 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.communication.request.invoke;
+
+import java.net.URI;
+import org.apache.olingo.client.api.ODataV4Client;
+import org.apache.olingo.client.api.communication.request.invoke.ODataInvokeRequest;
+import org.apache.olingo.client.api.communication.request.invoke.V4InvokeRequestFactory;
+import org.apache.olingo.client.api.domain.ODataInvokeResult;
+import org.apache.olingo.client.api.edm.xml.XMLMetadata;
+import org.apache.olingo.client.api.edm.xml.v4.FunctionImport;
+
+public class V4InvokeRequestFactoryImpl extends AbstractInvokeRequestFactory<FunctionImport>
+        implements V4InvokeRequestFactory {
+
+  private static final long serialVersionUID = 8452737360003104372L;
+
+  public V4InvokeRequestFactoryImpl(final ODataV4Client client) {
+    super(client);
+  }
+
+  @Override
+  public <RES extends ODataInvokeResult> ODataInvokeRequest<RES> getInvokeRequest(
+          final URI uri, final XMLMetadata metadata, final FunctionImport functionImport) {
+    throw new UnsupportedOperationException("Not supported yet.");
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
new file mode 100644
index 0000000..bd5166a
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractODataRetrieveRequest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.communication.request.retrieve;
+
+import java.io.InputStream;
+import java.net.URI;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataRetrieveRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
+import org.apache.olingo.client.core.communication.response.ODataResponseImpl;
+
+/**
+ * This is an abstract representation of an OData retrieve query request returning one or more result item. Get instance
+ * by using ODataRetrieveRequestFactory.
+ */
+abstract class AbstractODataRetrieveRequest<V, T extends Enum<T>>
+        extends AbstractODataBasicRequest<ODataRetrieveResponse<V>, T>
+        implements ODataRetrieveRequest<V, T>, ODataBatchableRequest {
+
+  /**
+   * Private constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param formatRef reference class for the format being used
+   * @param query query to be executed.
+   */
+  AbstractODataRetrieveRequest(final ODataClient odataClient, final Class<T> formatRef, final URI query) {
+    super(odataClient, formatRef, HttpMethod.GET, query);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public abstract ODataRetrieveResponse<V> execute();
+
+  /**
+   * {@inheritDoc }
+   * <p>
+   * This kind of request doesn't have any payload: null will be returned.
+   */
+  @Override
+  protected InputStream getPayload() {
+    return null;
+  }
+
+  /**
+   * Response abstract class about an ODataRetrieveRequest.
+   */
+  protected abstract class ODataRetrieveResponseImpl extends ODataResponseImpl implements ODataRetrieveResponse<V> {
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    protected ODataRetrieveResponseImpl() {
+      super();
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    protected ODataRetrieveResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public abstract V getBody();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractRetrieveRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractRetrieveRequestFactory.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractRetrieveRequestFactory.java
new file mode 100644
index 0000000..a660208
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/AbstractRetrieveRequestFactory.java
@@ -0,0 +1,98 @@
+/*
+ * 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.communication.request.retrieve;
+
+import java.net.URI;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetIteratorRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataGenericRetrieveRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataMediaRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataMetadataRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataPropertyRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataServiceDocumentRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataValueRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.RetrieveRequestFactory;
+
+public abstract class AbstractRetrieveRequestFactory implements RetrieveRequestFactory {
+
+  private static final long serialVersionUID = -111683263158803362L;
+
+  protected final ODataClient client;
+
+  protected AbstractRetrieveRequestFactory(final ODataClient client) {
+    this.client = client;
+  }
+
+  @Override
+  public ODataEntitySetRequest getEntitySetRequest(final URI query) {
+    return new ODataEntitySetRequestImpl(client, query);
+  }
+
+  @Override
+  public ODataEntitySetIteratorRequest getEntitySetIteratorRequest(final URI query) {
+    return new ODataEntitySetIteratorRequestImpl(client, query);
+  }
+
+  @Override
+  public ODataEntityRequest getEntityRequest(final URI query) {
+    return new ODataEntityRequestImpl(client, query);
+  }
+
+  @Override
+  public ODataPropertyRequest getPropertyRequest(final URI query) {
+    return new ODataPropertyRequestImpl(client, query);
+  }
+
+  @Override
+  public ODataValueRequest getValueRequest(final URI query) {
+    return new ODataValueRequestImpl(client, query);
+  }
+
+  @Override
+  public ODataMediaRequest getMediaRequest(final URI query) {
+    return new ODataMediaRequestImpl(client, query);
+  }
+
+  @Override
+  public ODataRawRequest getRawRequest(final URI uri) {
+    return new ODataRawRequestImpl(client, uri);
+  }
+
+  @Override
+  public ODataMetadataRequest getMetadataRequest(final String serviceRoot) {
+    return new ODataMetadataRequestImpl(client, client.getURIBuilder(serviceRoot).appendMetadataSegment().build());
+  }
+
+  @Override
+  public ODataServiceDocumentRequest getServiceDocumentRequest(final String serviceRoot) {
+    return new ODataServiceDocumentRequestImpl(client,
+            StringUtils.isNotBlank(serviceRoot) && serviceRoot.endsWith("/")
+            ? client.getURIBuilder(serviceRoot).build()
+            : client.getURIBuilder(serviceRoot + "/").build());
+  }
+
+  @Override
+  public ODataGenericRetrieveRequest getGenericRetrieveRequest(final URI uri) {
+    return new ODataGenericRetrieveRequestImpl(client, uri);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/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
new file mode 100644
index 0000000..2a35514
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntityRequestImpl.java
@@ -0,0 +1,95 @@
+/*
+ * 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.communication.request.retrieve;
+
+import java.net.URI;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.domain.ODataEntity;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+
+/**
+ * This class implements an OData retrieve query request returning a single entity.
+ */
+public class ODataEntityRequestImpl extends AbstractODataRetrieveRequest<ODataEntity, ODataPubFormat>
+        implements ODataEntityRequest {
+
+  /**
+   * Private constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param query query to be executed.
+   */
+  ODataEntityRequestImpl(final ODataClient odataClient, final URI query) {
+    super(odataClient, ODataPubFormat.class, query);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataRetrieveResponse<ODataEntity> execute() {
+    return new ODataEntityResponseImpl(httpClient, doExecute());
+  }
+
+  /**
+   * Response class about an ODataEntityRequest.
+   */
+  public class ODataEntityResponseImpl extends ODataRetrieveResponseImpl {
+
+    private ODataEntity entity = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataEntityResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataEntityResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public ODataEntity getBody() {
+      if (entity == null) {
+        try {
+          entity = odataClient.getReader().
+                  readEntity(getRawResponse(), ODataPubFormat.fromString(getContentType()));
+        } finally {
+          this.close();
+        }
+      }
+      return entity;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetIteratorRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetIteratorRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetIteratorRequestImpl.java
new file mode 100644
index 0000000..345f673
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetIteratorRequestImpl.java
@@ -0,0 +1,86 @@
+/*
+ * 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.communication.request.retrieve;
+
+import java.net.URI;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetIteratorRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.domain.ODataEntitySetIterator;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+
+/**
+ * This class implements an OData EntitySet query request.
+ */
+public class ODataEntitySetIteratorRequestImpl
+        extends AbstractODataRetrieveRequest<ODataEntitySetIterator, ODataPubFormat>
+        implements ODataEntitySetIteratorRequest {
+
+  private ODataEntitySetIterator feedIterator = null;
+
+  /**
+   * Private constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param query query to be executed.
+   */
+  ODataEntitySetIteratorRequestImpl(final ODataClient odataClient, final URI query) {
+    super(odataClient, ODataPubFormat.class, query);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataRetrieveResponse<ODataEntitySetIterator> execute() {
+    final HttpResponse res = doExecute();
+    return new ODataEntitySetIteratorResponseImpl(httpClient, res);
+  }
+
+  /**
+   * Response class about an ODataEntitySetIteratorRequest.
+   */
+  protected class ODataEntitySetIteratorResponseImpl extends ODataRetrieveResponseImpl {
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataEntitySetIteratorResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public ODataEntitySetIterator getBody() {
+      if (feedIterator == null) {
+        feedIterator = new ODataEntitySetIterator(
+                odataClient, getRawResponse(), ODataPubFormat.fromString(getContentType()));
+      }
+      return feedIterator;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/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
new file mode 100644
index 0000000..a18cba9
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataEntitySetRequestImpl.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.client.core.communication.request.retrieve;
+
+import java.net.URI;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.domain.ODataEntitySet;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+
+/**
+ * This class implements an OData EntitySet query request.
+ */
+public class ODataEntitySetRequestImpl extends AbstractODataRetrieveRequest<ODataEntitySet, ODataPubFormat>
+        implements ODataEntitySetRequest {
+
+  private ODataEntitySet feed = null;
+
+  /**
+   * Private constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param query query to be executed.
+   */
+  ODataEntitySetRequestImpl(final ODataClient odataClient, final URI query) {
+    super(odataClient, ODataPubFormat.class, query);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataRetrieveResponse<ODataEntitySet> execute() {
+    final HttpResponse res = doExecute();
+    return new ODataEntitySetResponseImpl(httpClient, res);
+  }
+
+  /**
+   * Response class about an ODataEntitySetRequest.
+   */
+  protected class ODataEntitySetResponseImpl extends ODataRetrieveResponseImpl {
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataEntitySetResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataEntitySetResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public ODataEntitySet getBody() {
+      if (feed == null) {
+        try {
+          feed = odataClient.getReader().
+                  readEntitySet(getRawResponse(), ODataPubFormat.fromString(getContentType()));
+        } finally {
+          this.close();
+        }
+      }
+      return feed;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataGenericRetrieveRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataGenericRetrieveRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataGenericRetrieveRequestImpl.java
new file mode 100644
index 0000000..a370881
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataGenericRetrieveRequestImpl.java
@@ -0,0 +1,105 @@
+/*
+ * 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.communication.request.retrieve;
+
+import java.net.URI;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataGenericRetrieveRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.data.ObjectWrapper;
+import org.apache.olingo.client.core.communication.response.ODataResponseImpl;
+
+/**
+ * This class implements a generic OData retrieve query request.
+ */
+public class ODataGenericRetrieveRequestImpl extends ODataRawRequestImpl implements ODataGenericRetrieveRequest {
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param uri query request.
+   */
+  public ODataGenericRetrieveRequestImpl(final ODataClient odataClient, final URI uri) {
+    super(odataClient, uri);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public void setFormat(final String format) {
+    setAccept(format);
+    setContentType(format);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataRetrieveResponse<ObjectWrapper> execute() {
+    return new ODataGenericResponseImpl(httpClient, doExecute());
+  }
+
+  /**
+   * Query response implementation about a generic query request.
+   */
+  protected class ODataGenericResponseImpl extends ODataResponseImpl implements ODataRetrieveResponse<ObjectWrapper> {
+
+    /**
+     * Retrieved object wrapper.
+     */
+    private ObjectWrapper obj = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataGenericResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataGenericResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public ObjectWrapper getBody() {
+      if (obj == null) {
+        try {
+          obj = new ObjectWrapper(odataClient.getReader(), getRawResponse(), getContentType());
+        } finally {
+          this.close();
+        }
+      }
+      return obj;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataLinkCollectionRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataLinkCollectionRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataLinkCollectionRequestImpl.java
new file mode 100644
index 0000000..73e6c67
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataLinkCollectionRequestImpl.java
@@ -0,0 +1,98 @@
+/*
+ * 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.communication.request.retrieve;
+
+import java.io.IOException;
+import java.net.URI;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.ODataV3Client;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataLinkCollectionRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.domain.ODataLinkCollection;
+import org.apache.olingo.client.api.format.ODataFormat;
+import org.apache.olingo.client.api.http.HttpClientException;
+
+/**
+ * This class implements an OData link query request.
+ */
+public class ODataLinkCollectionRequestImpl extends AbstractODataRetrieveRequest<ODataLinkCollection, ODataFormat>
+        implements ODataLinkCollectionRequest {
+
+  /**
+   * Private constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param targetURI target URI.
+   * @param linkName link name.
+   */
+  ODataLinkCollectionRequestImpl(final ODataV3Client odataClient, final URI targetURI, final String linkName) {
+    super(odataClient, ODataFormat.class,
+            odataClient.getURIBuilder(targetURI.toASCIIString()).appendLinksSegment(linkName).build());
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataRetrieveResponse<ODataLinkCollection> execute() {
+    return new ODataLinkCollectionResponseImpl(httpClient, doExecute());
+  }
+
+  protected class ODataLinkCollectionResponseImpl extends ODataRetrieveResponseImpl {
+
+    private ODataLinkCollection links = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataLinkCollectionResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataLinkCollectionResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    public ODataLinkCollection getBody() {
+      if (links == null) {
+        try {
+          links = odataClient.getReader().readLinks(
+                  res.getEntity().getContent(), ODataFormat.fromString(getContentType()));
+        } catch (IOException e) {
+          throw new HttpClientException(e);
+        } finally {
+          this.close();
+        }
+      }
+      return links;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataMediaRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataMediaRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataMediaRequestImpl.java
new file mode 100644
index 0000000..9209f96
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataMediaRequestImpl.java
@@ -0,0 +1,109 @@
+/*
+ * 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.communication.request.retrieve;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.header.HeaderName;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataMediaRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.format.ODataMediaFormat;
+import org.apache.olingo.client.api.http.HttpClientException;
+
+/**
+ * This class implements an OData media query request.
+ */
+public class ODataMediaRequestImpl extends AbstractODataRetrieveRequest<InputStream, ODataMediaFormat>
+        implements ODataMediaRequest {
+
+  /**
+   * Private constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param query query to be executed.
+   */
+  ODataMediaRequestImpl(final ODataClient odataClient, final URI query) {
+    super(odataClient, ODataMediaFormat.class, query);
+
+    setAccept(ODataMediaFormat.APPLICATION_OCTET_STREAM.toString());
+    setContentType(ODataMediaFormat.APPLICATION_OCTET_STREAM.toString());
+
+    this.odataHeaders.removeHeader(HeaderName.minDataServiceVersion);
+    this.odataHeaders.removeHeader(HeaderName.maxDataServiceVersion);
+    this.odataHeaders.removeHeader(HeaderName.dataServiceVersion);
+  }
+
+  /**
+   * {@inheritDoc }
+   */
+  @Override
+  public ODataRetrieveResponse<InputStream> execute() {
+    final HttpResponse res = doExecute();
+    return new ODataMediaResponseImpl(httpClient, res);
+  }
+
+  /**
+   * Response class about an ODataMediaRequest.
+   */
+  protected class ODataMediaResponseImpl extends ODataRetrieveResponseImpl {
+
+    private InputStream input = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    private ODataMediaResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataMediaResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * Gets query result objects.
+     * <br/>
+     * <b>WARNING</b>: Closing this <tt>ODataResponse</tt> instance is left to the caller.
+     *
+     * @return query result objects as <tt>InputStream</tt>.
+     */
+    @Override
+    public InputStream getBody() {
+      if (input == null) {
+        try {
+          input = res.getEntity().getContent();
+        } catch (IOException e) {
+          throw new HttpClientException(e);
+        }
+      }
+      return input;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/d3b05e01/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataMetadataRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataMetadataRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataMetadataRequestImpl.java
new file mode 100644
index 0000000..b51b715
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/retrieve/ODataMetadataRequestImpl.java
@@ -0,0 +1,109 @@
+/*
+ * 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.communication.request.retrieve;
+
+import java.net.URI;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.entity.ContentType;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.request.ODataRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataMetadataRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.client.api.edm.xml.XMLMetadata;
+import org.apache.olingo.client.api.format.ODataPubFormat;
+
+/**
+ * This class implements a metadata query request.
+ */
+class ODataMetadataRequestImpl extends AbstractODataRetrieveRequest<XMLMetadata, ODataPubFormat>
+        implements ODataMetadataRequest {
+
+  /**
+   * Constructor.
+   *
+   * @param odataClient client instance getting this request
+   * @param uri metadata URI.
+   */
+  ODataMetadataRequestImpl(final ODataClient odataClient, final URI uri) {
+    super(odataClient, ODataPubFormat.class, uri);
+    super.setAccept(ContentType.APPLICATION_XML.getMimeType());
+    super.setContentType(ContentType.APPLICATION_XML.getMimeType());
+  }
+
+  @Override
+  public ODataRequest setAccept(final String value) {
+    // do nothing: Accept is application/XML
+    return this;
+  }
+
+  @Override
+  public ODataRequest setContentType(final String value) {
+    // do nothing: Accept is application/XML
+    return this;
+  }
+
+  @Override
+  public ODataRetrieveResponse<XMLMetadata> execute() {
+    final HttpResponse res = doExecute();
+    return new ODataMetadataResponseImpl(httpClient, res);
+  }
+
+  /**
+   * Response class about an ODataMetadataRequest.
+   */
+  protected class ODataMetadataResponseImpl extends ODataRetrieveResponseImpl {
+
+    private XMLMetadata metadata = null;
+
+    /**
+     * Constructor.
+     * <p>
+     * Just to create response templates to be initialized from batch.
+     */
+    public ODataMetadataResponseImpl() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param client HTTP client.
+     * @param res HTTP response.
+     */
+    private ODataMetadataResponseImpl(final HttpClient client, final HttpResponse res) {
+      super(client, res);
+    }
+
+    /**
+     * {@inheritDoc }
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public XMLMetadata getBody() {
+      if (metadata == null) {
+        try {
+          metadata = (XMLMetadata) odataClient.getReader().readMetadata(getRawResponse());
+        } finally {
+          this.close();
+        }
+      }
+      return metadata;
+    }
+  }
+}