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/04/24 10:14:04 UTC

[2/2] git commit: [OLINGO-248] provided V4 asynchronous mechanisms. Still missing verification towards external services

[OLINGO-248] provided V4 asynchronous mechanisms. Still missing verification towards external services


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

Branch: refs/heads/master
Commit: 4f1072a6e0170187778fd3afcec307f36ba5fbfe
Parents: d45a482
Author: fmartelli <fa...@gmail.com>
Authored: Thu Apr 24 10:13:48 2014 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Thu Apr 24 10:13:48 2014 +0200

----------------------------------------------------------------------
 .../org/apache/olingo/fit/AbstractServices.java |   1 -
 .../java/org/apache/olingo/fit/V4Services.java  |  68 +++
 .../olingo/fit/utils/AbstractUtilities.java     |  39 +-
 .../main/resources/V40/Customers/feed.full.json |  89 ++++
 fit/src/main/resources/V40/Customers/feed.xml   | 103 ++++
 .../request/cud/ODataDeleteRequest.java         |   4 +-
 .../request/cud/ODataPropertyUpdateRequest.java |   4 +-
 .../request/cud/ODataValueUpdateRequest.java    |   4 +-
 .../request/cud/v3/ODataLinkCreateRequest.java  |   4 +-
 .../request/cud/v3/ODataLinkUpdateRequest.java  |   4 +-
 .../streamed/ODataStreamUpdateRequest.java      |   6 +-
 .../request/v4/AsyncRequestFactory.java         |  28 ++
 .../request/v4/AsyncRequestWrapper.java         |  40 ++
 .../communication/response/ODataResponse.java   |  20 +-
 .../response/v4/AsyncResponse.java              |  24 +
 .../response/v4/AsyncResponseWrapper.java       |  69 +++
 .../olingo/client/api/v4/ODataClient.java       |   3 +
 .../request/AbstractODataBasicRequest.java      |   2 +-
 .../request/AbstractODataRequest.java           | 433 +++++++++++++++++
 .../communication/request/AbstractRequest.java  |  84 ++++
 .../communication/request/ODataRequestImpl.java | 486 -------------------
 .../batch/AbstractODataBatchRequest.java        |   2 +-
 .../request/batch/ODataChangesetImpl.java       |   4 +-
 .../request/batch/ODataRetrieveImpl.java        |   6 +-
 .../request/batch/v3/ODataBatchRequestImpl.java |   2 +-
 .../batch/v4/ODataOutsideUpdateImpl.java        |   6 +-
 .../request/cud/ODataDeleteRequestImpl.java     |   3 +-
 .../cud/ODataEntityCreateRequestImpl.java       |   2 +-
 .../cud/ODataPropertyUpdateRequestImpl.java     |   3 +-
 .../cud/ODataValueUpdateRequestImpl.java        |   5 +-
 .../cud/v3/ODataLinkCreateRequestImpl.java      |   3 +-
 .../cud/v3/ODataLinkUpdateRequestImpl.java      |   3 +-
 .../AbstractRetrieveRequestFactory.java         |   4 +-
 .../request/retrieve/ODataRawRequestImpl.java   |   4 +-
 .../streamed/AbstractODataStreamedRequest.java  |   4 +-
 .../streamed/ODataStreamUpdateRequestImpl.java  |   3 +-
 .../request/v4/AsyncRequestException.java       |  28 ++
 .../request/v4/AsyncRequestFactoryImpl.java     |  42 ++
 .../request/v4/AsyncRequestWrapperImpl.java     | 302 ++++++++++++
 .../response/AbstractODataResponse.java         | 122 +++--
 .../response/batch/ODataBatchErrorResponse.java | 196 +-------
 .../response/v4/AsyncResponseImpl.java          |  49 ++
 .../apache/olingo/client/core/uri/URIUtils.java |   2 +-
 .../olingo/client/core/v4/ODataClientImpl.java  |   9 +
 .../client/core/it/v3/AsyncTestITCase.java      |   4 +-
 .../client/core/it/v4/AsyncTestITCase.java      | 164 +++++++
 .../client/core/it/v4/BatchTestITCase.java      |  20 +-
 .../api/domain/ODataCollectionValue.java        |   2 +-
 .../commons/api/domain/ODataComplexValue.java   |   2 +-
 .../domain/AbstractODataCollectionValue.java    |   5 +-
 .../core/domain/AbstractODataComplexValue.java  |   6 +-
 .../domain/v3/ODataCollectionValueImpl.java     |   4 +
 .../core/domain/v3/ODataComplexValueImpl.java   |   5 +
 .../domain/v4/ODataCollectionValueImpl.java     |   5 +
 .../core/domain/v4/ODataComplexValueImpl.java   |   7 +-
 55 files changed, 1767 insertions(+), 776 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
