You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ed...@apache.org on 2014/02/14 23:22:24 UTC

[48/51] [partial] [OLINGO-146] Java Client Lib contributed under SGA from Microsoft Open Technologies, Inc. The majority of this was written by Francesco Chicchiriccò

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataChangeset.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataChangeset.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataChangeset.java
new file mode 100644
index 0000000..70aee38
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataChangeset.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.batch;
+
+import com.msopentech.odatajclient.engine.client.http.HttpMethod;
+import com.msopentech.odatajclient.engine.communication.header.ODataHeaders;
+import com.msopentech.odatajclient.engine.communication.request.ODataRequestImpl;
+import com.msopentech.odatajclient.engine.utils.ODataBatchConstants;
+import java.util.UUID;
+
+/**
+ * Changeset wrapper for the corresponding batch item.
+ */
+public class ODataChangeset extends ODataBatchRequestItem {
+
+    /**
+     * 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.
+     */
+    ODataChangeset(final ODataBatchRequest req, final ODataChangesetResponseItem expectedResItem) {
+        super(req);
+        this.expectedResItem = expectedResItem;
+
+        // create a random UUID value for boundary
+        boundary = "changeset_" + UUID.randomUUID().toString();
+    }
+
+    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();
+        }
+    }
+
+    /**
+     * 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.
+     */
+    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((ODataHeaders.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/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataChangesetResponseItem.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataChangesetResponseItem.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataChangesetResponseItem.java
new file mode 100644
index 0000000..379a23a
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataChangesetResponseItem.java
@@ -0,0 +1,132 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.batch;
+
+import static com.msopentech.odatajclient.engine.communication.request.batch.ODataBatchResponseItem.LOG;
+
+import com.msopentech.odatajclient.engine.communication.response.ODataResponse;
+import com.msopentech.odatajclient.engine.utils.ODataBatchConstants;
+import java.util.Collection;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+/**
+ * Changeset wrapper for the corresponding batch item.
+ */
+public class ODataChangesetResponseItem extends ODataBatchResponseItem {
+
+    /**
+     * 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/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataRetrieve.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataRetrieve.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataRetrieve.java
new file mode 100644
index 0000000..407b462
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataRetrieve.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.batch;
+
+import com.msopentech.odatajclient.engine.client.http.HttpMethod;
+import com.msopentech.odatajclient.engine.communication.request.ODataRequestImpl;
+
+/**
+ * Retrieve request wrapper for the corresponding batch item.
+ */
+public class ODataRetrieve extends ODataBatchRequestItem {
+
+    private final ODataRetrieveResponseItem expectedResItem;
+
+    /**
+     * Constructor.
+     *
+     * @param req batch request.
+     * @param expectedResItem expected batch response item.
+     */
+    ODataRetrieve(final ODataBatchRequest req, final ODataRetrieveResponseItem expectedResItem) {
+        super(req);
+        this.expectedResItem = expectedResItem;
+    }
+
+    /**
+     * Close item.
+     */
+    @Override
+    protected void closeItem() {
+        // nop
+    }
+
+    /**
+     * 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.
+     */
+    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/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataRetrieveResponseItem.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataRetrieveResponseItem.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataRetrieveResponseItem.java
new file mode 100644
index 0000000..b763a8a
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/ODataRetrieveResponseItem.java
@@ -0,0 +1,87 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.batch;
+
+import static com.msopentech.odatajclient.engine.communication.request.batch.ODataBatchResponseItem.LOG;
+import com.msopentech.odatajclient.engine.communication.response.ODataResponse;
+import java.util.Collection;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+/**
+ * Retrieve response wrapper for the corresponding batch item.
+ */
+public class ODataRetrieveResponseItem extends ODataBatchResponseItem {
+
+    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/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/V3BatchRequestFactory.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/V3BatchRequestFactory.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/V3BatchRequestFactory.java
new file mode 100644
index 0000000..0b7eca8
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/V3BatchRequestFactory.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.batch;
+
+import com.msopentech.odatajclient.engine.client.ODataV3Client;
+
+public class V3BatchRequestFactory extends AbstractBatchRequestFactory {
+
+    private static final long serialVersionUID = -6271567229804128570L;
+
+    public V3BatchRequestFactory(final ODataV3Client client) {
+        super(client);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/V4BatchRequestFactory.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/V4BatchRequestFactory.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/V4BatchRequestFactory.java
new file mode 100644
index 0000000..e0eaa5a
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/batch/V4BatchRequestFactory.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.batch;
+
+import com.msopentech.odatajclient.engine.client.ODataV4Client;
+
+public class V4BatchRequestFactory extends AbstractBatchRequestFactory {
+
+    private static final long serialVersionUID = 788349446729208639L;
+
+    public V4BatchRequestFactory(final ODataV4Client client) {
+        super(client);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/AbstractCUDRequestFactory.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/AbstractCUDRequestFactory.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/AbstractCUDRequestFactory.java
new file mode 100644
index 0000000..d93e7d7
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/AbstractCUDRequestFactory.java
@@ -0,0 +1,190 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.cud;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import com.msopentech.odatajclient.engine.client.http.HttpMethod;
+import com.msopentech.odatajclient.engine.communication.request.UpdateType;
+import com.msopentech.odatajclient.engine.data.ODataEntity;
+import com.msopentech.odatajclient.engine.data.ODataLink;
+import com.msopentech.odatajclient.engine.data.ODataPrimitiveValue;
+import com.msopentech.odatajclient.engine.data.ODataProperty;
+import java.net.URI;
+
+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 ODataEntityCreateRequest(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 ODataEntityUpdateRequest(client, HttpMethod.POST, targetURI, changes);
+            req.setXHTTPMethod(type.getMethod().name());
+        } else {
+            req = new ODataEntityUpdateRequest(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 ODataEntityUpdateRequest(client, HttpMethod.POST, entity.getEditLink(), entity);
+            req.setXHTTPMethod(type.getMethod().name());
+        } else {
+            req = new ODataEntityUpdateRequest(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 ODataValueUpdateRequest(client, HttpMethod.POST, targetURI, value);
+            req.setXHTTPMethod(type.getMethod().name());
+        } else {
+            req = new ODataValueUpdateRequest(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 ODataPropertyUpdateRequest(client, HttpMethod.POST, targetURI, property);
+            req.setXHTTPMethod(HttpMethod.PUT.name());
+        } else {
+            req = new ODataPropertyUpdateRequest(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 ODataPropertyUpdateRequest(client, HttpMethod.POST, targetURI, property);
+            req.setXHTTPMethod(type.getMethod().name());
+        } else {
+            req = new ODataPropertyUpdateRequest(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 ODataPropertyUpdateRequest(client, HttpMethod.POST, targetURI, property);
+            req.setXHTTPMethod(HttpMethod.PUT.name());
+        } else {
+            req = new ODataPropertyUpdateRequest(client, HttpMethod.PUT, targetURI, property);
+        }
+
+        return req;
+    }
+
+    @Override
+    public ODataLinkCreateRequest getLinkCreateRequest(final URI targetURI, final ODataLink link) {
+        return new ODataLinkCreateRequest(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 ODataLinkUpdateRequest(client, HttpMethod.POST, targetURI, link);
+            req.setXHTTPMethod(type.getMethod().name());
+        } else {
+            req = new ODataLinkUpdateRequest(client, type.getMethod(), targetURI, link);
+        }
+
+        return req;
+    }
+
+    @Override
+    public ODataDeleteRequest getDeleteRequest(final URI targetURI) {
+        final ODataDeleteRequest req;
+
+        if (client.getConfiguration().isUseXHTTPMethod()) {
+            req = new ODataDeleteRequest(client, HttpMethod.POST, targetURI);
+            req.setXHTTPMethod(HttpMethod.DELETE.name());
+        } else {
+            req = new ODataDeleteRequest(client, HttpMethod.DELETE, targetURI);
+        }
+
+        return req;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/CUDRequestFactory.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/CUDRequestFactory.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/CUDRequestFactory.java
new file mode 100644
index 0000000..1f3f828
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/CUDRequestFactory.java
@@ -0,0 +1,146 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.cud;
+
+import com.msopentech.odatajclient.engine.communication.request.UpdateType;
+import com.msopentech.odatajclient.engine.data.ODataEntity;
+import com.msopentech.odatajclient.engine.data.ODataLink;
+import com.msopentech.odatajclient.engine.data.ODataPrimitiveValue;
+import com.msopentech.odatajclient.engine.data.ODataProperty;
+import java.io.Serializable;
+import java.net.URI;
+
+/**
+ * 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/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataDeleteRequest.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataDeleteRequest.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataDeleteRequest.java
new file mode 100644
index 0000000..7b317dd
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataDeleteRequest.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.cud;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import com.msopentech.odatajclient.engine.client.http.HttpMethod;
+import com.msopentech.odatajclient.engine.communication.response.ODataResponseImpl;
+import com.msopentech.odatajclient.engine.communication.request.AbstractODataBasicRequestImpl;
+import com.msopentech.odatajclient.engine.communication.request.batch.ODataBatchableRequest;
+import com.msopentech.odatajclient.engine.communication.response.ODataDeleteResponse;
+import com.msopentech.odatajclient.engine.format.ODataPubFormat;
+import java.io.InputStream;
+import java.net.URI;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+
+/**
+ * This class implements an OData delete request.
+ */
+public class ODataDeleteRequest extends AbstractODataBasicRequestImpl<ODataDeleteResponse, ODataPubFormat>
+        implements 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.
+     */
+    ODataDeleteRequest(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();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataEntityCreateRequest.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataEntityCreateRequest.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataEntityCreateRequest.java
new file mode 100644
index 0000000..ac6d60c
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataEntityCreateRequest.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.cud;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import com.msopentech.odatajclient.engine.client.http.HttpMethod;
+import com.msopentech.odatajclient.engine.communication.request.AbstractODataBasicRequestImpl;
+import com.msopentech.odatajclient.engine.communication.request.batch.ODataBatchableRequest;
+import com.msopentech.odatajclient.engine.communication.response.ODataEntityCreateResponse;
+import com.msopentech.odatajclient.engine.communication.response.ODataResponseImpl;
+import com.msopentech.odatajclient.engine.data.ODataEntity;
+import com.msopentech.odatajclient.engine.format.ODataPubFormat;
+import com.msopentech.odatajclient.engine.utils.URIUtils;
+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;
+
+/**
+ * This class implements an OData create request.
+ */
+public class ODataEntityCreateRequest extends AbstractODataBasicRequestImpl<ODataEntityCreateResponse, ODataPubFormat>
+        implements 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.
+     */
+    ODataEntityCreateRequest(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/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataEntityUpdateRequest.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataEntityUpdateRequest.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataEntityUpdateRequest.java
new file mode 100644
index 0000000..b56902a
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataEntityUpdateRequest.java
@@ -0,0 +1,131 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.cud;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import com.msopentech.odatajclient.engine.client.http.HttpMethod;
+import com.msopentech.odatajclient.engine.communication.request.AbstractODataBasicRequestImpl;
+import com.msopentech.odatajclient.engine.communication.request.batch.ODataBatchableRequest;
+import com.msopentech.odatajclient.engine.communication.response.ODataEntityUpdateResponse;
+import com.msopentech.odatajclient.engine.communication.response.ODataResponseImpl;
+import com.msopentech.odatajclient.engine.data.ODataEntity;
+import com.msopentech.odatajclient.engine.format.ODataPubFormat;
+import com.msopentech.odatajclient.engine.utils.URIUtils;
+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;
+
+/**
+ * This class implements an OData update request.
+ */
+public class ODataEntityUpdateRequest extends AbstractODataBasicRequestImpl<ODataEntityUpdateResponse, ODataPubFormat>
+        implements 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.
+     */
+    ODataEntityUpdateRequest(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/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataLinkCreateRequest.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataLinkCreateRequest.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataLinkCreateRequest.java
new file mode 100644
index 0000000..f653f46
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataLinkCreateRequest.java
@@ -0,0 +1,108 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.cud;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import com.msopentech.odatajclient.engine.client.http.HttpMethod;
+import com.msopentech.odatajclient.engine.communication.request.AbstractODataBasicRequestImpl;
+import com.msopentech.odatajclient.engine.communication.request.batch.ODataBatchableRequest;
+import com.msopentech.odatajclient.engine.communication.response.ODataLinkOperationResponse;
+import com.msopentech.odatajclient.engine.communication.response.ODataResponseImpl;
+import com.msopentech.odatajclient.engine.data.ODataLink;
+import com.msopentech.odatajclient.engine.format.ODataFormat;
+import com.msopentech.odatajclient.engine.utils.URIUtils;
+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;
+
+/**
+ * This class implements an insert link OData request.
+ */
+public class ODataLinkCreateRequest extends AbstractODataBasicRequestImpl<ODataLinkOperationResponse, ODataFormat>
+        implements 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.
+     */
+    ODataLinkCreateRequest(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/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataLinkUpdateRequest.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataLinkUpdateRequest.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataLinkUpdateRequest.java
new file mode 100644
index 0000000..32b6f2f
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataLinkUpdateRequest.java
@@ -0,0 +1,111 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.cud;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import com.msopentech.odatajclient.engine.client.http.HttpMethod;
+import com.msopentech.odatajclient.engine.communication.request.AbstractODataBasicRequestImpl;
+import com.msopentech.odatajclient.engine.communication.request.batch.ODataBatchableRequest;
+import com.msopentech.odatajclient.engine.communication.response.ODataLinkOperationResponse;
+import com.msopentech.odatajclient.engine.communication.response.ODataResponseImpl;
+import com.msopentech.odatajclient.engine.data.ODataLink;
+import com.msopentech.odatajclient.engine.format.ODataFormat;
+import com.msopentech.odatajclient.engine.utils.URIUtils;
+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;
+
+/**
+ * This class implements an update link OData request.
+ */
+public class ODataLinkUpdateRequest extends AbstractODataBasicRequestImpl<ODataLinkOperationResponse, ODataFormat>
+        implements 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.
+     */
+    ODataLinkUpdateRequest(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/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataPropertyUpdateRequest.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataPropertyUpdateRequest.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataPropertyUpdateRequest.java
new file mode 100644
index 0000000..fa28486
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataPropertyUpdateRequest.java
@@ -0,0 +1,130 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.cud;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import com.msopentech.odatajclient.engine.client.http.HttpMethod;
+import com.msopentech.odatajclient.engine.communication.request.AbstractODataBasicRequestImpl;
+import com.msopentech.odatajclient.engine.communication.request.batch.ODataBatchableRequest;
+import com.msopentech.odatajclient.engine.communication.response.ODataPropertyUpdateResponse;
+import com.msopentech.odatajclient.engine.communication.response.ODataResponseImpl;
+import com.msopentech.odatajclient.engine.data.ODataProperty;
+import com.msopentech.odatajclient.engine.format.ODataFormat;
+import com.msopentech.odatajclient.engine.utils.URIUtils;
+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.http.entity.InputStreamEntity;
+
+/**
+ * This class implements an OData update entity property request.
+ */
+public class ODataPropertyUpdateRequest extends AbstractODataBasicRequestImpl<ODataPropertyUpdateResponse, ODataFormat>
+        implements 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.
+     */
+    ODataPropertyUpdateRequest(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/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataValueUpdateRequest.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataValueUpdateRequest.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataValueUpdateRequest.java
new file mode 100644
index 0000000..455eec5
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/ODataValueUpdateRequest.java
@@ -0,0 +1,139 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.cud;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import com.msopentech.odatajclient.engine.client.http.HttpClientException;
+import com.msopentech.odatajclient.engine.client.http.HttpMethod;
+import com.msopentech.odatajclient.engine.communication.response.ODataResponseImpl;
+import com.msopentech.odatajclient.engine.communication.request.AbstractODataBasicRequestImpl;
+import com.msopentech.odatajclient.engine.communication.request.batch.ODataBatchableRequest;
+import com.msopentech.odatajclient.engine.communication.response.ODataValueUpdateResponse;
+import com.msopentech.odatajclient.engine.data.ODataPrimitiveValue;
+import com.msopentech.odatajclient.engine.data.ODataValue;
+import com.msopentech.odatajclient.engine.metadata.edm.EdmSimpleType;
+import com.msopentech.odatajclient.engine.format.ODataValueFormat;
+import com.msopentech.odatajclient.engine.utils.URIUtils;
+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;
+
+/**
+ * This class implements an OData update entity property value request.
+ */
+public class ODataValueUpdateRequest extends AbstractODataBasicRequestImpl<ODataValueUpdateResponse, ODataValueFormat>
+        implements 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.
+     */
+    ODataValueUpdateRequest(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 ODataValueUpdateResponseImpl 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 ? EdmSimpleType.String : EdmSimpleType.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/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/V3CUDRequestFactory.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/V3CUDRequestFactory.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/V3CUDRequestFactory.java
new file mode 100644
index 0000000..c4a118d
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/V3CUDRequestFactory.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.cud;
+
+import com.msopentech.odatajclient.engine.client.ODataV3Client;
+
+public class V3CUDRequestFactory extends AbstractCUDRequestFactory {
+
+    private static final long serialVersionUID = 109196636064983035L;
+
+    public V3CUDRequestFactory(final ODataV3Client client) {
+        super(client);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/V4CUDRequestFactory.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/V4CUDRequestFactory.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/V4CUDRequestFactory.java
new file mode 100644
index 0000000..2164d52
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/cud/V4CUDRequestFactory.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.cud;
+
+import com.msopentech.odatajclient.engine.client.ODataV4Client;
+
+public class V4CUDRequestFactory extends AbstractCUDRequestFactory {
+
+    private static final long serialVersionUID = 3080623853913380425L;
+
+    public V4CUDRequestFactory(final ODataV4Client client) {
+        super(client);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/invoke/AbstractInvokeRequestFactory.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/invoke/AbstractInvokeRequestFactory.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/invoke/AbstractInvokeRequestFactory.java
new file mode 100644
index 0000000..f8a750a
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/invoke/AbstractInvokeRequestFactory.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.invoke;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import com.msopentech.odatajclient.engine.data.ODataInvokeResult;
+import com.msopentech.odatajclient.engine.data.ODataValue;
+import com.msopentech.odatajclient.engine.metadata.AbstractEdmMetadata;
+import com.msopentech.odatajclient.engine.metadata.edm.AbstractComplexType;
+import com.msopentech.odatajclient.engine.metadata.edm.AbstractDataServices;
+import com.msopentech.odatajclient.engine.metadata.edm.AbstractEdmx;
+import com.msopentech.odatajclient.engine.metadata.edm.AbstractEntityContainer;
+import com.msopentech.odatajclient.engine.metadata.edm.AbstractEntityType;
+import com.msopentech.odatajclient.engine.metadata.edm.AbstractFunctionImport;
+import com.msopentech.odatajclient.engine.metadata.edm.AbstractSchema;
+import java.net.URI;
+import java.util.Map;
+
+abstract class AbstractInvokeRequestFactory<META extends AbstractEdmMetadata<
+        EDMX, DS, S, EC, E, C, FI>, EDMX extends AbstractEdmx<DS, S, EC, E, C, FI>, DS extends AbstractDataServices<
+        S, EC, E, C, FI>, S extends AbstractSchema<EC, E, C, FI>, EC extends AbstractEntityContainer<
+        FI>, E extends AbstractEntityType, C extends AbstractComplexType, FI extends AbstractFunctionImport>
+        implements InvokeRequestFactory<META, EDMX, DS, S, EC, E, C, 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 META 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/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/invoke/InvokeRequestFactory.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/invoke/InvokeRequestFactory.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/invoke/InvokeRequestFactory.java
new file mode 100644
index 0000000..acd6777
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/invoke/InvokeRequestFactory.java
@@ -0,0 +1,69 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.invoke;
+
+import com.msopentech.odatajclient.engine.data.ODataInvokeResult;
+import com.msopentech.odatajclient.engine.data.ODataValue;
+import com.msopentech.odatajclient.engine.metadata.AbstractEdmMetadata;
+import com.msopentech.odatajclient.engine.metadata.edm.AbstractComplexType;
+import com.msopentech.odatajclient.engine.metadata.edm.AbstractDataServices;
+import com.msopentech.odatajclient.engine.metadata.edm.AbstractEdmx;
+import com.msopentech.odatajclient.engine.metadata.edm.AbstractEntityContainer;
+import com.msopentech.odatajclient.engine.metadata.edm.AbstractEntityType;
+import com.msopentech.odatajclient.engine.metadata.edm.AbstractFunctionImport;
+import com.msopentech.odatajclient.engine.metadata.edm.AbstractSchema;
+import java.io.Serializable;
+import java.net.URI;
+import java.util.Map;
+
+/**
+ * OData request factory class.
+ */
+public interface InvokeRequestFactory<META extends AbstractEdmMetadata<
+        EDMX, DS, S, EC, E, C, FI>, EDMX extends AbstractEdmx<DS, S, EC, E, C, FI>, DS extends AbstractDataServices<
+        S, EC, E, C, FI>, S extends AbstractSchema<EC, E, C, FI>, EC extends AbstractEntityContainer<
+        FI>, E extends AbstractEntityType, C extends AbstractComplexType, FI extends AbstractFunctionImport>
+        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, META 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, META metadata, FI functionImport, Map<String, ODataValue> parameters);
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/7baecb90/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/invoke/ODataInvokeRequest.java
----------------------------------------------------------------------
diff --git a/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/invoke/ODataInvokeRequest.java b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/invoke/ODataInvokeRequest.java
new file mode 100644
index 0000000..6983364
--- /dev/null
+++ b/ODataJClient/engine/src/main/java/com/msopentech/odatajclient/engine/communication/request/invoke/ODataInvokeRequest.java
@@ -0,0 +1,236 @@
+/**
+ * Copyright © Microsoft Open Technologies, Inc.
+ *
+ * All Rights Reserved
+ *
+ * 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
+ *
+ * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
+ * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
+ *
+ * See the Apache License, Version 2.0 for the specific language
+ * governing permissions and limitations under the License.
+ */
+package com.msopentech.odatajclient.engine.communication.request.invoke;
+
+import com.msopentech.odatajclient.engine.client.ODataClient;
+import com.msopentech.odatajclient.engine.client.http.HttpClientException;
+import com.msopentech.odatajclient.engine.client.http.HttpMethod;
+import com.msopentech.odatajclient.engine.communication.request.AbstractODataBasicRequestImpl;
+import com.msopentech.odatajclient.engine.communication.request.batch.ODataBatchableRequest;
+import com.msopentech.odatajclient.engine.communication.response.ODataInvokeResponse;
+import com.msopentech.odatajclient.engine.communication.response.ODataResponseImpl;
+import com.msopentech.odatajclient.engine.data.ODataEntity;
+import com.msopentech.odatajclient.engine.data.ODataEntitySet;
+import com.msopentech.odatajclient.engine.data.ODataInvokeResult;
+import com.msopentech.odatajclient.engine.data.ODataNoContent;
+import com.msopentech.odatajclient.engine.data.ODataProperty;
+import com.msopentech.odatajclient.engine.data.ODataValue;
+import com.msopentech.odatajclient.engine.format.ODataFormat;
+import com.msopentech.odatajclient.engine.format.ODataPubFormat;
+import com.msopentech.odatajclient.engine.utils.URIUtils;
+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;
+
+/**
+ * This class implements an OData invoke operation request.
+ */
+public class ODataInvokeRequest<T extends ODataInvokeResult>
+        extends AbstractODataBasicRequestImpl<ODataInvokeResponse<T>, ODataPubFormat>
+        implements 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.
+     */
+    ODataInvokeRequest(
+            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>();
+    }
+
+    /**
+     * Sets operation parameters.
+     *
+     * @param parameters operation parameters.
+     */
+    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.addProperty(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;
+        }
+    }
+}