[OLINGO-1054]Inline Consumer Callback Data handling
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumer.java
index d1c4179..c9781f0 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumer.java
@@ -321,7 +321,7 @@
               resultEntry.setContainsInlineEntry(true);
             } else {
               ReadFeedResult result = new ReadFeedResult(inlineReadProperties, navigationProperty, 
-                  feed, entryMetadata.getId());
+                  feed, entryMetadata.getId() != null ? entryMetadata.getId() : fetchParentIdInfo(eia, resultEntry));
               callback.handleReadFeed(result);
             }
           } else {
@@ -333,7 +333,7 @@
               resultEntry.setContainsInlineEntry(true);
             } else {
               ReadEntryResult result = new ReadEntryResult(inlineReadProperties, navigationProperty, 
-                  entry, entryMetadata.getId());
+                  entry, entryMetadata.getId() != null ? entryMetadata.getId() : fetchParentIdInfo(eia, resultEntry));
               callback.handleReadEntry(result);
             }
           }
@@ -374,7 +374,7 @@
         resultEntry.setContainsInlineEntry(true);
       } else {
         ReadFeedResult result = new ReadFeedResult(inlineReadProperties, navigationProperty,
-            feed, entryMetadata.getId());
+            feed, entryMetadata.getId() != null ? entryMetadata.getId() : fetchParentIdInfo(eia, resultEntry));
         try {
           callback.handleReadFeed(result);
         } catch (final ODataApplicationException e) {
@@ -385,6 +385,31 @@
     }
   }
 