index 6ff2c11..ca2fd84 100644
--- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
+++ b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
@@ -209,7 +209,6 @@ public abstract class AbstractServices {
           final @Multipart MultipartBody attachment) {
     try {
       final boolean continueOnError = prefer.contains("odata.continue-on-error");
-
       return xml.createBatchResponse(
               exploreMultipart(attachment.getAllAttachments(), BOUNDARY, continueOnError), BOUNDARY);
     } catch (IOException e) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/fit/src/main/java/org/apache/olingo/fit/V4Services.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/V4Services.java b/fit/src/main/java/org/apache/olingo/fit/V4Services.java
index 60c2e05..5b51a9f 100644
--- a/fit/src/main/java/org/apache/olingo/fit/V4Services.java
+++ b/fit/src/main/java/org/apache/olingo/fit/V4Services.java
@@ -43,6 +43,7 @@ import javax.ws.rs.PathParam;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriInfo;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.io.IOUtils;
@@ -80,10 +81,77 @@ import org.springframework.stereotype.Service;
 @InInterceptors(classes = {XHTTPMethodInterceptor.class, ResolvingReferencesInterceptor.class})
 public class V4Services extends AbstractServices {
 
+  /**
+   * CR/LF.
+   */
+  public static final byte[] CRLF = {13, 10};
+
+  private Map<String, String> providedAsync = new HashMap<String, String>();
+
   public V4Services() throws Exception {
     super(ODataServiceVersion.V40);
   }
 
+  @DELETE
+  @Path("/monitor/{name}")
+  public Response removeMonitor(@Context final UriInfo uriInfo, @PathParam("name") final String name) {
+    providedAsync.remove(name);
+    return xml.createResponse(null, null, null, Status.NO_CONTENT);
+  }
+
+  @GET
+  @Path("/monitor/{name}")
+  public Response async(@Context final UriInfo uriInfo, @PathParam("name") final String name) {
+    try {
+      if (!providedAsync.containsKey(name)) {
+        throw new NotFoundException();
+      }
+      final InputStream res = IOUtils.toInputStream(providedAsync.get(name));
+      providedAsync.remove(name);
+      return xml.createMonitorResponse(res);
+    } catch (Exception e) {
+      return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(), e);
+    }
+  }
+
+  @GET
+  @Path("/async/{name}")
+  public Response async(
+          @Context final UriInfo uriInfo,
+          @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+          @PathParam("name") final String name) {
+
+    try {
+      final Accept acceptType = Accept.parse(accept, version);
+      if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+        throw new UnsupportedMediaTypeException("Unsupported media type");
+      }
+
+      final String basePath = name + File.separatorChar;
+      final StringBuilder path = new StringBuilder(basePath);
+
+      path.append(getMetadataObj().getEntitySet(name).isSingleton()
+              ? Constants.get(version, ConstantKey.ENTITY)
+              : Constants.get(version, ConstantKey.FEED));
+
+      final InputStream feed = FSManager.instance(version).readFile(path.toString(), acceptType);
+
+      final StringBuilder builder = new StringBuilder();
+      builder.append("HTTP/1.1 200 Ok").append(new String(CRLF));
+      builder.append("Content-Type: ").append(accept).append(new String(CRLF)).append(new String(CRLF));
+      builder.append(IOUtils.toString(feed));
+      IOUtils.closeQuietly(feed);
+
+      final UUID uuid = UUID.randomUUID();
+      providedAsync.put(uuid.toString(), builder.toString());
+
+      return xml.createAsyncResponse(
+              uriInfo.getRequestUri().toASCIIString().replaceAll("async/" + name, "") + "monitor/" + uuid.toString());
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
   @Override
   protected void setInlineCount(final Feed feed, final String count) {
     if ("true".equals(count)) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
index 6a1dc10..804c7c2 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
@@ -292,8 +292,8 @@ public abstract class AbstractUtilities {
     final List<String> hrefs = new ArrayList<String>();
 
     for (final Link link : entry.getNavigationLinks()) {
-      final NavigationProperty navProp = navigationProperties == null
-              ? null : navigationProperties.get(link.getTitle());
+      final NavigationProperty navProp =
+              navigationProperties == null ? null : navigationProperties.get(link.getTitle());
       if (navProp != null) {
         final String inlineEntitySetName = navProp.getTarget();
         if (link.getInlineEntry() != null) {
@@ -407,7 +407,7 @@ public abstract class AbstractUtilities {
 
     fsManager.putInMemory(
             IOUtils.toInputStream(entity), fsManager.getAbsolutePath(path + Constants.get(version, ConstantKey.ENTITY),
-                    Accept.JSON_FULLMETA));
+            Accept.JSON_FULLMETA));
     // -----------------------------------------
 
     return readEntity(entitySetName, entityKey, getDefaultFormat()).getValue();
@@ -456,6 +456,31 @@ public abstract class AbstractUtilities {
     return createResponse(location, entity, etag, accept, null);
   }
 
+  public Response createAsyncResponse(final String location) {
+    final Response.ResponseBuilder builder = Response.accepted();
+    if (version.compareTo(ODataServiceVersion.V30) <= 0) {
+      builder.header(Constants.get(version, ConstantKey.ODATA_SERVICE_VERSION), version.toString() + ";");
+    }
+
+    builder.header("Location", location);
+    builder.header("Preference-Applied", "Respond-Async");
+    builder.header("Retry-After", "10");
+
+    return builder.build();
+  }
+
+  public Response createMonitorResponse(final InputStream res) {
+    final Response.ResponseBuilder builder = Response.ok();
+    if (version.compareTo(ODataServiceVersion.V30) <= 0) {
+      builder.header(Constants.get(version, ConstantKey.ODATA_SERVICE_VERSION), version.toString() + ";");
+    }
+
+    builder.header("Content-Type", "application/http");
+    builder.header("Content-Transfer-Encoding", "binary");
+
+    return builder.entity(res).build();
+  }
+
   public Response createResponse(final InputStream entity, final String etag, final Accept accept) {
     return createResponse(null, entity, etag, accept, null);
   }
@@ -586,7 +611,7 @@ public abstract class AbstractUtilities {
     } else {
       mapper.writeValue(
               writer, new JSONFeedContainer(container.getContextURL(),
-                      container.getMetadataETag(), dataBinder.toJSONFeed(container.getObject())));
+              container.getMetadataETag(), dataBinder.toJSONFeed(container.getObject())));
     }
 
     return IOUtils.toInputStream(writer.toString(), Constants.ENCODING);
@@ -603,7 +628,7 @@ public abstract class AbstractUtilities {
     } else {
       final Container<JSONEntryImpl> container =
               mapper.readValue(entity, new TypeReference<JSONEntryImpl>() {
-              });
+      });
       entry = dataBinder.toAtomEntry(container.getObject());
     }
 
@@ -619,7 +644,7 @@ public abstract class AbstractUtilities {
     } else {
       mapper.writeValue(
               writer, new JSONEntryContainer(container.getContextURL(), container.getMetadataETag(),
-                      dataBinder.toJSONEntry(container.getObject())));
+              dataBinder.toJSONEntry(container.getObject())));
     }
 
     return IOUtils.toInputStream(writer.toString(), Constants.ENCODING);
