http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/ProducerConsumerIntegrationTest.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/ProducerConsumerIntegrationTest.java
 
b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/ProducerConsumerIntegrationTest.java
new file mode 100644
index 0000000..9615caa
--- /dev/null
+++ 
b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/ProducerConsumerIntegrationTest.java
@@ -0,0 +1,811 @@
+/*******************************************************************************
+ * 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.odata2.client.core.ep;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.batch.BatchResponsePart;
+import org.apache.olingo.odata2.api.client.batch.BatchChangeSet;
+import org.apache.olingo.odata2.api.client.batch.BatchChangeSetPart;
+import org.apache.olingo.odata2.api.client.batch.BatchPart;
+import org.apache.olingo.odata2.api.client.batch.BatchSingleResponse;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.ODataDeltaFeed;
+import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.client.api.ODataClient;
+import org.apache.olingo.odata2.client.api.ep.DeserializerProperties;
+import org.apache.olingo.odata2.client.api.ep.Entity;
+import org.apache.olingo.odata2.client.api.ep.EntityCollection;
+import 
org.apache.olingo.odata2.client.api.ep.EntityCollectionSerializerProperties;
+import org.apache.olingo.odata2.client.api.ep.EntitySerializerProperties;
+import org.apache.olingo.odata2.client.api.ep.EntityStream;
+import org.apache.olingo.odata2.core.batch.v2.BatchLineReader;
+import org.apache.olingo.odata2.core.batch.v2.BatchParser;
+import org.apache.olingo.odata2.core.batch.v2.Line;
+import org.apache.olingo.odata2.testutil.mock.MockFacade;
+import org.junit.Test;
+
+public class ProducerConsumerIntegrationTest {
+  protected static final URI BASE_URI;
+  private static final String PUT = "PUT";
+  private static final String BOUNDARY = "batch_123";
+  private static final Object CRLF = "\r\n";
+
+  static {
+    try {
+      BASE_URI = new URI("http://host:80/service/";);
+    } catch (URISyntaxException e) {
+      throw new RuntimeException(e);
+    }
+  }
+  private static final DeserializerProperties DEFAULT_READ_PROPERTIES 
+  = DeserializerProperties.init()
+      .build();
+  private static final EntitySerializerProperties DEFAULT_WRITE_PROPERTIES 
+  = EntitySerializerProperties
+      .serviceRoot(
+          BASE_URI).build();
+  private static final String XML = "application/xml";
+  private static final String JSON = "application/json";
+
+  @Test
+  public void produceRoomAndThenConsumeIt() throws Exception {
+    EdmEntitySet roomSet = MockFacade.getMockEdm()
+        .getDefaultEntityContainer().getEntitySet("Rooms");
+    Entity localRoomData = new Entity();
+    localRoomData.addProperty("Id", "1");
+    localRoomData.addProperty("Name", "Neu \n Schwanstein蝴蝶");
+
+    Map<String, Object> properties = execute(localRoomData, roomSet, XML);
+    assertEquals("1", properties.get("Id"));
+    assertEquals("Neu \n Schwanstein蝴蝶", properties.get("Name"));
+
+    Map<String, Object> properties2 = execute(localRoomData, roomSet, JSON);
+    assertEquals("1", properties2.get("Id"));
+    assertEquals("Neu \n Schwanstein蝴蝶", properties2.get("Name"));
+  }
+
+  @Test
+  public void produceRoomFeedAndThenConsumeIt() throws Exception {
+    EdmEntitySet roomSet = MockFacade.getMockEdm()
+        .getDefaultEntityContainer().getEntitySet("Rooms");
+    EntityCollection roomsData = new EntityCollection();
+    Entity localRoomData = new Entity();
+    localRoomData.addProperty("Id", "1");
+    localRoomData.addProperty("Name", "Neu \n Schwanstein蝴蝶");
+    roomsData.addEntity(localRoomData);
+
+    localRoomData = new Entity();
+    localRoomData.addProperty("Id", "2");
+    localRoomData.addProperty("Name", "John蝴蝶");
+    roomsData.addEntity(localRoomData);
+    
+    List<Map<String, Object>> entries = execute1(roomsData, roomSet, XML);
+    validateResults(entries);
+    
+    entries = execute1(roomsData, roomSet, JSON);
+    validateResults(entries);
+  }
+  
+  @Test(expected=EntityProviderException.class)
+  public void negativeTests() throws Exception {
+    EdmEntitySet roomSet = MockFacade.getMockEdm()
+        .getDefaultEntityContainer().getEntitySet("Rooms");
+    Entity localRoomData = new Entity();
+    localRoomData.addProperty("Id", "1");
+    localRoomData.addProperty("Name", "Neu \n Schwanstein蝴蝶");
+
+    Map<String, Object> properties = execute(localRoomData, roomSet, "abc");
+    assertEquals("1", properties.get("Id"));
+    assertEquals("Neu \n Schwanstein蝴蝶", properties.get("Name"));   
+  }
+  
+  @Test(expected=EntityProviderException.class)
+  public void negativeTestsDeserializer() throws Exception {
+    EdmEntitySet roomSet = MockFacade.getMockEdm()
+        .getDefaultEntityContainer().getEntitySet("Rooms");
+    Entity localRoomData = new Entity();
+    localRoomData.addProperty("Id", "1");
+    localRoomData.addProperty("Name", "Neu \n Schwanstein蝴蝶");
+
+    Map<String, Object> properties = executeFail(localRoomData, roomSet, 
"abc");
+    assertEquals("1", properties.get("Id"));
+    assertEquals("Neu \n Schwanstein蝴蝶", properties.get("Name"));   
+  }
+
+  /**
+   * @param entries
+   */
+  private void validateResults(List<Map<String, Object>> entries) {
+    for (Map<String, Object> entryProperties : entries) {
+      for (Entry<String, Object> properties : entryProperties.entrySet()) {
+        if (properties.getKey().equals("Id")) {
+          assertTrue(properties.getValue().toString().contains("1") || 
+              properties.getValue().toString().contains("2"));
+        } else {
+          assertTrue(properties.getValue().toString().contains("Neu \n 
Schwanstein蝴蝶") || 
+              properties.getValue().toString().contains("John蝴蝶"));
+        }
+      }
+    }
+  }
+  
+  private Map<String, Object> execute(final Entity localRoomData, final 
EdmEntitySet roomSet,
+      final String contentType)
+      throws ODataException {
+    localRoomData.setWriteProperties(DEFAULT_WRITE_PROPERTIES);
+    ODataResponse response = 
ODataClient.newInstance().createSerializer(contentType)
+        .writeEntry(roomSet, localRoomData);
+    InputStream content = response.getEntityAsStream();
+    EntityStream entityContent = new EntityStream();
+    entityContent.setReadProperties(DEFAULT_READ_PROPERTIES);
+    entityContent.setContent(content);
+    ODataEntry entry = ODataClient.newInstance()
+        .createDeserializer(contentType).readEntry(roomSet, entityContent);
+    Map<String, Object> properties = entry.getProperties();
+    return properties;
+  }
+  
+  private Map<String, Object> executeFail(final Entity localRoomData, final 
EdmEntitySet roomSet,
+      final String contentType)
+      throws ODataException {
+    localRoomData.setWriteProperties(DEFAULT_WRITE_PROPERTIES);
+    ODataResponse response = ODataClient.newInstance().createSerializer(XML)
+        .writeEntry(roomSet, localRoomData);
+    InputStream content = response.getEntityAsStream();
+    EntityStream entityContent = new EntityStream();
+    entityContent.setReadProperties(DEFAULT_READ_PROPERTIES);
+    entityContent.setContent(content);
+    ODataEntry entry = ODataClient.newInstance()
+        .createDeserializer(contentType).readEntry(roomSet, entityContent);
+    Map<String, Object> properties = entry.getProperties();
+    return properties;
+  }
+
+  private List<Map<String, Object>> execute1(final EntityCollection 
localRoomData, final EdmEntitySet roomSet,
+      final String contentType)
+      throws ODataException {
+    List<Map<String, Object>> propertiesList = new 
ArrayList<Map<String,Object>>();
+    
localRoomData.setCollectionProperties(EntityCollectionSerializerProperties.serviceRoot(BASE_URI).build());
+    ODataResponse response = 
ODataClient.newInstance().createSerializer(contentType)
+        .writeFeed(roomSet, localRoomData);
+    InputStream content = response.getEntityAsStream();
+    EntityStream entityContent = new EntityStream();
+    entityContent.setReadProperties(DEFAULT_READ_PROPERTIES);
+    entityContent.setContent(content);
+    ODataFeed feed = ODataClient.newInstance()
+        .createDeserializer(contentType).readFeed(roomSet, entityContent);
+    List<ODataEntry> entries = feed.getEntries();
+    for (ODataEntry entry : entries) {
+      propertiesList.add(entry.getProperties());
+    }
+    return propertiesList;
+  }
+  
+  
+  @Test
+  public void executeWriteBatchRequestJSON() throws IOException, 
+  EntityProviderException, BatchException, URISyntaxException {
+    List<BatchPart> batch = new ArrayList<BatchPart>();
+    Map<String, String> headers = new HashMap<String, String>();
+    headers.put("content-type", "application/json");
+    BatchChangeSetPart request = BatchChangeSetPart.method(PUT)
+        .uri("Employees('2')")
+        .body("{\"Age\":40}")
+        .headers(headers)
+        .contentId("111")
+        .build();
+    BatchChangeSet changeSet = BatchChangeSet.newBuilder().build();
+    changeSet.add(request);
+    batch.add((BatchPart) changeSet);
+
+    InputStream batchRequest = 
ODataClient.newInstance().createSerializer(JSON).
+        readBatchRequest(batch, BOUNDARY);
+    validateBatchRequest(batchRequest);
+  }
+  
+  private void validateBatchRequest(InputStream batchRequest) throws 
IOException {
+    BatchLineReader reader =
+        new BatchLineReader(batchRequest);
+    List<Line> lines = reader.toLineList();
+    reader.close();
+    int index = 0;
+     
+    assertTrue(lines.get(index++).toString().startsWith("--batch"));
+    assertTrue(lines.get(index++).toString().startsWith("Content-Type: 
multipart/mixed; boundary=changeset_"));
+    assertEquals(CRLF, lines.get(index++).toString());
+    assertTrue(lines.get(index++).toString().startsWith("--changeset"));
+    assertEquals("Content-Type: application/http" + CRLF, 
lines.get(index++).toString());
+    assertEquals("Content-Transfer-Encoding: binary" + CRLF, 
lines.get(index++).toString());
+    assertEquals("Content-Id: 111" + CRLF, lines.get(index++).toString());
+    assertEquals(CRLF, lines.get(index++).toString());
+    assertEquals("PUT Employees('2') HTTP/1.1" + CRLF, 
lines.get(index++).toString());
+    assertEquals("Content-Length: 10" + CRLF, lines.get(index++).toString());
+    assertEquals("content-type: application/json" + CRLF, 
lines.get(index++).toString());
+    assertEquals(CRLF, lines.get(index++).toString());
+    assertEquals("{\"Age\":40}" + CRLF, lines.get(index++).toString());
+    assertTrue(lines.get(index++).toString().startsWith("--changeset"));
+    assertTrue(lines.get(index++).toString().startsWith("--batch"));
+  }
+  
+  @Test
+  public void executeWriteBatchResponseJSON() throws BatchException, 
EntityProviderException {
+    List<BatchResponsePart> parts = new ArrayList<BatchResponsePart>();
+    ODataResponse response = ODataResponse.entity("Walter Winter")
+        .status(HttpStatusCodes.OK)
+        .contentHeader("application/json")
+        .build();
+    List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
+    responses.add(response);
+    parts.add(BatchResponsePart.responses(responses).changeSet(false).build());
+
+    ODataResponse changeSetResponse = 
ODataResponse.status(HttpStatusCodes.NO_CONTENT).build();
+    responses = new ArrayList<ODataResponse>(1);
+    responses.add(changeSetResponse);
+    parts.add(BatchResponsePart.responses(responses).changeSet(true).build());
+
+    ODataResponse batchResponse = 
ODataClient.newInstance().createDeserializer(JSON).writeBatchResponse(parts);
+    assertEquals(202, batchResponse.getStatus().getStatusCode());
+    assertNotNull(batchResponse.getEntity());
+    String body = (String) batchResponse.getEntity();
+
+    assertTrue(body.contains("--batch"));
+    assertTrue(body.contains("--changeset"));
+    assertTrue(body.contains("HTTP/1.1 200 OK"));
+    assertTrue(body.contains("Content-Type: application/http"));
+    assertTrue(body.contains("Content-Transfer-Encoding: binary"));
+    assertTrue(body.contains("Walter Winter"));
+    assertTrue(body.contains("multipart/mixed; boundary=changeset"));
+    assertTrue(body.contains("HTTP/1.1 204 No Content"));
+
+    String contentHeader = batchResponse.getContentHeader();
+    BatchParser parser = new BatchParser(contentHeader, true);
+    List<BatchSingleResponse> result = parser.parseBatchResponse(new 
ByteArrayInputStream(body.getBytes()));
+    assertEquals(2, result.size());
+  }
+  
+  @Test
+  public void readFunctionImportJOSNSimpleProperty1() throws Exception {
+    final EdmFunctionImport functionImport = 
MockFacade.getMockEdm().getDefaultEntityContainer()
+        .getFunctionImport("MaximalAge");
+    InputStream content = new 
ByteArrayInputStream("{\"d\":{\"MaximalAge\":42}}".getBytes("UTF-8"));
+    EntityStream entityStream = new EntityStream();
+    entityStream.setReadProperties(DEFAULT_READ_PROPERTIES);
+    entityStream.setContent(content);    
+    
+    final Object result = executeFunctionImport(functionImport, entityStream, 
JSON);
+    assertEquals((short) 42, result);
+  }
+  
+  @Test
+  public void readFunctionImportXMLSimpleProperty() throws Exception {
+    final EdmFunctionImport functionImport = 
MockFacade.getMockEdm().getDefaultEntityContainer()
+        .getFunctionImport("MaximalAge");
+    InputStream content = new ByteArrayInputStream((
+        "<?xml version='1.0' encoding='utf-8'?>"
+        + "<MaximalAge 
xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices\"; "
+        + 
"xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\";>"
+        + "42</MaximalAge>").getBytes("UTF-8"));
+    EntityStream entityStream = new EntityStream();
+    entityStream.setReadProperties(DEFAULT_READ_PROPERTIES);
+    entityStream.setContent(content);    
+    
+    final Object result = executeFunctionImport(functionImport, entityStream, 
XML);
+    assertEquals((short) 42, result);
+  }
+  
+  @Test
+  public void readFunctionImportJOSNSimpleProperty2() throws Exception {
+    final EdmFunctionImport functionImport = 
MockFacade.getMockEdm().getDefaultEntityContainer()
+        .getFunctionImport("MaximalAge");
+    InputStream content = new 
ByteArrayInputStream("{\"MaximalAge\":42}".getBytes("UTF-8"));
+    EntityStream entityStream = new EntityStream();
+    entityStream.setReadProperties(DEFAULT_READ_PROPERTIES);
+    entityStream.setContent(content);    
+    
+    final Object result = executeFunctionImport(functionImport, entityStream, 
JSON);
+    assertEquals((short) 42, result);
+  }
+  
+  @SuppressWarnings("unchecked")
+  @Test
+  public void readFunctionImportJSONCollectionOfComplexProperty1() throws 
Exception {
+    final EdmFunctionImport functionImport = 
MockFacade.getMockEdm().getDefaultEntityContainer()
+        .getFunctionImport("AllLocations");
+    InputStream content = new ByteArrayInputStream((
+        "{\"results\": [{\"City\": 
{\"PostalCode\":\"56\",\"CityName\":\"Bangalore\"},"
+        + "\"Country\": \"India\"}]}").getBytes("UTF-8"));
+    EntityStream entityStream = new EntityStream();
+    entityStream.setReadProperties(DEFAULT_READ_PROPERTIES);
+    entityStream.setContent(content);    
+    
+    final Object result = executeFunctionImport(functionImport, entityStream, 
JSON);
+    List<Map<String, Object>> res = (List<Map<String, Object>>) result;
+    assertEquals(1, res.size());
+    assertEquals("India", ((HashMap<String, 
Object>)res.get(0)).get("Country"));
+    assertEquals(2, ((Map<String, Object>)((Map<String, 
Object>)res.get(0)).get("City")).size());
+  }
+  
+  @SuppressWarnings("unchecked")
+  @Test
+  public void readFunctionImportJSONCollectionOfComplexProperty2() throws 
Exception {
+    final EdmFunctionImport functionImport = 
MockFacade.getMockEdm().getDefaultEntityContainer()
+        .getFunctionImport("AllLocations");
+    InputStream content = new ByteArrayInputStream((
+        "{\"d\":{\"results\": [{\"City\": 
{\"PostalCode\":\"56\",\"CityName\":\"Bangalore\"},"
+        + "\"Country\": \"India\"}]}}").getBytes("UTF-8"));
+    EntityStream entityStream = new EntityStream();
+    entityStream.setReadProperties(DEFAULT_READ_PROPERTIES);
+    entityStream.setContent(content);    
+    
+    final Object result = executeFunctionImport(functionImport, entityStream, 
JSON);
+    List<Map<String, Object>> res = (List<Map<String, Object>>) result;
+    assertEquals(1, res.size());
+    assertEquals("India", ((HashMap<String, 
Object>)res.get(0)).get("Country"));
+    assertEquals(2, ((Map<String, Object>)((Map<String, 
Object>)res.get(0)).get("City")).size());
+  }
+  
+  @SuppressWarnings("unchecked")
+  @Test
+  public void readFunctionImportXMLCollectionOfComplexProperty() throws 
Exception {
+    final EdmFunctionImport functionImport = 
MockFacade.getMockEdm().getDefaultEntityContainer()
+        .getFunctionImport("AllLocations");
+    InputStream content = new ByteArrayInputStream((
+        "<?xml version='1.0' encoding='utf-8'?>"
+        + "<AllLocations 
xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices\"; "
+        + 
"xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\";>"
+        + "<element m:type=\"RefScenario.c_Location\">"
+        + "<City m:type=\"RefScenario.c_City\">"
+        + "<PostalCode>69124</PostalCode>"
+        + "<CityName>Heidelberg</CityName>"
+        + "</City>"
+        + "<Country>Germany</Country>"
+        + "</element>"
+        + "<element m:type=\"RefScenario.c_Location\">"
+        + "<City m:type=\"RefScenario.c_City\">"
+        + "<PostalCode>69190</PostalCode>"
+        + "<CityName>Walldorf</CityName>"
+        + "</City>"
+        + "<Country>Germany</Country>"
+        + "</element>"
+        + "</AllLocations>").getBytes("UTF-8"));
+    EntityStream entityStream = new EntityStream();
+    entityStream.setReadProperties(DEFAULT_READ_PROPERTIES);
+    entityStream.setContent(content);    
+    
+    final Object result = executeFunctionImport(functionImport, entityStream, 
XML);
+    List<Map<String, Object>> res = (List<Map<String, Object>>) result;
+    assertEquals(2, res.size());
+    assertEquals("Germany", ((HashMap<String, 
Object>)res.get(0)).get("Country"));
+    assertEquals(2, ((Map<String, Object>)((Map<String, 
Object>)res.get(0)).get("City")).size());
+  }
+  
+  @Test
+  public void readFunctionImportJSONSingleEntity1() throws Exception {
+    final EdmFunctionImport functionImport = 
MockFacade.getMockEdm().getDefaultEntityContainer()
+        .getFunctionImport("OldestEmployee");
+    InputStream content = new ByteArrayInputStream(
+        ("{\"d\": {"
+            + "\"__metadata\": {"
+            + "\"type\": \"RefScenario.Employee\","
+            + "\"content_type\": \"image/jpeg\","
+            + 
"\"media_src\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\","
+            + 
"\"edit_media\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\""
+            + "},"
+            + "\"EmployeeId\": \"3\","
+            + "\"EmployeeName\": \"Jonathan Smith\","
+            + "\"ManagerId\": \"1\","
+            + "\"RoomId\": \"2\","
+            + "\"TeamId\": \"1\","
+            + "\"Location\": {"
+            + "\"__metadata\": {"
+            + "\"type\": \"RefScenario.c_Location\""
+            + "},"
+            + "\"City\": {"
+            + "\"__metadata\": {"
+            + "\"type\": \"RefScenario.c_City\""
+            + "},"
+            + "\"PostalCode\": \"69190\","
+            + "\"CityName\": \"Walldorf\""
+            + "},"
+            + "\"Country\": \"Germany\""
+            + "},"
+            + "\"Age\": 56,"
+            + "\"EntryDate\": null,"
+            + "\"ImageUrl\": \"Employees('3')/$value\","
+            + "\"ne_Manager\": {"
+            + "\"__deferred\": {"
+            + "\"uri\": 
\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Manager\""
+            + "}"
+            + "},"
+            + "\"ne_Team\": {"
+            + "\"__deferred\": {"
+            + "\"uri\": 
\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Team\""
+            + "}"
+            + "},"
+            + "\"ne_Room\": {"
+            + "\"__deferred\": {"
+            + "\"uri\": 
\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Room\""
+            + "}"
+            + "}"
+            + "}"
+            + "}").getBytes("UTF-8"));
+    EntityStream entityStream = new EntityStream();
+    entityStream.setReadProperties(DEFAULT_READ_PROPERTIES);
+    entityStream.setContent(content);    
+    
+    final Object result = executeFunctionImport(functionImport, entityStream, 
JSON);
+    ODataEntry entry = (ODataEntry) result;
+    assertEquals(9, entry.getProperties().size());
+    assertEquals("3", entry.getProperties().get("EmployeeId"));
+  }
+  
+  @Test
+  public void readFunctionImportXMLSingleEntity() throws Exception {
+    final EdmFunctionImport functionImport = 
MockFacade.getMockEdm().getDefaultEntityContainer()
+        .getFunctionImport("OldestEmployee");
+    InputStream content = new ByteArrayInputStream(
+        ("<?xml version='1.0' encoding='utf-8'?>"
+            + "<entry xmlns=\"http://www.w3.org/2005/Atom\"; "
+            + 
"xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\"; "
+            + 
"xmlns:d=\"http://schemas.microsoft.com/ado/2007/08/dataservices\"; "
+            + 
"xml:base=\"http://localhost:8083/olingo-odata2-ref-web/ReferenceScenarioNonJaxrs.svc/\";>"
+            + "<id>"
+            + 
"http://localhost:8083/olingo-odata2-ref-web/ReferenceScenarioNonJaxrs.svc/Employees('3')"
+            + "</id>"
+            + "<title type=\"text\">Jonathan Smith</title>"
+            + "<updated>2017-10-26T09:06:41.15+05:30</updated>"
+            + "<category term=\"RefScenario.Employee\" "
+            + 
"scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\"/>"
+            + "<link href=\"Employees('3')\" rel=\"edit\" title=\"Employee\"/>"
+            + "<link href=\"Employees('3')/$value\" rel=\"edit-media\" "
+            + "type=\"image/jpeg\"/><link href=\"Employees('3')/ne_Manager\" "
+            + 
"rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager\";
 "
+            + "title=\"ne_Manager\" type=\"application/atom+xml;type=entry\"/>"
+            + "<link href=\"Employees('3')/ne_Team\" "
+            + 
"rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team\"; "
+            + "title=\"ne_Team\" type=\"application/atom+xml;type=entry\"/>"
+            + "<link href=\"Employees('3')/ne_Room\" "
+            + 
"rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room\"; "
+            + "title=\"ne_Room\" type=\"application/atom+xml;type=entry\"/>"
+            + "<content type=\"image/jpeg\" src=\"Employees('3')/$value\"/>"
+            + "<m:properties><d:EmployeeId>3</d:EmployeeId>"
+            + "<d:EmployeeName>Jonathan Smith</d:EmployeeName>"
+            + "<d:ManagerId>1</d:ManagerId><d:RoomId>2</d:RoomId>"
+            + "<d:TeamId>1</d:TeamId><d:Location 
m:type=\"RefScenario.c_Location\">"
+            + "<d:City 
m:type=\"RefScenario.c_City\"><d:PostalCode>69190</d:PostalCode>"
+            + 
"<d:CityName>Walldorf</d:CityName></d:City><d:Country>Germany</d:Country>"
+            + "</d:Location><d:Age>56</d:Age><d:EntryDate m:null=\"true\"/>"
+            + "<d:ImageUrl>Employees('3')/$value</d:ImageUrl>"
+            + "</m:properties></entry>").getBytes("UTF-8"));
+    EntityStream entityStream = new EntityStream();
+    entityStream.setReadProperties(DEFAULT_READ_PROPERTIES);
+    entityStream.setContent(content);    
+    
+    final Object result = executeFunctionImport(functionImport, entityStream, 
XML);
+    ODataEntry entry = (ODataEntry) result;
+    assertEquals(9, entry.getProperties().size());
+    assertEquals("3", entry.getProperties().get("EmployeeId"));
+    assertEquals("Employees('3')/ne_Manager", 
entry.getMetadata().getAssociationUris("ne_Manager").get(0));
+    assertEquals("http://localhost:8083/olingo-odata2-ref-web/";
+        + "ReferenceScenarioNonJaxrs.svc/Employees('3')", 
entry.getMetadata().getId());
+  }
+  
+  @Test
+  public void readFunctionImportJSONSingleEntity2() throws Exception {
+    final EdmFunctionImport functionImport = 
MockFacade.getMockEdm().getDefaultEntityContainer()
+        .getFunctionImport("OldestEmployee");
+    InputStream content = new ByteArrayInputStream(
+        ("{"
+            + "\"__metadata\": {"
+            + "\"type\": \"RefScenario.Employee\","
+            + "\"content_type\": \"image/jpeg\","
+            + 
"\"media_src\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\","
+            + 
"\"edit_media\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\""
+            + "},"
+            + "\"EmployeeId\": \"3\","
+            + "\"EmployeeName\": \"Jonathan Smith\","
+            + "\"ManagerId\": \"1\","
+            + "\"RoomId\": \"2\","
+            + "\"TeamId\": \"1\","
+            + "\"Location\": {"
+            + "\"__metadata\": {"
+            + "\"type\": \"RefScenario.c_Location\""
+            + "},"
+            + "\"City\": {"
+            + "\"__metadata\": {"
+            + "\"type\": \"RefScenario.c_City\""
+            + "},"
+            + "\"PostalCode\": \"69190\","
+            + "\"CityName\": \"Walldorf\""
+            + "},"
+            + "\"Country\": \"Germany\""
+            + "},"
+            + "\"Age\": 56,"
+            + "\"EntryDate\": null,"
+            + "\"ImageUrl\": \"Employees('3')/$value\","
+            + "\"ne_Manager\": {"
+            + "\"__deferred\": {"
+            + "\"uri\": 
\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Manager\""
+            + "}"
+            + "},"
+            + "\"ne_Team\": {"
+            + "\"__deferred\": {"
+            + "\"uri\": 
\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Team\""
+            + "}"
+            + "},"
+            + "\"ne_Room\": {"
+            + "\"__deferred\": {"
+            + "\"uri\": 
\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Room\""
+            + "}"
+            + "}"
+            + "}").getBytes("UTF-8"));
+    EntityStream entityStream = new EntityStream();
+    entityStream.setReadProperties(DEFAULT_READ_PROPERTIES);
+    entityStream.setContent(content);    
+    
+    final Object result = executeFunctionImport(functionImport, entityStream, 
JSON);
+    ODataEntry entry = (ODataEntry) result;
+    assertEquals(9, entry.getProperties().size());
+    assertEquals("3", entry.getProperties().get("EmployeeId"));
+  }
+  
+  @Test
+  public void readMultipleEntityJSONFunctionImport1() throws Exception {
+    final EdmFunctionImport functionImport = 
MockFacade.getMockEdm().getDefaultEntityContainer()
+        .getFunctionImport("EmployeeSearch");
+    InputStream content = new ByteArrayInputStream(
+        ("{\"d\": {"
+            + "\"results\": [{"
+            + "\"__metadata\": {"
+            + "\"type\": \"RefScenario.Employee\","
+            + "\"content_type\": \"image/jpeg\","
+            + 
"\"media_src\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\","
+            + 
"\"edit_media\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\""
+            + "},"
+            + "\"EmployeeId\": \"3\","
+            + "\"EmployeeName\": \"Jonathan Smith\","
+            + "\"ManagerId\": \"1\","
+            + "\"RoomId\": \"2\","
+            + "\"TeamId\": \"1\","
+            + "\"Location\": {"
+            + "\"__metadata\": {"
+            + "\"type\": \"RefScenario.c_Location\""
+            + "},"
+            + "\"City\": {"
+            + "\"__metadata\": {"
+            + "\"type\": \"RefScenario.c_City\""
+            + "},"
+            + "\"PostalCode\": \"69190\","
+            + "\"CityName\": \"Walldorf\""
+            + "},"
+            + "\"Country\": \"Germany\""
+            + "},"
+            + "\"Age\": 56,"
+            + "\"EntryDate\": null,"
+            + "\"ImageUrl\": \"Employees('3')/$value\","
+            + "\"ne_Manager\": {"
+            + "\"__deferred\": {"
+            + "\"uri\": 
\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Manager\""
+            + "}"
+            + "},"
+            + "\"ne_Team\": {"
+            + "\"__deferred\": {"
+            + "\"uri\": 
\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Team\""
+            + "}"
+            + "},"
+            + "\"ne_Room\": {"
+            + "\"__deferred\": {"
+            + "\"uri\": 
\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Room\""
+            + "}"
+            + "}"
+            + "}]"
+            + "}"
+            + "}").getBytes("UTF-8"));
+    EntityStream entityStream = new EntityStream();
+    entityStream.setReadProperties(DEFAULT_READ_PROPERTIES);
+    entityStream.setContent(content);
+    final Object result = executeFunctionImport(functionImport, entityStream, 
JSON);
+    ODataDeltaFeed feed = (ODataDeltaFeed) result;
+    List<ODataEntry> entries = feed.getEntries();
+    int size = entries.size();
+    assertEquals(1, size);
+    String id = (String) entries.get(0).getProperties().get("EmployeeId");
+    assertEquals("3", id);
+  }
+  
+  @Test
+  public void readMultipleEntityJSONFunctionImport2() throws Exception {
+    final EdmFunctionImport functionImport = 
MockFacade.getMockEdm().getDefaultEntityContainer()
+        .getFunctionImport("EmployeeSearch");
+    InputStream content = new ByteArrayInputStream(
+        ("{"
+            + "\"results\": [{"
+            + "\"__metadata\": {"
+            + "\"type\": \"RefScenario.Employee\","
+            + "\"content_type\": \"image/jpeg\","
+            + 
"\"media_src\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\","
+            + 
"\"edit_media\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\""
+            + "},"
+            + "\"EmployeeId\": \"3\","
+            + "\"EmployeeName\": \"Jonathan Smith\","
+            + "\"ManagerId\": \"1\","
+            + "\"RoomId\": \"2\","
+            + "\"TeamId\": \"1\","
+            + "\"Location\": {"
+            + "\"__metadata\": {"
+            + "\"type\": \"RefScenario.c_Location\""
+            + "},"
+            + "\"City\": {"
+            + "\"__metadata\": {"
+            + "\"type\": \"RefScenario.c_City\""
+            + "},"
+            + "\"PostalCode\": \"69190\","
+            + "\"CityName\": \"Walldorf\""
+            + "},"
+            + "\"Country\": \"Germany\""
+            + "},"
+            + "\"Age\": 56,"
+            + "\"EntryDate\": null,"
+            + "\"ImageUrl\": \"Employees('3')/$value\","
+            + "\"ne_Manager\": {"
+            + "\"__deferred\": {"
+            + "\"uri\": 
\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Manager\""
+            + "}"
+            + "},"
+            + "\"ne_Team\": {"
+            + "\"__deferred\": {"
+            + "\"uri\": 
\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Team\""
+            + "}"
+            + "},"
+            + "\"ne_Room\": {"
+            + "\"__deferred\": {"
+            + "\"uri\": 
\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Room\""
+            + "}"
+            + "}"
+            + "}]"
+            + "}").getBytes("UTF-8"));
+    EntityStream entityStream = new EntityStream();
+    entityStream.setReadProperties(DEFAULT_READ_PROPERTIES);
+    entityStream.setContent(content);
+    final Object result = executeFunctionImport(functionImport, entityStream, 
JSON);
+    ODataDeltaFeed feed = (ODataDeltaFeed) result;
+    List<ODataEntry> entries = feed.getEntries();
+    int size = entries.size();
+    assertEquals(1, size);
+    String id = (String) entries.get(0).getProperties().get("EmployeeId");
+    assertEquals("3", id);
+  }
+  
+  @SuppressWarnings("unchecked")
+  @Test
+  public void readMultipleEntityXMLFunctionImport() throws Exception {
+    final EdmFunctionImport functionImport = 
MockFacade.getMockEdm().getDefaultEntityContainer()
+        .getFunctionImport("EmployeeSearch");
+    InputStream content = new ByteArrayInputStream(
+        ("<?xml version='1.0' encoding='utf-8'?>"
+            + "<feed xmlns=\"http://www.w3.org/2005/Atom\"; "
+            + 
"xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\"; "
+            + 
"xmlns:d=\"http://schemas.microsoft.com/ado/2007/08/dataservices\"; "
+            + 
"xml:base=\"http://localhost:8083/olingo-odata2-ref-web/ReferenceScenarioNonJaxrs.svc/\";>"
+            + 
"<id>http://localhost:8083/olingo-odata2-ref-web/ReferenceScenarioNonJaxrs.svc/Employees</id>"
+            + "<title 
type=\"text\">Employees</title><updated>2017-10-26T09:17:27.113+05:30</updated>"
+            + "<author><name/></author><link href=\"Employees\" rel=\"self\" 
title=\"Employees\"/>"
+            + "<entry>"
+            + 
"<id>http://localhost:8083/olingo-odata2-ref-web/ReferenceScenarioNonJaxrs.svc/Employees('1')</id>"
+            + "<title type=\"text\">Walter Winter</title>"
+            + "<updated>1999-01-01T00:00:00Z</updated><category 
term=\"RefScenario.Employee\" "
+            + 
"scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\"/>"
+            + "<link href=\"Employees('1')\" rel=\"edit\" title=\"Employee\"/>"
+            + "<link href=\"Employees('1')/$value\" rel=\"edit-media\" 
type=\"image/jpeg\"/>"
+            + "<link href=\"Employees('1')/ne_Manager\" "
+            + 
"rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager\";
 "
+            + "title=\"ne_Manager\" type=\"application/atom+xml;type=entry\"/>"
+            + "<link href=\"Employees('1')/ne_Team\" "
+            + 
"rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team\"; "
+            + "title=\"ne_Team\" type=\"application/atom+xml;type=entry\"/>"
+            + "<link href=\"Employees('1')/ne_Room\" "
+            + 
"rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room\"; "
+            + "title=\"ne_Room\" type=\"application/atom+xml;type=entry\"/>"
+            + "<content type=\"image/jpeg\" src=\"Employees('1')/$value\"/>"
+            + "<m:properties><d:EmployeeId>1</d:EmployeeId>"
+            + "<d:EmployeeName>Walter Winter</d:EmployeeName>"
+            + 
"<d:ManagerId>1</d:ManagerId><d:RoomId>1</d:RoomId><d:TeamId>1</d:TeamId>"
+            + "<d:Location m:type=\"RefScenario.c_Location\"><d:City 
m:type=\"RefScenario.c_City\">"
+            + "</d:City>"
+            + "<d:Country>Germany</d:Country></d:Location><d:Age>52</d:Age>"
+            + "<d:EntryDate>1999-01-01T00:00:00</d:EntryDate>"
+            + "<d:ImageUrl>Employees('1')/$value</d:ImageUrl>"
+            + "</m:properties></entry>"
+            + "<entry>"
+            + 
"<id>http://localhost:8083/olingo-odata2-ref-web/ReferenceScenarioNonJaxrs.svc/Employees('2')</id>"
+            + "<title type=\"text\">Frederic Fall</title>"
+            + "<updated>2003-07-01T00:00:00Z</updated>"
+            + "<category term=\"RefScenario.Employee\" "
+            + 
"scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\"/>"
+            + "<link href=\"Employees('2')\" rel=\"edit\" title=\"Employee\"/>"
+            + "<link href=\"Employees('2')/$value\" rel=\"edit-media\" "
+            + "type=\"image/jpeg\"/><link href=\"Employees('2')/ne_Manager\" "
+            + 
"rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager\";
 "
+            + "title=\"ne_Manager\" type=\"application/atom+xml;type=entry\"/>"
+            + "<link href=\"Employees('2')/ne_Team\" "
+            + 
"rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team\"; "
+            + "title=\"ne_Team\" type=\"application/atom+xml;type=entry\"/>"
+            + "<link href=\"Employees('2')/ne_Room\" "
+            + 
"rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room\"; "
+            + "title=\"ne_Room\" type=\"application/atom+xml;type=entry\"/>"
+            + "<content type=\"image/jpeg\" src=\"Employees('2')/$value\"/>"
+            + "<m:properties><d:EmployeeId>2</d:EmployeeId>"
+            + "<d:EmployeeName>Frederic Fall</d:EmployeeName>"
+            + "<d:ManagerId>1</d:ManagerId><d:RoomId>2</d:RoomId>"
+            + "<d:TeamId>1</d:TeamId>"
+            + "<d:Location m:type=\"RefScenario.c_Location\" m:null=\"true\">"
+            + "</d:Location><d:Age>32</d:Age>"
+            + "<d:EntryDate>2003-07-01T00:00:00</d:EntryDate>"
+            + "</m:properties></entry></feed>").getBytes("UTF-8"));
+    EntityStream entityStream = new EntityStream();
+    entityStream.setReadProperties(DEFAULT_READ_PROPERTIES);
+    entityStream.setContent(content);
+    final Object result = executeFunctionImport(functionImport, entityStream, 
XML);
+    ODataDeltaFeed feed = (ODataDeltaFeed) result;
+    List<ODataEntry> entries = feed.getEntries();
+    int size = entries.size();
+    assertEquals(2, size);
+    assertEquals(9, entries.get(0).getProperties().size());
+    assertEquals(8, entries.get(1).getProperties().size());
+    assertEquals(0, ((Map<String, Object>)
+        ((Map<String, 
Object>)entries.get(0).getProperties().get("Location")).get("City")).size());
+    assertEquals(null, entries.get(1).getProperties().get("Location"));
+    String id = (String) entries.get(0).getProperties().get("EmployeeId");
+    assertEquals("1", id);
+  }
+
+  /**
+   * @param functionImport
+   * @param entityStream
+   * @return
+   * @throws EntityProviderException
+   */
+  private Object executeFunctionImport(final EdmFunctionImport functionImport, 
+      EntityStream entityStream, String contentType)
+      throws EntityProviderException {
+    return ODataClient.newInstance().
+        createDeserializer(contentType).readFunctionImport(functionImport, 
entityStream);
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/SerializerPropertiesTest.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/SerializerPropertiesTest.java
 
b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/SerializerPropertiesTest.java
new file mode 100644
index 0000000..32ec72c
--- /dev/null
+++ 
b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/SerializerPropertiesTest.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * 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.odata2.client.core.ep;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import 
org.apache.olingo.odata2.client.api.ep.EntityCollectionSerializerProperties;
+import org.apache.olingo.odata2.client.api.ep.EntitySerializerProperties;
+import org.apache.olingo.odata2.testutil.fit.BaseTest;
+import org.junit.Test;
+
+/**
+ *  
+ */
+public class SerializerPropertiesTest extends BaseTest {
+
+  @Test
+  public void buildFeedProperties() throws Exception {
+    URI serviceRoot = new URI("http://localhost:80/";);
+    EntitySerializerProperties properties = 
EntitySerializerProperties.serviceRoot(serviceRoot)
+        .build();
+
+    assertEquals("Wrong base uri.", "http://localhost:80/";, 
properties.getServiceRoot().toASCIIString());
+   }
+
+  @Test
+  public void buildPropertiesDefault() throws Exception {
+    URI serviceRoot = new URI("http://localhost:80/";);
+    final EntitySerializerProperties properties 
+    = EntitySerializerProperties.serviceRoot(serviceRoot).build();
+
+    assertFalse(properties.isIncludeMetadata());
+    assertTrue(properties.isValidatingFacets());
+  }
+
+  @Test
+  public void buildPropertiesAllSet() throws Exception {
+    URI serviceRoot = new URI("http://localhost:80/";);
+    Map<String, Map<String, Object>> links = new HashMap<String, Map<String, 
Object>>();
+    links.put("aNavigationProperty", Collections.<String, Object> emptyMap());
+    final EntitySerializerProperties properties = EntitySerializerProperties
+        .serviceRoot(serviceRoot)
+        .includeMetadata(true)
+        .validatingFacets(false)
+        .build();
+
+    assertEquals("Wrong base uri.", "http://localhost:80/";, 
properties.getServiceRoot().toASCIIString());
+    assertTrue("Metadata in content should be set", 
properties.isIncludeMetadata());
+    assertFalse("validating facets should be not set", 
properties.isValidatingFacets());
+  }
+
+  @Test
+  public void buildPropertiesForEntityCollectionAllSet() throws Exception {
+    URI serviceRoot = new URI("http://localhost:80/";);
+    URI selfLink = new URI("http://some.uri";);
+    final EntityCollectionSerializerProperties properties = 
+        EntityCollectionSerializerProperties.serviceRoot(serviceRoot)
+        .selfLink(selfLink)
+        .build();
+
+    assertEquals("Wrong base uri.", "http://localhost:80/";, 
properties.getServiceRoot().toASCIIString());
+    assertEquals(selfLink, properties.getSelfLink());
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractDeserializerTest.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractDeserializerTest.java
 
b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractDeserializerTest.java
new file mode 100644
index 0000000..df82949
--- /dev/null
+++ 
b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractDeserializerTest.java
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * 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.odata2.client.core.ep.deserializer;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.client.api.ep.DeserializerProperties;
+import org.apache.olingo.odata2.client.api.ep.EntityStream;
+import org.apache.olingo.odata2.testutil.fit.BaseTest;
+import org.apache.olingo.odata2.testutil.mock.MockFacade;
+
+/**
+ *  
+ */
+public abstract class AbstractDeserializerTest extends BaseTest {
+
+  protected static final DeserializerProperties DEFAULT_PROPERTIES = 
DeserializerProperties.init()
+      .build();
+
+  protected XMLStreamReader createReaderForTest(final String input) throws 
XMLStreamException {
+    return createReaderForTest(input, false);
+  }
+
+  protected XMLStreamReader createReaderForTest(final String input, final 
boolean namespaceAware)
+      throws XMLStreamException {
+    XMLInputFactory factory = XMLInputFactory.newInstance();
+    factory.setProperty(XMLInputFactory.IS_VALIDATING, false);
+    factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, namespaceAware);
+
+    XMLStreamReader streamReader = factory.createXMLStreamReader(new 
StringReader(input));
+
+    return streamReader;
+  }
+
+  protected Map<String, Object> createTypeMappings(final String key, final 
Object value) {
+    Map<String, Object> typeMappings = new HashMap<String, Object>();
+    typeMappings.put(key, value);
+    return typeMappings;
+  }
+
+  protected InputStream getFileAsStream(final String filename) throws 
IOException {
+    InputStream in = 
Thread.currentThread().getContextClassLoader().getResourceAsStream(filename);
+    if (in == null) {
+      throw new IOException("Requested file '" + filename + "' was not 
found.");
+    }
+    return in;
+  }
+
+  protected String readFile(final String filename) throws IOException {
+    InputStream in = getFileAsStream(filename);
+
+    byte[] tmp = new byte[8192];
+    int count = in.read(tmp);
+    StringBuilder b = new StringBuilder();
+    while (count >= 0) {
+      b.append(new String(tmp, 0, count));
+      count = in.read(tmp);
+    }
+
+    return b.toString();
+  }
+
+  /**
+   * Create a map with a 'String' to 'Class<?>' mapping based on given 
parameters.
+   * Therefore parameters MUST be a set of such pairs.
+   * As example an correct method call would be:
+   * <p>
+   * <code>
+   * createTypeMappings("someKey", Integer.class, "anotherKey", Long.class);
+   * </code>
+   * </p>
+   * 
+   * @param firstKeyThenMappingClass
+   * @return
+   */
+  protected Map<String, Object> createTypeMappings(final Object... 
firstKeyThenMappingClass) {
+    Map<String, Object> typeMappings = new HashMap<String, Object>();
+    if (firstKeyThenMappingClass.length % 2 != 0) {
+      throw new IllegalArgumentException("Got odd number of parameters. Please 
read javadoc.");
+    }
+    for (int i = 0; i < firstKeyThenMappingClass.length; i += 2) {
+      String key = (String) firstKeyThenMappingClass[i];
+      Class<?> mappingClass = (Class<?>) firstKeyThenMappingClass[i + 1];
+      typeMappings.put(key, mappingClass);
+    }
+    return typeMappings;
+  }
+
+  protected InputStream createContentAsStream(final String content) throws 
UnsupportedEncodingException {
+    return new ByteArrayInputStream(content.getBytes("UTF-8"));
+  }
+
+  /**
+   * 
+   * @param content
+   * @param replaceWhitespaces if <code>true</code> all XML not necessary 
whitespaces between tags are
+   * @return
+   * @throws UnsupportedEncodingException
+   */
+  protected InputStream createContentAsStream(final String content, final 
boolean replaceWhitespaces)
+      throws UnsupportedEncodingException {
+    String contentForStream = content;
+    if (replaceWhitespaces) {
+      contentForStream = content.replaceAll(">\\s.<", "><");
+    }
+
+    return new ByteArrayInputStream(contentForStream.getBytes("UTF-8"));
+  }
+
+  protected ODataEntry prepareAndExecuteEntry(final String fileName, final 
String entitySetName,
+      final DeserializerProperties readProperties) throws IOException, 
EdmException, ODataException,
+      UnsupportedEncodingException, EntityProviderException {
+    // prepare
+    EdmEntitySet entitySet = 
MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet(entitySetName);
+    String content = readFile(fileName);
+    assertNotNull(content);
+    InputStream contentBody = createContentAsStream(content);
+    EntityStream entityStream = new EntityStream();
+    entityStream.setContent(contentBody);
+    entityStream.setReadProperties(readProperties);
+
+    // execute
+    JsonEntityDeserializer xec = new JsonEntityDeserializer();
+    ODataEntry result = xec.readEntry(entitySet, entityStream);
+    assertNotNull(result);
+    return result;
+  }
+
+  protected ODataFeed prepareAndExecuteFeed(final String fileName, final 
String entitySetName,
+      final DeserializerProperties readProperties) throws IOException, 
EdmException, ODataException,
+      UnsupportedEncodingException, EntityProviderException {
+    // prepare
+    EdmEntitySet entitySet = 
MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet(entitySetName);
+    String content = readFile(fileName);
+    assertNotNull(content);
+    InputStream contentBody = createContentAsStream(content);
+    EntityStream entityStream = new EntityStream();
+    entityStream.setContent(contentBody);
+    entityStream.setReadProperties(readProperties);
+
+    // execute
+    JsonEntityDeserializer xec = new JsonEntityDeserializer();
+    ODataFeed result = xec.readFeed(entitySet, entityStream);
+    assertNotNull(result);
+    return result;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractXmlDeserializerTest.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractXmlDeserializerTest.java
 
b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractXmlDeserializerTest.java
new file mode 100644
index 0000000..bfd3c6c
--- /dev/null
+++ 
b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractXmlDeserializerTest.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * 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.odata2.client.core.ep.deserializer;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public abstract class AbstractXmlDeserializerTest extends 
AbstractDeserializerTest {
+
+  public enum StreamWriterImplType {
+    WOODSTOCKIMPL, SUNINTERNALIMPL;
+  }
+
+  // CHECKSTYLE:OFF
+  public AbstractXmlDeserializerTest(final StreamWriterImplType type) {
+    switch (type) {
+    case WOODSTOCKIMPL:
+      System.setProperty("javax.xml.stream.XMLInputFactory", 
"com.ctc.wstx.stax.WstxInputFactory"); // NOSONAR
+      System.setProperty("javax.xml.stream.XMLOutputFactory", 
"com.ctc.wstx.stax.WstxOutputFactory"); // NOSONAR
+      break;
+    case SUNINTERNALIMPL:
+      System.setProperty("javax.xml.stream.XMLInputFactory", 
"com.sun.xml.internal.stream.XMLInputFactoryImpl"); // NOSONAR
+      System.setProperty("javax.xml.stream.XMLOutputFactory", 
"com.sun.xml.internal.stream.XMLOutputFactoryImpl"); // NOSONAR
+      break;
+    default:
+      System.setProperty("javax.xml.stream.XMLOutputFactory", 
"com.sun.xml.internal.stream.XMLOutputFactoryImpl"); // NOSONAR
+      System.setProperty("javax.xml.stream.XMLInputFactory", 
"com.sun.xml.internal.stream.XMLInputFactoryImpl"); // NOSONAR
+      break;
+    }
+  }
+
+  // CHECKSTYLE:On
+
+  @Parameterized.Parameters
+  public static List<Object[]> data() {
+    // If desired this can be made dependent on runtime variables
+    Object[][] a = new Object[2][1];
+    a[0][0] = StreamWriterImplType.WOODSTOCKIMPL;
+    a[1][0] = StreamWriterImplType.SUNINTERNALIMPL;
+
+    return Arrays.asList(a);
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/Callback.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/Callback.java
 
b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/Callback.java
new file mode 100644
index 0000000..2d1bf91
--- /dev/null
+++ 
b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/Callback.java
@@ -0,0 +1,21 @@
+package org.apache.olingo.odata2.client.core.ep.deserializer;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.client.api.ep.DeserializerProperties;
+import 
org.apache.olingo.odata2.client.api.ep.callback.OnDeserializeInlineContent;
+
+public class Callback implements OnDeserializeInlineContent {
+
+  @Override
+  public DeserializerProperties receiveReadProperties(DeserializerProperties 
readProperties,
+      EdmNavigationProperty navigationProperty) throws 
ODataApplicationException {
+    Map<String, Object> typeMappings = new HashMap<String, Object>();
+    return DeserializerProperties.init().addTypeMappings(typeMappings).
+        callback(new Callback()).build();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertEntryTest.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertEntryTest.java
 
b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertEntryTest.java
new file mode 100644
index 0000000..d6f25a7
--- /dev/null
+++ 
b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertEntryTest.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * 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.odata2.client.core.ep.deserializer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.edm.EdmType;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.client.api.ep.DeserializerProperties;
+import org.apache.olingo.odata2.client.api.ep.EntityStream;
+import 
org.apache.olingo.odata2.client.api.ep.callback.OnDeserializeInlineContent;
+import org.apache.olingo.odata2.testutil.mock.MockFacade;
+import org.junit.Test;
+
+public class JsonEntryDeepInsertEntryTest extends AbstractDeserializerTest {
+
+  private static final String EMPLOYEE_WITH_INLINE_TEAM = 
"JsonEmployeeWithInlineTeam.json";
+  private static final String INLINE_ROOM_WITH_INLINE_BUILDING = 
"JsonInlineRoomWithInlineBuilding.json";
+  private static final String INLINE_ROOM_WITH_INLINE_NULL = 
"JsonInlineRoomWithInlineNull.json";
+
+  @Test
+  public void innerEntryNoMediaResource() throws Exception {
+    ODataEntry outerEntry = prepareAndExecuteEntry(EMPLOYEE_WITH_INLINE_TEAM, 
"Employees", DEFAULT_PROPERTIES);
+    assertTrue(outerEntry.containsInlineEntry());
+
+    ODataEntry innerTeam = (ODataEntry) 
outerEntry.getProperties().get("ne_Team");
+    assertNotNull(innerTeam);
+    assertFalse(innerTeam.containsInlineEntry());
+
+    Map<String, Object> innerTeamProperties = innerTeam.getProperties();
+
+    assertEquals("1", innerTeamProperties.get("Id"));
+    assertEquals("Team 1", innerTeamProperties.get("Name"));
+    assertEquals(Boolean.FALSE, innerTeamProperties.get("isScrumTeam"));
+    assertNull(innerTeamProperties.get("nt_Employees"));
+
+    List<String> associationUris = 
innerTeam.getMetadata().getAssociationUris("nt_Employees");
+    assertEquals(1, associationUris.size());
+    
assertEquals("http://localhost:8080/ReferenceScenario.svc/Teams('1')/nt_Employees",
 associationUris.get(0));
+  }
+
+  @Test
+  public void innerEntryWithOptionalNavigationProperty() throws Exception {
+    // prepare
+    DeserializerProperties readProperties =
+        DeserializerProperties.init().build();
+    EdmEntitySet entitySet = 
MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+    // modify edm for test case (change multiplicity to ZERO_TO_ONE)
+    EdmType navigationType = mock(EdmType.class);
+    when(navigationType.getKind()).thenReturn(EdmTypeKind.ENTITY);
+
+    EdmNavigationProperty navigationProperty = 
mock(EdmNavigationProperty.class);
+    when(navigationProperty.getName()).thenReturn("ne_Team");
+    when(navigationProperty.getType()).thenReturn(navigationType);
+    
when(navigationProperty.getMultiplicity()).thenReturn(EdmMultiplicity.ZERO_TO_ONE);
+
+    
when(entitySet.getEntityType().getProperty("ne_Team")).thenReturn(navigationProperty);
+    EdmEntitySet targetEntitySet = 
MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams");
+    
when(entitySet.getRelatedEntitySet(navigationProperty)).thenReturn(targetEntitySet);
+
+    // execute
+    JsonEntityDeserializer xec = new JsonEntityDeserializer();
+    InputStream contentBody = getFileAsStream(EMPLOYEE_WITH_INLINE_TEAM);
+    EntityStream entityStream = new EntityStream();
+    entityStream.setContent(contentBody);
+    entityStream.setReadProperties(readProperties);
+    ODataEntry outerEntry = xec.readEntry(entitySet, entityStream);
+
+    ODataEntry innerTeam = (ODataEntry) 
outerEntry.getProperties().get("ne_Team");
+    Map<String, Object> innerTeamProperties = innerTeam.getProperties();
+
+    assertEquals("1", innerTeamProperties.get("Id"));
+    assertEquals("Team 1", innerTeamProperties.get("Name"));
+    assertEquals(Boolean.FALSE, innerTeamProperties.get("isScrumTeam"));
+    assertNull(innerTeamProperties.get("nt_Employees"));
+
+    List<String> associationUris = 
innerTeam.getMetadata().getAssociationUris("nt_Employees");
+    assertEquals(1, associationUris.size());
+    
assertEquals("http://localhost:8080/ReferenceScenario.svc/Teams('1')/nt_Employees",
 associationUris.get(0));
+  }
+
+  @Test
+  public void inlineRoomWithInlineBuilding() throws Exception {
+    OnDeserializeInlineContent callback = new Callback();
+    DeserializerProperties readProperties = 
DeserializerProperties.init().callback(callback).build();
+    ODataEntry outerEntry = 
prepareAndExecuteEntry(INLINE_ROOM_WITH_INLINE_BUILDING, "Employees", 
readProperties);
+    assertTrue(outerEntry.containsInlineEntry());
+
+    ODataEntry innerRoom = (ODataEntry) 
outerEntry.getProperties().get("ne_Room");
+    assertNotNull(innerRoom);
+    assertTrue(innerRoom.containsInlineEntry());
+
+    Map<String, Object> innerRoomProperties = innerRoom.getProperties();
+
+    assertEquals(5, innerRoomProperties.size());
+    assertEquals("1", innerRoomProperties.get("Id"));
+    assertEquals("Room 1", innerRoomProperties.get("Name"));
+    assertEquals(Short.valueOf("1"), innerRoomProperties.get("Version"));
+    assertEquals(Short.valueOf("1"), innerRoomProperties.get("Seats"));
+    assertNull(innerRoomProperties.get("nr_Employees"));
+
+    List<String> associationUris = 
innerRoom.getMetadata().getAssociationUris("nr_Employees");
+    assertEquals(1, associationUris.size());
+    
assertEquals("http://localhost:8080/ReferenceScenario.svc/Rooms('1')/nr_Employees",
 associationUris.get(0));
+
+    associationUris = 
innerRoom.getMetadata().getAssociationUris("nr_Building");
+    assertEquals(Collections.emptyList(), associationUris);
+
+    assertEquals("W/\"1\"", innerRoom.getMetadata().getEtag());
+
+    ODataEntry innerBuilding = (ODataEntry) 
innerRoomProperties.get("nr_Building");
+    assertNotNull(innerBuilding);
+    assertFalse(innerBuilding.containsInlineEntry());
+
+    Map<String, Object> innerBuildingProperties = 
innerBuilding.getProperties();
+    assertEquals(3, innerBuildingProperties.size());
+    assertEquals("1", innerBuildingProperties.get("Id"));
+    assertEquals("Building 1", innerBuildingProperties.get("Name"));
+    assertEquals(null, innerBuildingProperties.get("Image"));
+    assertNull(innerBuildingProperties.get("nb_Rooms"));
+
+    associationUris = 
innerBuilding.getMetadata().getAssociationUris("nb_Rooms");
+    assertEquals(1, associationUris.size());
+    
assertEquals("http://localhost:8080/ReferenceScenario.svc/Buildings('1')/nb_Rooms",
 associationUris.get(0));
+  }
+
+  @Test
+  public void inlineRoomWithInlineNull() throws Exception {
+    DeserializerProperties readProperties =
+        DeserializerProperties.init().build();
+    ODataEntry outerEntry = 
prepareAndExecuteEntry(INLINE_ROOM_WITH_INLINE_NULL, "Employees", 
readProperties);
+
+    ODataEntry innerRoom = (ODataEntry) 
outerEntry.getProperties().get("ne_Room");
+    assertNull(innerRoom);
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertFeedTest.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertFeedTest.java
 
b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertFeedTest.java
new file mode 100644
index 0000000..b1a8d0b
--- /dev/null
+++ 
b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertFeedTest.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * 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.odata2.client.core.ep.deserializer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.FeedMetadata;
+import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.client.api.ep.EntityStream;
+import 
org.apache.olingo.odata2.client.core.ep.deserializer.JsonEntityDeserializer;
+import org.apache.olingo.odata2.testutil.mock.MockFacade;
+import org.junit.Test;
+
+/**
+ *  
+ */
+public class JsonEntryDeepInsertFeedTest extends AbstractDeserializerTest {
+
+  private static final String BUILDING_WITH_INLINE_ROOMS = 
"JsonBuildingWithInlineRooms.json";
+  private static final String BUILDING_WITH_INLINE_ROOMS_CLIENT_CASE = 
"JsonBuildingWithInlineRoomsClientCase.json";
+  private static final String TEAM_WITH_INLINE_EMPLOYEES = 
"JsonTeamsWithInlineEmployees.json";
+  private static final String BUILDING_WITH_INLINE_ROOMS_NEXTLINK_AND_COUNT =
+      "JsonBuildingWithInlineRoomsAndNextLinkAndCount.json";
+
+  @Test
+  public void innerFeedWithoutResultsWrapperClientUseCase() throws Exception {
+    ODataEntry outerEntry = prepareAndExecuteEntry(
+        BUILDING_WITH_INLINE_ROOMS_CLIENT_CASE, "Buildings", 
DEFAULT_PROPERTIES);
+
+    ODataFeed innerRoomFeed = (ODataFeed) 
outerEntry.getProperties().get("nb_Rooms");
+    assertNotNull(innerRoomFeed);
+
+    List<ODataEntry> rooms = innerRoomFeed.getEntries();
+    assertNotNull(rooms);
+    assertEquals(1, rooms.size());
+
+    ODataEntry room = rooms.get(0);
+    Map<String, Object> roomProperties = room.getProperties();
+
+    assertEquals(4, roomProperties.size());
+    assertEquals("1", roomProperties.get("Id"));
+    assertEquals("Room 1", roomProperties.get("Name"));
+    assertEquals(Short.valueOf("1"), roomProperties.get("Version"));
+    assertEquals(Short.valueOf("1"), roomProperties.get("Seats"));
+
+    List<String> associationUris = 
room.getMetadata().getAssociationUris("nr_Employees");
+    assertEquals(1, associationUris.size());
+    
assertEquals("http://localhost:8080/ReferenceScenario.svc/Rooms('1')/nr_Employees",
 associationUris.get(0));
+
+    associationUris = room.getMetadata().getAssociationUris("nr_Building");
+    assertEquals(1, associationUris.size());
+    
assertEquals("http://localhost:8080/ReferenceScenario.svc/Rooms('1')/nr_Building",
 associationUris.get(0));
+  }
+  
+  @Test
+  public void innerFeedNoMediaResource() throws Exception {
+    ODataEntry outerEntry = prepareAndExecuteEntry(BUILDING_WITH_INLINE_ROOMS, 
"Buildings", DEFAULT_PROPERTIES);
+
+    ODataFeed innerRoomFeed = (ODataFeed) 
outerEntry.getProperties().get("nb_Rooms");
+    assertNotNull(innerRoomFeed);
+
+    List<ODataEntry> rooms = innerRoomFeed.getEntries();
+    assertNotNull(rooms);
+    assertEquals(1, rooms.size());
+
+    ODataEntry room = rooms.get(0);
+    Map<String, Object> roomProperties = room.getProperties();
+
+    assertEquals(4, roomProperties.size());
+    assertEquals("1", roomProperties.get("Id"));
+    assertEquals("Room 1", roomProperties.get("Name"));
+    assertEquals(Short.valueOf("1"), roomProperties.get("Version"));
+    assertEquals(Short.valueOf("1"), roomProperties.get("Seats"));
+
+    List<String> associationUris = 
room.getMetadata().getAssociationUris("nr_Employees");
+    assertEquals(1, associationUris.size());
+    
assertEquals("http://localhost:8080/ReferenceScenario.svc/Rooms('1')/nr_Employees",
 associationUris.get(0));
+
+    associationUris = room.getMetadata().getAssociationUris("nr_Building");
+    assertEquals(1, associationUris.size());
+    
assertEquals("http://localhost:8080/ReferenceScenario.svc/Rooms('1')/nr_Building",
 associationUris.get(0));
+  }
+
+  @Test
+  public void innerFeedNoMediaResourceContainsNextLinkAndCount() throws 
Exception {
+    ODataEntry outerEntry =
+        prepareAndExecuteEntry(BUILDING_WITH_INLINE_ROOMS_NEXTLINK_AND_COUNT, 
"Buildings", DEFAULT_PROPERTIES);
+
+    ODataFeed innerRoomFeed = (ODataFeed) 
outerEntry.getProperties().get("nb_Rooms");
+    assertNotNull(innerRoomFeed);
+
+    List<ODataEntry> rooms = innerRoomFeed.getEntries();
+    assertNotNull(rooms);
+    assertEquals(1, rooms.size());
+
+    FeedMetadata roomsMetadata = innerRoomFeed.getFeedMetadata();
+    assertEquals(Integer.valueOf(1), roomsMetadata.getInlineCount());
+    assertEquals("nextLink", roomsMetadata.getNextLink());
+  }
+
+  @Test
+  public void innerFeedNoMediaResourceSimpleArray() throws Exception {
+    EdmEntitySet entitySet = 
MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Buildings");
+    String content = "{\"d\":{\"Id\":\"1\",\"Name\":\"Building 1\","
+        + "\"nb_Rooms\":[{\"Id\":\"1\",\"Name\":\"Room 1\"}]}}";
+    InputStream contentBody = createContentAsStream(content);
+    EntityStream entityStream = new EntityStream();
+    entityStream.setContent(contentBody);
+    entityStream.setReadProperties(DEFAULT_PROPERTIES);
+    final ODataEntry outerEntry = new 
JsonEntityDeserializer().readEntry(entitySet, entityStream);
+    assertNotNull(outerEntry);
+    final ODataFeed innerRoomFeed = (ODataFeed) 
outerEntry.getProperties().get("nb_Rooms");
+    assertNotNull(innerRoomFeed);
+
+    final List<ODataEntry> rooms = innerRoomFeed.getEntries();
+    assertNotNull(rooms);
+    assertEquals(1, rooms.size());
+  }
+
+  @Test
+  public void innerFeedMediaResource() throws Exception {
+    ODataEntry outerEntry = prepareAndExecuteEntry(TEAM_WITH_INLINE_EMPLOYEES, 
"Teams", DEFAULT_PROPERTIES);
+
+    ODataFeed innerEmployeeFeed = (ODataFeed) 
outerEntry.getProperties().get("nt_Employees");
+    assertNotNull(innerEmployeeFeed);
+
+    List<ODataEntry> employees = innerEmployeeFeed.getEntries();
+    assertNotNull(employees);
+    assertEquals(3, employees.size());
+  }
+}

Reply via email to