+  /**
+   * 
+   * @param eia
+   * @param resultEntry
+   * @return
+   * @throws EdmException
+   */
+  private String fetchParentIdInfo(EntityInfoAggregator eia, ODataEntryImpl resultEntry) throws EdmException {
+    String keyInfo = "";
+    if (null != resultEntry) {
+      if (eia != null && eia.getEntityType() != null) {
+        List<String> keys = eia.getEntityType().getKeyPropertyNames();
+        int i = 0;
+        for (String key : keys) {
+          keyInfo += key + "=" + resultEntry.getProperties().get(key);
+          i++;
+          if (i < keys.size()) {
+            keyInfo += ",";
+          }
+        }
+      }
+    }
+    return keyInfo;
+  }
+  
   private void updateExpandSelectTree(final String navigationPropertyName, final ODataFeed feed) {
     List<ODataEntry> entries = feed.getEntries();
     if (!entries.isEmpty()) {
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/AbstractConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/AbstractConsumerTest.java
index 37a352c..5016b55 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/AbstractConsumerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/AbstractConsumerTest.java
@@ -26,19 +26,25 @@
 import java.io.StringReader;
 import java.io.UnsupportedEncodingException;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
 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.EdmEntityType;
 import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.edm.EdmType;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
 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.api.uri.ExpandSelectTreeNode;
 import org.apache.olingo.odata2.testutil.fit.BaseTest;
 import org.apache.olingo.odata2.testutil.mock.MockFacade;
 
@@ -172,4 +178,85 @@
     return result;
   }
 
+  /**
+   * @param inlineEntries
+   * @param feed
+   * @param entry
+   * @param edmEntityType 
+   * @throws EdmException 
+   */
+  protected void getExpandedData(Map<String, Object> inlineEntries, 
+      ODataEntry entry, EdmType edmType) throws EdmException {
+    assertNotNull(entry);
+    Map<String, ExpandSelectTreeNode> expandNodes = entry.getExpandSelectTree().getLinks();
+    for (Entry<String, ExpandSelectTreeNode> expand : expandNodes.entrySet()) {
+      assertNotNull(expand.getKey());
+      String keyName = extractKey(entry, (EdmEntityType)edmType, expand);
+      if (inlineEntries.containsKey(keyName)) {
+        if (inlineEntries.get(keyName) instanceof ODataFeed) {
+          ODataFeed innerFeed = (ODataFeed) inlineEntries.get(keyName);
+          assertNotNull(innerFeed);
+          getExpandedData(inlineEntries, innerFeed,
+              ((EdmNavigationProperty)((EdmEntityType)edmType).getProperty(expand.getKey())).getType());
+          entry.getProperties().put(expand.getKey(), innerFeed);
+        } else if (inlineEntries.get(keyName) instanceof ODataEntry) {
+          ODataEntry innerEntry = (ODataEntry) inlineEntries.get(keyName);
+          assertNotNull(innerEntry);
+          getExpandedData(inlineEntries, innerEntry,
+              ((EdmNavigationProperty)((EdmEntityType)edmType).getProperty(expand.getKey())).getType());
+          entry.getProperties().put(expand.getKey(), innerEntry);
+        }
+      }
+    }
+  }
+  
+  /**
+   * Extract key information to map the parent entry to child entry
+   * @param entry
+   * @param edmEntityType
+   * @param expand
+   * @return
+   * @throws EdmException
+   */
+  private String extractKey(ODataEntry entry, EdmEntityType edmEntityType, Entry<String, 
+      ExpandSelectTreeNode> expand) throws EdmException {
+    return entry.getMetadata().getId() != null ?
+        (expand.getKey() + entry.getMetadata().getId()) : 
+          (expand.getKey() + edmEntityType.getKeyPropertyNames().get(0) + "=" + 
+        entry.getProperties().get(edmEntityType.getKeyPropertyNames().get(0)));
+  }
+
+  /**
+   * @param inlineEntries
+   * @param feed
+   * @param entry
+   * @throws EdmException 
+   */
+  protected void getExpandedData(Map<String, Object> inlineEntries, 
+      ODataFeed feed, EdmType edmType) throws EdmException {
+    assertNotNull(feed.getEntries());
+    List<ODataEntry> entries = feed.getEntries();
+    for (ODataEntry entry : entries) {
+      Map<String, ExpandSelectTreeNode> expandNodes = entry.getExpandSelectTree().getLinks();
+      for (Entry<String, ExpandSelectTreeNode> expand : expandNodes.entrySet()) {
+        assertNotNull(expand.getKey());
+        String keyName = extractKey(entry, (EdmEntityType) edmType, expand);
+        if (inlineEntries.containsKey(keyName)) {
+          if (inlineEntries.get(keyName) instanceof ODataFeed) {
+            ODataFeed innerFeed = (ODataFeed) inlineEntries.get(keyName);
+            assertNotNull(innerFeed);
+            getExpandedData(inlineEntries, innerFeed,
+                ((EdmNavigationProperty)((EdmEntityType)edmType).getProperty(expand.getKey())).getType());
+            feed.getEntries().get(feed.getEntries().indexOf(entry)).getProperties().put(expand.getKey(), innerFeed);
+          } else if (inlineEntries.get(keyName) instanceof ODataEntry) {
+            ODataEntry innerEntry = (ODataEntry) inlineEntries.get(keyName);
+            assertNotNull(innerEntry);
+            getExpandedData(inlineEntries, innerEntry,
+                ((EdmNavigationProperty)((EdmEntityType)edmType).getProperty(expand.getKey())).getType());
+            feed.getEntries().get(feed.getEntries().indexOf(entry)).getProperties().put(expand.getKey(), innerEntry);
+          }
+        }
+      }
+    }
+  }
 }
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumerTest.java
index b0b5c7e..145f8f4 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumerTest.java
@@ -29,7 +29,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.TimeZone;
-import java.util.Map.Entry;
 
 import org.apache.olingo.odata2.api.edm.EdmEntitySet;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
@@ -38,7 +37,6 @@
 import org.apache.olingo.odata2.api.ep.entry.MediaMetadata;
 import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
 import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
-import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
 import org.apache.olingo.odata2.testutil.mock.MockFacade;
 import org.junit.Test;
 
@@ -371,7 +369,37 @@
     assertEquals(9, result.getProperties().size());
 
     Map<String, Object> inlineEntries = callback.getNavigationProperties();