@@ -649,7 +674,7 @@ public abstract class AbstractUtilities {
     } else {
       mapper.writeValue(
               writer, new JSONPropertyContainer(container.getContextURL(), container.getMetadataETag(),
-                      dataBinder.toJSONProperty(container.getObject())));
+              dataBinder.toJSONProperty(container.getObject())));
     }
 
     return IOUtils.toInputStream(writer.toString(), Constants.ENCODING);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/fit/src/main/resources/V40/Customers/feed.full.json
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/Customers/feed.full.json b/fit/src/main/resources/V40/Customers/feed.full.json
new file mode 100644
index 0000000..54af904
--- /dev/null
+++ b/fit/src/main/resources/V40/Customers/feed.full.json
@@ -0,0 +1,89 @@
+{
+  "@odata.context": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/$metadata#Customers",
+  "value":
+          [
+            {
+              "@odata.id": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)",
+              "@odata.editLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)",
+              "PersonID": 1,
+              "FirstName": "Bob",
+              "LastName": "Cat",
+              "MiddleName": null,
+              "HomeAddress":
+                      {
+                        "@odata.type": "#Microsoft.Test.OData.Services.ODataWCFService.HomeAddress",
+                        "Street": "1 Microsoft Way",
+                        "City": "London",
+                        "PostalCode": "98052",
+                        "FamilyName": "Cats"
+                      },
+              "Home":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  23.1,
+                                  32.1
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Numbers":
+                      [
+                        "111-111-1111",
+                        "012",
+                        "310",
+                        "bca",
+                        "ayz"
+                      ],
+              "Emails":
+                      [
+                        "abc@abc.com"
+                      ],
+              "City": "London",
+              "Birthday": "1957-04-03T00:00:00Z",
+              "TimeBetweenLastTwoOrders": "PT0.0000001S"
+            },
+            {
+              "@odata.id": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)",
+              "@odata.editLink": "http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)",
+              "PersonID": 2,
+              "FirstName": "Jill",
+              "LastName": "Jones",
+              "MiddleName": null,
+              "HomeAddress": null,
+              "Home":
+                      {
+                        "type": "Point",
+                        "coordinates":
+                                [
+                                  161.8,
+                                  15
+                                ],
+                        "crs":
+                                {
+                                  "type": "name",
+                                  "properties":
+                                          {
+                                            "name": "EPSG:4326"
+                                          }
+                                }
+                      },
+              "Numbers":
+                      [
+                      ],
+              "Emails":
+                      [
+                      ],
+              "City": "Sydney",
+              "Birthday": "1983-01-15T00:00:00Z",
+              "TimeBetweenLastTwoOrders": "PT0.0000002S"
+            }
+          ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/fit/src/main/resources/V40/Customers/feed.xml
----------------------------------------------------------------------
diff --git a/fit/src/main/resources/V40/Customers/feed.xml b/fit/src/main/resources/V40/Customers/feed.xml
new file mode 100644
index 0000000..198acd5
--- /dev/null
+++ b/fit/src/main/resources/V40/Customers/feed.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<feed xml:base="http://odatae2etest.azurewebsites.net/javatest/DefaultService/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" m:context="http://odatae2etest.azurewebsites.net/javatest/DefaultService/$metadata#Customers">
+  <id>http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers</id>
+  <title />
+  <updated>2014-04-23T10:01:18Z</updated>
+  <entry>
+    <id>http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)</id>
+    <category term="#Microsoft.Test.OData.Services.ODataWCFService.Customer" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
+    <link rel="edit" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Parent" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Orders" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=1)/Company" />
+    <title />
+    <updated>2014-04-23T10:01:18Z</updated>
+    <author>
+      <name />
+    </author>
+    <content type="application/xml">
+      <m:properties>
+        <d:PersonID m:type="Int32">1</d:PersonID>
+        <d:FirstName>Bob</d:FirstName>
+        <d:LastName>Cat</d:LastName>
+        <d:MiddleName m:null="true" />
+        <d:HomeAddress m:type="#Microsoft.Test.OData.Services.ODataWCFService.HomeAddress">
+          <d:Street>1 Microsoft Way</d:Street>
+          <d:City>London</d:City>
+          <d:PostalCode>98052</d:PostalCode>
+          <d:FamilyName>Cats</d:FamilyName>
+        </d:HomeAddress>
+        <d:Home m:type="GeographyPoint">
+          <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+            <gml:pos>32.1 23.1</gml:pos>
+          </gml:Point>
+        </d:Home>
+        <d:Numbers m:type="#Collection(String)">
+          <m:element>111-111-1111</m:element>
+          <m:element>012</m:element>
+          <m:element>310</m:element>
+          <m:element>bca</m:element>
+          <m:element>ayz</m:element>
+        </d:Numbers>
+        <d:Emails m:type="#Collection(String)">
+          <m:element>abc@abc.com</m:element>
+        </d:Emails>
+        <d:City>London</d:City>
+        <d:Birthday m:type="DateTimeOffset">1957-04-03T00:00:00Z</d:Birthday>
+        <d:TimeBetweenLastTwoOrders m:type="Duration">PT0.0000001S</d:TimeBetweenLastTwoOrders>
+      </m:properties>
+    </content>
+  </entry>
+  <entry>
+    <id>http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)</id>
+    <category term="#Microsoft.Test.OData.Services.ODataWCFService.Customer" scheme="http://docs.oasis-open.org/odata/ns/scheme" />
+    <link rel="edit" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Parent" type="application/atom+xml;type=entry" title="Parent" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)/Parent" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Orders" type="application/atom+xml;type=feed" title="Orders" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)/Orders" />
+    <link rel="http://docs.oasis-open.org/odata/ns/related/Company" type="application/atom+xml;type=entry" title="Company" href="http://odatae2etest.azurewebsites.net/javatest/DefaultService/Customers(PersonID=2)/Company" />
+    <title />
+    <updated>2014-04-23T10:01:18Z</updated>
+    <author>
+      <name />
+    </author>
+    <content type="application/xml">
+      <m:properties>
+        <d:PersonID m:type="Int32">2</d:PersonID>
+        <d:FirstName>Jill</d:FirstName>
+        <d:LastName>Jones</d:LastName>
+        <d:MiddleName m:null="true" />
+        <d:HomeAddress m:null="true" />
+        <d:Home m:type="GeographyPoint">
+          <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+            <gml:pos>15 161.8</gml:pos>
+          </gml:Point>
+        </d:Home>
+        <d:Numbers m:type="#Collection(String)" />
+        <d:Emails m:type="#Collection(String)" />
+        <d:City>Sydney</d:City>
+        <d:Birthday m:type="DateTimeOffset">1983-01-15T00:00:00Z</d:Birthday>
+        <d:TimeBetweenLastTwoOrders m:type="Duration">PT0.0000002S</d:TimeBetweenLastTwoOrders>
+      </m:properties>
+    </content>
+  </entry>
+</feed>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/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
index 79b2641..9ac5e95 100644
--- 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
@@ -19,11 +19,13 @@
 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.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.response.ODataDeleteResponse;
 import org.apache.olingo.commons.api.format.ODataPubFormat;
 
 /**
  * This class implements an OData delete request.
  */