-    getExpandedData(inlineEntries, result);
+    getExpandedData(inlineEntries, result, entitySet.getEntityType());
+    assertEquals(10, result.getProperties().size());
+    assertEquals(5, ((ODataEntry)result.getProperties().get("ne_Room")).getProperties().size());
+    assertEquals(3, ((ODataEntry)((ODataEntry)result.getProperties().get("ne_Room")).getProperties()
+        .get("nr_Building")).getProperties().size());
+  }
+  
+  /**
+   * Employee with inline entity Room with inline entity Buildings with no metadata
+   * Scenario of 1:1:1 navigation
+   * E.g: Employees('1')?$expand=ne_Room/nr_Building
+   * @throws Exception
+   */
+  @Test
+  public void employeesEntryWithEmployeeToRoomToBuildingWithoutMetadata() throws Exception {
+    InputStream stream = getFileAsStream("JsonEmployeeInlineRoomBuildingWithoutMetadata.json");
+    assertNotNull(stream);
+    FeedCallback callback = new FeedCallback();
+
+    EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+        .mergeSemantic(false).callback(callback).build();
+
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+    JsonEntityConsumer xec = new JsonEntityConsumer();
+    ODataEntry result =
+        xec.readEntry(entitySet, stream, readProperties);
+    assertNotNull(result);
+    assertEquals(9, result.getProperties().size());
+
+    Map<String, Object> inlineEntries = callback.getNavigationProperties();
+    getExpandedData(inlineEntries, result, entitySet.getEntityType());
     assertEquals(10, result.getProperties().size());
     assertEquals(5, ((ODataEntry)result.getProperties().get("ne_Room")).getProperties().size());
     assertEquals(3, ((ODataEntry)((ODataEntry)result.getProperties().get("ne_Room")).getProperties()
@@ -401,13 +429,45 @@
     assertEquals(4, result.getProperties().size());
 
     Map<String, Object> inlineEntries = callback.getNavigationProperties();
-    getExpandedData(inlineEntries, result);
+    getExpandedData(inlineEntries, result, entitySet.getEntityType());
     assertEquals(5, result.getProperties().size());
     for (ODataEntry employeeEntry : ((ODataFeed)result.getProperties().get("nr_Employees")).getEntries()) {
       assertEquals(10, employeeEntry.getProperties().size());
       assertEquals(3, ((ODataEntry)employeeEntry.getProperties().get("ne_Team")).getProperties().size());
     }
   }
+  
+  /**
+   * Room has inline entity to Employees and has inline entry To Team
+   * Scenario of 1:n:1 navigation 
+   * E.g: Rooms('1')?$expand=nr_Employees/ne_Team
+   * @throws Exception
+   */
+  @Test
+  public void RoomEntryWithInlineEmployeeInlineTeamWithoutMetadata() throws Exception {
+    InputStream stream = getFileAsStream("JsonRoom_InlineEmployeesToTeamWithoutMetadata.json");
+    assertNotNull(stream);
+    FeedCallback callback = new FeedCallback();
+
+    EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+        .mergeSemantic(false).callback(callback).build();
+
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+    JsonEntityConsumer xec = new JsonEntityConsumer();
+    ODataEntry result =
+        xec.readEntry(entitySet, stream, readProperties);
+    assertNotNull(result);
+    assertEquals(4, result.getProperties().size());
+
+    Map<String, Object> inlineEntries = callback.getNavigationProperties();
+    getExpandedData(inlineEntries, result, entitySet.getEntityType());
+    assertEquals(5, result.getProperties().size());
+    for (ODataEntry employeeEntry : ((ODataFeed)result.getProperties().get("nr_Employees")).getEntries()) {
+      assertEquals(10, employeeEntry.getProperties().size());
+      assertEquals(3, ((ODataEntry)employeeEntry.getProperties().get("ne_Team")).getProperties().size());
+    }
+  }
+  
   /**
    * Room has empty inline entity to Employees and has inline entry To Team
    * E.g: Rooms('10')?$expand=nr_Employees/ne_Team
@@ -430,7 +490,7 @@
     assertEquals(4, result.getProperties().size());
 
     Map<String, Object> inlineEntries = callback.getNavigationProperties();
-    getExpandedData(inlineEntries, result);
+    getExpandedData(inlineEntries, result, entitySet.getEntityType());
     assertEquals(5, result.getProperties().size());
     assertEquals(0, ((ODataFeed)result.getProperties().get("nr_Employees")).getEntries().size());
   }
@@ -461,58 +521,4 @@
     assertNull(entry.getExpandSelectTree().getExpandedList().get(2)
         .getLinks().get("nr_Employees").getLinks().get("ne_Room"));
   }
-  
-  /**
-   * @param inlineEntries
-   * @param feed
-   * @param entry
-   */
-  private void getExpandedData(Map<String, Object> inlineEntries, ODataEntry entry) {
-    assertNotNull(entry);
-    Map<String, ExpandSelectTreeNode> expandNodes = entry.getExpandSelectTree().getLinks();
-    for (Entry<String, ExpandSelectTreeNode> expand : expandNodes.entrySet()) {
-      assertNotNull(expand.getKey());
-      if (inlineEntries.containsKey(expand.getKey() + entry.getMetadata().getId())) {
-        if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataFeed) {
-          ODataFeed innerFeed = (ODataFeed) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
-          assertNotNull(innerFeed);
-          getExpandedData(inlineEntries, innerFeed);
-          entry.getProperties().put(expand.getKey(), innerFeed);
-        } else if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataEntry) {
-          ODataEntry innerEntry = (ODataEntry) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
-          assertNotNull(innerEntry);
-          getExpandedData(inlineEntries, innerEntry);
-          entry.getProperties().put(expand.getKey(), innerEntry);
-        }
-      }
-    }
-  }
-  /**
-   * @param inlineEntries
-   * @param feed
-   * @param entry
-   */
-  private void getExpandedData(Map<String, Object> inlineEntries, ODataFeed feed) {
-    assertNotNull(feed.getEntries());
-    List<ODataEntry> entries = feed.getEntries();
-    for (ODataEntry entry : entries) {
-      Map<String, ExpandSelectTreeNode> expandNodes = entry.getExpandSelectTree().getLinks();
-      for (Entry<String, ExpandSelectTreeNode> expand : expandNodes.entrySet()) {
-        assertNotNull(expand.getKey());
-        if (inlineEntries.containsKey(expand.getKey() + entry.getMetadata().getId())) {
-          if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataFeed) {
-            ODataFeed innerFeed = (ODataFeed) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
-            assertNotNull(innerFeed);
-            getExpandedData(inlineEntries, innerFeed);
-            feed.getEntries().get(feed.getEntries().indexOf(entry)).getProperties().put(expand.getKey(), innerFeed);
-          } else if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataEntry) {
-            ODataEntry innerEntry = (ODataEntry) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
-            assertNotNull(innerEntry);
-            getExpandedData(inlineEntries, innerEntry);
-            feed.getEntries().get(feed.getEntries().indexOf(entry)).getProperties().put(expand.getKey(), innerEntry);
-          }
-        }
-      }
-    }
-  }
 }
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryDeepInsertFeedTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryDeepInsertFeedTest.java
index 8e14d1c..57b940b 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryDeepInsertFeedTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryDeepInsertFeedTest.java
@@ -23,10 +23,12 @@
 import static org.junit.Assert.assertNull;
 
 import java.io.InputStream;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
 import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
 import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
 import org.apache.olingo.odata2.api.ep.callback.OnReadInlineContent;
@@ -221,11 +223,20 @@
   private class FeedCallback implements OnReadInlineContent {
     private ODataFeed feed;
     private FeedCallback innerCallback;
-
+    private Map<String, Object> navigationProp = new HashMap<String, Object>();
+    private String id = "";
+    
     public FeedCallback() {
 
     }
 
+    /**
+     * @return the navigationPropFeed
+     */
+    public Map<String, Object> getNavigationProperties() {
+      return navigationProp;
+    }
+    
     public ODataFeed getFeed() {
       return feed;
     }
@@ -237,14 +248,72 @@
 
     @Override
     public void handleReadFeed(final ReadFeedResult context) {
+      this.id = context.getParentEntryId();
       feed = context.getResult();
+      handleFeed(context);
     }
 
+    private void handleFeed(final ReadFeedResult context) {
+      try {
+        String navigationPropertyName = context.getNavigationProperty().getName();
+        if (navigationPropertyName != null) {
+          navigationProp.put(navigationPropertyName + id, (ODataFeed) context.getResult());
+        } else {
+          throw new RuntimeException("Invalid title");
+        }
+      } catch (EdmException e) {
+        throw new RuntimeException("Invalid title");
+      }
+    }
+    
     @Override
     public EntityProviderReadProperties receiveReadProperties(final EntityProviderReadProperties readProperties,
         final EdmNavigationProperty navString) {
       return EntityProviderReadProperties.init().mergeSemantic(false).callback(innerCallback).build();
     }
   }