-public interface ODataDeleteRequest extends ODataBasicRequest<ODataDeleteResponse, ODataPubFormat> {
+public interface ODataDeleteRequest
+        extends ODataBasicRequest<ODataDeleteResponse, ODataPubFormat>, ODataBatchableRequest {
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/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
index 53fa447..25ece1a 100644
--- 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
@@ -19,11 +19,13 @@
 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.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.response.ODataPropertyUpdateResponse;
 import org.apache.olingo.commons.api.format.ODataFormat;
 
 /**
  * This class implements an OData update entity property request.
  */
-public interface ODataPropertyUpdateRequest extends ODataBasicRequest<ODataPropertyUpdateResponse, ODataFormat> {
+public interface ODataPropertyUpdateRequest
+        extends ODataBasicRequest<ODataPropertyUpdateResponse, ODataFormat>, ODataBatchableRequest {
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/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
index 753fde8..ced8c03 100644
--- 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
@@ -19,11 +19,13 @@
 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.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.response.ODataValueUpdateResponse;
 import org.apache.olingo.commons.api.format.ODataValueFormat;
 
 /**
  * This class implements an OData update entity property value request.
  */
-public interface ODataValueUpdateRequest extends ODataBasicRequest<ODataValueUpdateResponse, ODataValueFormat> {
+public interface ODataValueUpdateRequest
+        extends ODataBasicRequest<ODataValueUpdateResponse, ODataValueFormat>, ODataBatchableRequest {
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkCreateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkCreateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkCreateRequest.java
index 53bfde1..b35a76f 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkCreateRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkCreateRequest.java
@@ -19,11 +19,13 @@
 package org.apache.olingo.client.api.communication.request.cud.v3;
 
 import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.response.ODataLinkOperationResponse;
 import org.apache.olingo.commons.api.format.ODataFormat;
 
 /**
  * This class implements an insert link OData request.
  */
-public interface ODataLinkCreateRequest extends ODataBasicRequest<ODataLinkOperationResponse, ODataFormat> {
+public interface ODataLinkCreateRequest
+        extends ODataBasicRequest<ODataLinkOperationResponse, ODataFormat>, ODataBatchableRequest {
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkUpdateRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkUpdateRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkUpdateRequest.java
index d76f6ed..765594e 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkUpdateRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v3/ODataLinkUpdateRequest.java
@@ -19,11 +19,13 @@
 package org.apache.olingo.client.api.communication.request.cud.v3;
 
 import org.apache.olingo.client.api.communication.request.ODataBasicRequest;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.response.ODataLinkOperationResponse;
 import org.apache.olingo.commons.api.format.ODataFormat;
 
 /**
  * This class implements an update link OData request.
  */
-public interface ODataLinkUpdateRequest extends ODataBasicRequest<ODataLinkOperationResponse, ODataFormat> {
+public interface ODataLinkUpdateRequest
+        extends ODataBasicRequest<ODataLinkOperationResponse, ODataFormat>, ODataBatchableRequest {
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/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
index e403cf5..98da20c 100644
--- 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
@@ -18,13 +18,13 @@
  */
 package org.apache.olingo.client.api.communication.request.streamed;
 
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 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.
+ * This class implements an OData stream create/update request. Get instance by using ODataStreamedRequestFactory.
  */
 public interface ODataStreamUpdateRequest
-        extends ODataStreamedRequest<ODataStreamUpdateResponse, StreamUpdateStreamManager> {
+        extends ODataStreamedRequest<ODataStreamUpdateResponse, StreamUpdateStreamManager>, ODataBatchableRequest {
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestFactory.java
new file mode 100644
index 0000000..9fd06dc
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestFactory.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.v4;
+
+import org.apache.olingo.client.api.communication.request.ODataRequest;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+
+@SuppressWarnings("unchecked")
+public interface AsyncRequestFactory {
+
+  <R extends ODataResponse> AsyncRequestWrapper<R> getAsyncRequestWrapper(final ODataRequest odataRequest);
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestWrapper.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestWrapper.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestWrapper.java
new file mode 100644
index 0000000..7c57b69
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/v4/AsyncRequestWrapper.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.v4;
+
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.client.api.communication.response.v4.AsyncResponseWrapper;
+
+public interface AsyncRequestWrapper<R extends ODataResponse> {
+
+  /**
+   * Add wait http header.
+   *
+   * @param waitInSeconds wait time in seconds.
+   * @return the current AsyncRequestWrapper instance.
+   */
+  AsyncRequestWrapper<R> wait(int waitInSeconds);
+
+  /**
+   * execute the request for the first time.
+   *
+   * @return
+   */
+  AsyncResponseWrapper<R> execute();
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
index 5498d1b..7da07ec 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/ODataResponse.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
 import java.net.URI;
 import java.util.Collection;
 import java.util.Map;
+import org.apache.http.HttpResponse;
 import org.apache.olingo.client.api.communication.header.HeaderName;
 import org.apache.olingo.client.api.communication.request.batch.ODataBatchLineIterator;
 
@@ -59,7 +60,7 @@ public interface ODataResponse {
    * @return ETag header value, if provided
    */
   String getEtag();
-  
+
   /**
    * The context URL describes the content of the payload. It consists of the canonical metadata document URL and a
    * fragment identifying the relevant portion of the metadata document.
@@ -113,12 +114,21 @@ public interface ODataResponse {
   InputStream getRawResponse();
 
   /**
+   * Initializes OData response from HTTP response.
+   *
+   * @param res HTTP response.
+   * @return OData response;
+   */
+  ODataResponse initFromHttpResponse(HttpResponse res);
+
+  /**
    * Initializes response from batch response item.
    *
    * @param responseLine response line.
    * @param headers response headers.
    * @param batchLineIterator batch line iterator.
    * @param boundary batch boundary.
+   * @return OData response.
    */
   ODataResponse initFromBatch(
           final Map.Entry<Integer, String> responseLine,
@@ -127,6 +137,14 @@ public interface ODataResponse {
           final String boundary);
 
   /**
+   * Initializes response from an enclosed HTTP response.
+   *
+   * @param part enclosed HTTP response.
+   * @return OData response.
+   */
+  ODataResponse initFromEnclosedPart(InputStream part);
+
+  /**
    * Close the underlying message entity input stream (if available and open) as well as releases any other resources
    * associated with the response.
    * <p>

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponse.java
new file mode 100644
index 0000000..f3fe972
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponse.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.response.v4;
+
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+
+public interface AsyncResponse extends ODataResponse {
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponseWrapper.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponseWrapper.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponseWrapper.java
new file mode 100644
index 0000000..87b6904
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/AsyncResponseWrapper.java
@@ -0,0 +1,69 @@
+/*
+ * 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.v4;
+
+import org.apache.olingo.client.api.communication.response.ODataDeleteResponse;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+
+public interface AsyncResponseWrapper<R extends ODataResponse> {
+
+  /**
+   * Checks for preference applied.
+   *
+   * @return 'TRUE' if respond-async preference has been applied; 'FALSE' otherwise.
+   */
+  boolean isPreferenceApplied();
+
+  /**
+   * Checks if asynchronous processing has been terminated.
+   *
+   * @return 'TRUE' the process has been terminated; 'FALSE' otherwise.
+   */
+  boolean isDone();
+
+  /**
+   * Gets the real response.
+   * <br />
+   * If asynchronous processing has been terminated then the response will be returned immediately. This method retries
+   * after a delay, specified by the 'Retry-After' header indicating the time, in seconds, the client should wait before
+   * retry. If there isn't any 'Retry-After' response header available, a default of 5 seconds will be chosen. The query
+   * will be retried for a maximum of five times.
+   *
+   * @return real OData response.
+   */
+  R getODataResponse();
+
+  /**
+   * DeleteA DELETE request sent to the status monitor resource requests that the asynchronous processing be canceled. A
+   * 200 OK or to a 204 No Content response indicates that the asynchronous processing has been successfully canceled.
+   *
+   * @return OData delete response.
+   */
+  ODataDeleteResponse delete();
+
+  /**
+   * A client can request that the DELETE should be executed asynchronously. A 202 Accepted response indicates that the
+   * cancellation is being processed asynchronously; the client can use the returned Location header (which MUST be
+   * different from the status monitor resource of the initial request) to query for the status of the cancellation. If
+   * a delete request is not supported by the service, the service returns 405 Method Not Allowed.
+   *
+   * @return OData delete response.
+   */
+  AsyncResponseWrapper<ODataDeleteResponse> asyncDelete();
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/ODataClient.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/ODataClient.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/ODataClient.java
index 18306f2..7ee53bf 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/ODataClient.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/ODataClient.java
@@ -25,6 +25,7 @@ import org.apache.olingo.client.api.communication.request.cud.v4.UpdateType;
 import org.apache.olingo.client.api.communication.request.invoke.v4.InvokeRequestFactory;
 import org.apache.olingo.client.api.communication.request.retrieve.v4.RetrieveRequestFactory;
 import org.apache.olingo.client.api.communication.request.streamed.v4.StreamedRequestFactory;
+import org.apache.olingo.client.api.communication.request.v4.AsyncRequestFactory;
 import org.apache.olingo.client.api.op.v4.ODataBinder;
 import org.apache.olingo.client.api.op.v4.ODataDeserializer;
 import org.apache.olingo.client.api.op.v4.ODataReader;
@@ -55,6 +56,8 @@ public interface ODataClient extends CommonODataClient<UpdateType> {
   @Override
   ODataObjectFactory getObjectFactory();
 
+  AsyncRequestFactory getAsyncRequestFactory();
+
   @Override
   RetrieveRequestFactory getRetrieveRequestFactory();
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
index 21e6502..c08b426 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataBasicRequest.java
@@ -41,7 +41,7 @@ import org.apache.olingo.client.api.http.HttpMethod;
  * @param <T> OData format being used.
  */
 public abstract class AbstractODataBasicRequest<V extends ODataResponse, T extends Format>
-        extends ODataRequestImpl<T>
+        extends AbstractODataRequest<T>
         implements ODataBasicRequest<V, T> {
 
   /**

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java
new file mode 100644
index 0000000..8bc4d1c
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractODataRequest.java
@@ -0,0 +1,433 @@
+/*
+ * 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 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.CommonODataClient;
+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.ODataRequest;
+import org.apache.olingo.client.api.communication.request.ODataStreamer;
+import org.apache.olingo.client.api.communication.response.ODataResponse;
+import org.apache.olingo.commons.api.format.Format;
+import org.apache.olingo.client.api.http.HttpClientException;
+import org.apache.olingo.client.api.http.HttpMethod;
+import org.apache.olingo.client.core.communication.header.ODataHeadersImpl;
+import org.apache.olingo.commons.api.format.ODataMediaFormat;
+import org.apache.olingo.commons.api.format.ODataPubFormat;
+import org.apache.olingo.commons.api.format.ODataValueFormat;
+
+/**
+ * Abstract representation of an OData request. Get instance by using factories.
+ *
+ * @param <T> Accepted content-type formats by the request in object.
+ *
+ * @see org.apache.olingo.client.api.communication.request.cud.v3.CUDRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.cud.v4.CUDRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.batch.v4.BatchRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.invoke.v3.InvokeRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.invoke.v4.InvokeRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.streamed.v3.StreamedRequestFactory
+ * @see org.apache.olingo.client.api.communication.request.streamed.v4.StreamedRequestFactory
+ */
+public abstract class AbstractODataRequest<T extends Format> extends AbstractRequest implements ODataRequest {
+
+  protected final CommonODataClient<?> odataClient;
+
+  private 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 AbstractODataRequest(final CommonODataClient<?> 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 ODataRequest addCustomHeader(final HeaderName 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(odataClient.getServiceVersion()) : 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(odataClient.getServiceVersion()) : 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.getConfiguration().isKeyAsSegment()) {
+      addCustomHeader(
+              HeaderName.dataServiceUrlConventions.toString(),
+              odataClient.newPreferences().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);
+    }
+
+    checkForResponse(odataClient, response, getAccept());
+
+    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");
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java
new file mode 100644
index 0000000..25514b8
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/AbstractRequest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2014 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.olingo.client.api.CommonODataClient;
+import org.apache.olingo.client.api.communication.ODataClientErrorException;
+import org.apache.olingo.client.api.communication.ODataServerErrorException;
+import org.apache.olingo.client.api.http.HttpClientException;
+import org.apache.olingo.commons.api.domain.ODataError;
+import org.apache.olingo.commons.core.data.JSONODataErrorImpl;
+import org.apache.olingo.commons.core.data.XMLODataErrorImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractRequest {
+
+  /**
+   * Logger.
+   */
+  protected static final Logger LOG = LoggerFactory.getLogger(AbstractRequest.class);
+
+  private ODataError getGenericError(final int code, final String errorMsg, final boolean isXML) {
+    final ODataError error;
+    if (isXML) {
+      error = new XMLODataErrorImpl();
+      ((XMLODataErrorImpl) error).setCode(String.valueOf(code));
+      ((XMLODataErrorImpl) error).setMessage(errorMsg);
+    } else {
+      error = new JSONODataErrorImpl();
+      ((JSONODataErrorImpl) error).setCode(String.valueOf(code));
+      ((JSONODataErrorImpl) error).setMessage(errorMsg);
+    }
+
+    return error;
+  }
+
+  protected <C extends CommonODataClient<?>> void checkForResponse(
+          final C odataClient, final HttpResponse response, final String accept) {
+
+    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 = accept.contains("json");
+          ODataError 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);
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/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
deleted file mode 100644
index 4fc28a9..0000000
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/ODataRequestImpl.java
+++ /dev/null
@@ -1,486 +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.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 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.CommonODataClient;
-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.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.commons.api.format.Format;
-import org.apache.olingo.client.api.http.HttpClientException;
-import org.apache.olingo.client.api.http.HttpMethod;
-import org.apache.olingo.client.core.communication.header.ODataHeadersImpl;
-import org.apache.olingo.commons.api.domain.ODataError;
-import org.apache.olingo.commons.api.format.ODataMediaFormat;
-import org.apache.olingo.commons.api.format.ODataPubFormat;
-import org.apache.olingo.commons.api.format.ODataValueFormat;
-import org.apache.olingo.commons.core.data.JSONODataErrorImpl;
-import org.apache.olingo.commons.core.data.XMLODataErrorImpl;
-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 org.apache.olingo.client.api.communication.request.cud.v3.CUDRequestFactory
- * @see org.apache.olingo.client.api.communication.request.cud.v4.CUDRequestFactory
- * @see org.apache.olingo.client.api.communication.request.batch.v3.BatchRequestFactory
- * @see org.apache.olingo.client.api.communication.request.batch.v4.BatchRequestFactory
- * @see org.apache.olingo.client.api.communication.request.invoke.v3.InvokeRequestFactory
- * @see org.apache.olingo.client.api.communication.request.invoke.v4.InvokeRequestFactory
- * @see org.apache.olingo.client.api.communication.request.streamed.v3.StreamedRequestFactory
- * @see org.apache.olingo.client.api.communication.request.streamed.v4.StreamedRequestFactory
- */
-public class ODataRequestImpl<T extends Format> implements ODataRequest {
-
-  /**
-   * Logger.
-   */
-  protected static final Logger LOG = LoggerFactory.getLogger(ODataRequest.class);
-
-  protected final CommonODataClient<?> odataClient;
-
-  private 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 CommonODataClient<?> 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 ODataRequest addCustomHeader(final HeaderName 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(odataClient.getServiceVersion()) : 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(odataClient.getServiceVersion()) : 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.getConfiguration().isKeyAsSegment()) {
-      addCustomHeader(
-              HeaderName.dataServiceUrlConventions.toString(),
-              odataClient.newPreferences().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().contains("json");
-          ODataError 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 ODataError getGenericError(final int code, final String errorMsg, final boolean isXML) {
-    final ODataError error;
-    if (isXML) {
-      error = new XMLODataErrorImpl();
-      ((XMLODataErrorImpl) error).setCode(String.valueOf(code));
-      ((XMLODataErrorImpl) error).setMessage(errorMsg);
-    } else {
-      error = new JSONODataErrorImpl();
-      ((JSONODataErrorImpl) error).setCode(String.valueOf(code));
-      ((JSONODataErrorImpl) error).setMessage(errorMsg);
-    }
-
-    return error;
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchRequest.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchRequest.java
index 606dec9..382cbd1 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchRequest.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/AbstractODataBatchRequest.java
@@ -59,7 +59,7 @@ public abstract class AbstractODataBatchRequest<V extends ODataResponse, T exten
    * @param odataClient client instance getting this request
    * @param uri batch request URI (http://serviceRoot/$batch)
    */
-  protected AbstractODataBatchRequest(final CommonODataClient odataClient, final URI uri) {
+  protected AbstractODataBatchRequest(final CommonODataClient<?> odataClient, final URI uri) {
     super(odataClient, HttpMethod.POST, uri);
 
     // create a random UUID value for boundary

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/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
index edc294b..ec03220 100644
--- 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
@@ -24,7 +24,7 @@ import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
 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;
+import org.apache.olingo.client.core.communication.request.AbstractODataRequest;
 import org.apache.olingo.commons.api.format.ContentType;
 
 /**
@@ -122,7 +122,7 @@ public class ODataChangesetImpl extends AbstractODataBatchRequestItem
     request.batch(req, String.valueOf(contentId));
 
     // add request to the list
-    expectedResItem.addResponse(String.valueOf(contentId), ((ODataRequestImpl) request).getResponseTemplate());
+    expectedResItem.addResponse(String.valueOf(contentId), ((AbstractODataRequest) request).getResponseTemplate());
     return this;
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/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
index 9bc35f4..f7375ff 100644
--- 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
@@ -22,7 +22,7 @@ import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
 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;
+import org.apache.olingo.client.core.communication.request.AbstractODataRequest;
 
 /**
  * Retrieve request wrapper for the corresponding batch item.
@@ -60,7 +60,7 @@ public class ODataRetrieveImpl extends AbstractODataBatchRequestItem
       throw new IllegalStateException("Current batch item is closed");
     }
 
-    if (((ODataRequestImpl) request).getMethod() != HttpMethod.GET) {
+    if (((AbstractODataRequest) request).getMethod() != HttpMethod.GET) {
       throw new IllegalArgumentException("Invalid request. Only GET method is allowed");
     }
 
@@ -74,7 +74,7 @@ public class ODataRetrieveImpl extends AbstractODataBatchRequestItem
 
     // add request to the list
     expectedResItem.addResponse(
-            ODataRetrieveResponseItem.RETRIEVE_CONTENT_ID, ((ODataRequestImpl) request).getResponseTemplate());
+            ODataRetrieveResponseItem.RETRIEVE_CONTENT_ID, ((AbstractODataRequest) request).getResponseTemplate());
 
     return this;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v3/ODataBatchRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v3/ODataBatchRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v3/ODataBatchRequestImpl.java
index e838eca..dd3f365 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v3/ODataBatchRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v3/ODataBatchRequestImpl.java
@@ -44,7 +44,7 @@ public class ODataBatchRequestImpl
         extends AbstractODataBatchRequest<ODataBatchResponse, BatchStreamManager>
         implements ODataBatchRequest, ODataStreamedRequest<ODataBatchResponse, BatchStreamManager> {
 
-  public ODataBatchRequestImpl(final CommonODataClient odataClient, final URI uri) {
+  public ODataBatchRequestImpl(final CommonODataClient<?> odataClient, final URI uri) {
     super(odataClient, uri);
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f1072a6/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v4/ODataOutsideUpdateImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v4/ODataOutsideUpdateImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v4/ODataOutsideUpdateImpl.java
index 7354590..fd79e0b 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v4/ODataOutsideUpdateImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/batch/v4/ODataOutsideUpdateImpl.java
@@ -22,7 +22,7 @@ import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.request.batch.CommonODataBatchRequest;
 import org.apache.olingo.client.api.communication.request.batch.v4.ODataOutsideUpdate;
 import org.apache.olingo.client.api.http.HttpMethod;
-import org.apache.olingo.client.core.communication.request.ODataRequestImpl;
+import org.apache.olingo.client.core.communication.request.AbstractODataRequest;
 import org.apache.olingo.client.core.communication.request.batch.AbstractODataBatchRequestItem;
 
 /**
@@ -61,7 +61,7 @@ public class ODataOutsideUpdateImpl extends AbstractODataBatchRequestItem
       throw new IllegalStateException("Current batch item is closed");
     }
 
-    if (((ODataRequestImpl) request).getMethod() == HttpMethod.GET) {
+    if (((AbstractODataRequest) request).getMethod() == HttpMethod.GET) {
       throw new IllegalArgumentException("Invalid request. Use ODataRetrieve for GET method");
     }
 
@@ -77,7 +77,7 @@ public class ODataOutsideUpdateImpl extends AbstractODataBatchRequestItem
 
     // add request to the list
     expectedResItem.addResponse(
-            ODataOutsideUpdateResponseItem.OUTSIDE_CONTENT_ID, ((ODataRequestImpl) request).getResponseTemplate());
+            ODataOutsideUpdateResponseItem.OUTSIDE_CONTENT_ID, ((AbstractODataRequest) request).getResponseTemplate());
 
     return this;
   }