+  
+  @Test
+  public void innerFeedWithCallback() throws Exception {
+    FeedCallback callback = new FeedCallback();
+    EntityProviderReadProperties readProperties =
+        EntityProviderReadProperties.init().mergeSemantic(false).callback(callback).build();
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Buildings");
+    String content = readFile("JsonBuildingWithInlineRoomsFeedToEmployees.json");
+    assertNotNull(content);
+    InputStream contentBody = createContentAsStream(content);
 
+    // execute
+    JsonEntityConsumer xec = new JsonEntityConsumer();
+    ODataEntry result = xec.readEntry(entitySet, contentBody, readProperties);
+    assertNotNull(result);
+    
+    ODataFeed innerRoomFeed = (ODataFeed) result.getProperties().get("nb_Rooms");
+    assertNull(innerRoomFeed);
+
+    innerRoomFeed = callback.getFeed();
+
+    List<ODataEntry> rooms = innerRoomFeed.getEntries();
+    assertNotNull(rooms);
+    assertEquals(1, rooms.size());
+
+    ODataEntry room = rooms.get(0);
+    Map<String, Object> roomProperties = room.getProperties();
+
+    assertEquals(5, 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"));
+
+    Map<String, Object> inlineEntries = callback.getNavigationProperties();
+    getExpandedData(inlineEntries, result, entitySet.getEntityType());
+    List<ODataEntry> roomsFeed = ((ODataFeed)result.getProperties().get("nb_Rooms")).getEntries();
+    List<ODataEntry> employeesFeed = ((ODataFeed)roomsFeed.get(0).getProperties().
+        get("nr_Employees")).getEntries();
+    assertEquals(1, employeesFeed.size());
+    assertEquals(10, employeesFeed.get(0).getProperties().size());
+    assertEquals(3, ((ODataEntry)employeesFeed.get(0).getProperties().get("ne_Team")).
+        getProperties().size());
+  }
 }
diff --git a/odata2-lib/odata-core/src/test/resources/JsonBuildingWithInlineRoomsFeedToEmployees.json b/odata2-lib/odata-core/src/test/resources/JsonBuildingWithInlineRoomsFeedToEmployees.json
new file mode 100644
index 0000000..568374f
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonBuildingWithInlineRoomsFeedToEmployees.json
@@ -0,0 +1,66 @@
+{
+	"d" : {
+		"Id" : "1",
+		"Name" : "Building 1",
+		"Image" : null,
+		"nb_Rooms" : [{
+					"Id" : "1",
+					"Name" : "Room 1",
+					"Seats" : 1,
+					"Version" : 1,
+					"nr_Employees" : {
+						"results": [
+					        {
+					          "EmployeeId": "1",
+					          "EmployeeName": "Walter Winter",
+					          "ManagerId": "1",
+					          "RoomId": "1",
+					          "TeamId": "1",
+					          "Location": {
+					            "__metadata": {
+					              "type": "RefScenario.c_Location"
+					            },
+					            "City": {
+					              "__metadata": {
+					                "type": "RefScenario.c_City"
+					              },
+					              "PostalCode": "69124",
+					              "CityName": "Heidelberg"
+					            },
+					            "Country": "Germany"
+					          },
+					          "Age": 52,
+					          "EntryDate": "/Date(915148800000)/",
+					          "ImageUrl": "Employees('1')/$value",
+					          "ne_Manager": {
+					            "__deferred": {
+					              "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Manager"
+					            }
+					          },
+					          "ne_Team": {
+					            "Id": "1",
+					            "Name": "Team 1",
+					            "isScrumTeam": false,
+					            "nt_Employees": {
+					              "__deferred": {
+					                "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')/nt_Employees"
+					              }
+					            }
+					          },
+					          "ne_Room": {
+					            "__deferred": {
+					              "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Room"
+					            }
+					          }
+					        }
+					      ]
+					},
+					"nr_Building" : {
+						"__deferred" : {
+							"uri" : "http://localhost:8080/ReferenceScenario.svc/Rooms('1')/nr_Building"
+						}
+					}
+				}
+			]
+	}
+}
diff --git a/odata2-lib/odata-core/src/test/resources/JsonEmployeeInlineRoomBuildingWithoutMetadata.json b/odata2-lib/odata-core/src/test/resources/JsonEmployeeInlineRoomBuildingWithoutMetadata.json
new file mode 100644
index 0000000..f2c4a12
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonEmployeeInlineRoomBuildingWithoutMetadata.json
@@ -0,0 +1,46 @@
+{
+  "d": {
+    "EmployeeId": "1",
+    "EmployeeName": "Walter Winter",
+    "ManagerId": "1",
+    "RoomId": "1",
+    "TeamId": "1",
+    "Location": {
+      "__metadata": {
+        "type": "RefScenario.c_Location"
+      },
+      "City": {
+        "__metadata": {
+          "type": "RefScenario.c_City"
+        },
+        "PostalCode": "69124",
+        "CityName": "Heidelberg"
+      },
+      "Country": "Germany"
+    },
+    "Age": 52,
+    "EntryDate": "/Date(915148800000)/",
+    "ImageUrl": "Employees('1')/$value",
+    "ne_Room": {
+      "Id": "1",
+      "Name": "Room 1",
+      "Seats": 1,
+      "Version": 1,
+      "nr_Employees": {
+        "__deferred": {
+          "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')/nr_Employees"
+        }
+      },
+      "nr_Building": {
+        "Id": "1",
+        "Name": "Building 1",
+        "Image": null,
+        "nb_Rooms": {
+          "__deferred": {
+            "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('1')/nb_Rooms"
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/odata2-lib/odata-core/src/test/resources/JsonRoom_InlineEmployeesToTeamWithoutMetadata.json b/odata2-lib/odata-core/src/test/resources/JsonRoom_InlineEmployeesToTeamWithoutMetadata.json
new file mode 100644
index 0000000..32937ec
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonRoom_InlineEmployeesToTeamWithoutMetadata.json
@@ -0,0 +1,60 @@
+{
+  "d": {
+    "Id": "1",
+    "Name": "Room 1",
+    "Seats": 1,
+    "Version": 1,
+    "nr_Employees": {
+      "results": [
+        {
+          "EmployeeId": "1",
+          "EmployeeName": "Walter Winter",
+          "ManagerId": "1",
+          "RoomId": "1",
+          "TeamId": "1",
+          "Location": {
+            "__metadata": {
+              "type": "RefScenario.c_Location"
+            },
+            "City": {
+              "__metadata": {
+                "type": "RefScenario.c_City"
+              },
+              "PostalCode": "69124",
+              "CityName": "Heidelberg"
+            },
+            "Country": "Germany"
+          },
+          "Age": 52,
+          "EntryDate": "/Date(915148800000)/",
+          "ImageUrl": "Employees('1')/$value",
+          "ne_Manager": {
+            "__deferred": {
+              "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Manager"
+            }
+          },
+          "ne_Team": {
+            "Id": "1",
+            "Name": "Team 1",
+            "isScrumTeam": false,
+            "nt_Employees": {
+              "__deferred": {
+                "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')/nt_Employees"
+              }
+            }
+          },
+          "ne_Room": {
+            "__deferred": {
+              "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Room"
+            }
+          }
+        }
+      ]
+    },
+    "nr_Building": {
+      "__deferred": {
+        "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')/nr_Building"
+      }
+    }
+  }
+}
\ No newline at end of file