You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2017/01/26 10:10:46 UTC

[2/2] olingo-odata2 git commit: [OLINGO-1054] Inline Consumer Callback Data handling

[OLINGO-1054] Inline Consumer Callback Data handling

Signed-off-by: Christian Amend <ch...@sap.com>


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

Branch: refs/heads/master
Commit: f24fc8bf42aa225afee2913e47423f11dc9fc237
Parents: adda9d5
Author: i050510 <ra...@sap.com>
Authored: Thu Dec 1 13:31:59 2016 +0530
Committer: Christian Amend <ch...@sap.com>
Committed: Thu Jan 26 11:06:21 2017 +0100

----------------------------------------------------------------------
 .../odata2/api/ep/callback/ReadEntryResult.java |  11 +-
 .../odata2/api/ep/callback/ReadFeedResult.java  |  10 +-
 .../core/ep/consumer/JsonEntryConsumer.java     |   9 +-
 .../core/ep/consumer/XmlEntryConsumer.java      |   6 +-
 .../odata2/core/ep/consumer/FeedCallback.java   |  82 +++++++
 .../core/ep/consumer/JsonEntryConsumerTest.java | 142 +++++++++++
 .../core/ep/consumer/JsonFeedConsumerTest.java  | 149 ++++++++++++
 .../core/ep/consumer/XmlEntityConsumerTest.java | 141 +++++++++++
 .../core/ep/consumer/XmlFeedConsumerTest.java   | 151 ++++++++++++
 .../resources/Employee_InlineRoomBuilding.xml   |  71 ++++++
 .../JsonEmployeeInlineRoomBuilding.json         |  75 ++++++
 .../JsonRoom_EmptyInlineEmployeesToTeam.json    |  22 ++
 .../JsonRoom_InlineEmployeesToTeam.json         |  79 ++++++
 .../JsonRoomsToEmployeesWithInlineTeams.json    | 118 +++++++++
 .../JsonRooms_InlineEmployeesTeams.json         | 236 ++++++++++++++++++
 ...sonRooms_InlineEmployees_InlineBuilding.json | 236 ++++++++++++++++++
 .../Room_EmptyInlineEmployeesToTeam.xml         |  30 +++
 .../resources/Room_InlineEmployeesToTeam.xml    |  77 ++++++
 .../RoomsToEmployeesWithInlineTeams.xml         | 104 ++++++++
 .../resources/Rooms_InlineEmployeesTeams.xml    | 238 +++++++++++++++++++
 .../Rooms_InlineEmployees_InlineBuildings.xml   | 197 +++++++++++++++
 21 files changed, 2176 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadEntryResult.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadEntryResult.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadEntryResult.java
index e6b8d8c..26968d2 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadEntryResult.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadEntryResult.java
@@ -35,7 +35,7 @@ import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
 public class ReadEntryResult extends ReadResult {
 
   private final ODataEntry entry;
-
+  private final String parentEntryId;
   /**
    * Constructor.
    * Parameters <b>MUST NOT BE NULL</b>.
@@ -45,9 +45,10 @@ public class ReadEntryResult extends ReadResult {
    * @param entry read entity as {@link ODataEntry}
    */
   public ReadEntryResult(final EntityProviderReadProperties properties, final EdmNavigationProperty navigationProperty,
-      final ODataEntry entry) {
+      final ODataEntry entry, final String entryMetadataId) {
     super(properties, navigationProperty);
     this.entry = entry;
+    this.parentEntryId = entryMetadataId;
   }
 
   @Override
@@ -64,4 +65,10 @@ public class ReadEntryResult extends ReadResult {
   public String toString() {
     return super.toString() + "\n\t" + entry.toString();
   }
+  /**
+   * @return the rootEntryId
+   */
+  public String getParentEntryId() {
+    return parentEntryId;
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadFeedResult.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadFeedResult.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadFeedResult.java
index 3e58609..011becf 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadFeedResult.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadFeedResult.java
@@ -35,6 +35,7 @@ import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
 public class ReadFeedResult extends ReadResult {
 
   private final ODataFeed feed;
+  private final String parentEntryId;
 
   /**
    * Constructor.
@@ -45,9 +46,10 @@ public class ReadFeedResult extends ReadResult {
    * @param entry read entities as list of {@link org.apache.olingo.odata2.api.ep.entry.ODataEntry ODataEntry}
    */
   public ReadFeedResult(final EntityProviderReadProperties properties, final EdmNavigationProperty navigationProperty,
-      final ODataFeed entry) {
+      final ODataFeed entry, final String entryMetadataId) {
     super(properties, navigationProperty);
     feed = entry;
+    parentEntryId = entryMetadataId;
   }
 
   @Override
@@ -64,4 +66,10 @@ public class ReadFeedResult extends ReadResult {
   public String toString() {
     return super.toString() + "\n\t" + feed.toString();
   }
+  /**
+   * @return the rootEntryId
+   */
+  public String getParentEntryId() {
+    return parentEntryId;
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumer.java
----------------------------------------------------------------------
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 45726ba..fb4977b 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
@@ -320,7 +320,8 @@ public class JsonEntryConsumer {
               properties.put(navigationPropertyName, feed);
               resultEntry.setContainsInlineEntry(true);
             } else {
-              ReadFeedResult result = new ReadFeedResult(inlineReadProperties, navigationProperty, feed);
+              ReadFeedResult result = new ReadFeedResult(inlineReadProperties, navigationProperty, 
+                  feed, entryMetadata.getId());
               callback.handleReadFeed(result);
             }
           } else {
@@ -331,7 +332,8 @@ public class JsonEntryConsumer {
               properties.put(navigationPropertyName, entry);
               resultEntry.setContainsInlineEntry(true);
             } else {
-              ReadEntryResult result = new ReadEntryResult(inlineReadProperties, navigationProperty, entry);
+              ReadEntryResult result = new ReadEntryResult(inlineReadProperties, navigationProperty, 
+                  entry, entryMetadata.getId());
               callback.handleReadEntry(result);
             }
           }
@@ -371,7 +373,8 @@ public class JsonEntryConsumer {
         properties.put(navigationPropertyName, feed);
         resultEntry.setContainsInlineEntry(true);
       } else {
-        ReadFeedResult result = new ReadFeedResult(inlineReadProperties, navigationProperty, feed);
+        ReadFeedResult result = new ReadFeedResult(inlineReadProperties, navigationProperty,
+            feed, entryMetadata.getId());
         try {
           callback.handleReadFeed(result);
         } catch (final ODataApplicationException e) {

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java
index a9d8ae1..962fc34 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java
@@ -405,10 +405,12 @@ public class XmlEntryConsumer {
 
     try {
       if (isFeed) {
-        ReadFeedResult callbackInfo = new ReadFeedResult(readProperties, navigationProperty, (ODataFeed) content);
+        ReadFeedResult callbackInfo = new ReadFeedResult(readProperties, navigationProperty, 
+            (ODataFeed) content, entryMetadata.getId());
         callback.handleReadFeed(callbackInfo);
       } else {
-        ReadEntryResult callbackInfo = new ReadEntryResult(readProperties, navigationProperty, (ODataEntry) content);
+        ReadEntryResult callbackInfo = new ReadEntryResult(readProperties, navigationProperty, 
+            (ODataEntry) content, entryMetadata.getId());
         callback.handleReadEntry(callbackInfo);
       }
     } catch (ODataApplicationException e) {

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/FeedCallback.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/FeedCallback.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/FeedCallback.java
new file mode 100644
index 0000000..a8a9478
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/FeedCallback.java
@@ -0,0 +1,82 @@
+package org.apache.olingo.odata2.core.ep.consumer;
+
+import java.util.HashMap;
+import java.util.Map;
+
+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;
+import org.apache.olingo.odata2.api.ep.callback.ReadEntryResult;
+import org.apache.olingo.odata2.api.ep.callback.ReadFeedResult;
+import org.apache.olingo.odata2.api.ep.callback.ReadResult;
+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.ODataApplicationException;
+
+public class FeedCallback implements OnReadInlineContent{
+
+  private static Map<String, Object> navigationProp = new HashMap<String, Object>();
+  private String id = "";
+  
+  /**
+   * @return the id
+   */
+  public String getId() {
+    return id;
+  }
+
+  /**
+   * @return the navigationPropFeed
+   */
+  public Map<String, Object> getNavigationProperties() {
+    return navigationProp;
+  }
+
+  @Override
+  public EntityProviderReadProperties receiveReadProperties(EntityProviderReadProperties readProperties,
+      EdmNavigationProperty navigationProperty) throws ODataApplicationException {
+    Map<String, Object> typeMappings = new HashMap<String, Object>();
+    return EntityProviderReadProperties.init().addTypeMappings(typeMappings).callback(new FeedCallback()).build();
+  }
+
+  @Override
+  public void handleReadEntry(ReadEntryResult context) throws ODataApplicationException {
+    this.id = context.getParentEntryId();
+    handleEntry(context);
+    
+  }
+
+  @Override
+  public void handleReadFeed(ReadFeedResult context) throws ODataApplicationException {
+    this.id = context.getParentEntryId();
+    handleFeed(context);
+    
+  }
+  
+  private void handleEntry(final ReadResult context) {
+    try {
+      String navigationPropertyName = context.getNavigationProperty().getName();
+      if (navigationPropertyName != null) {
+        navigationProp.put(navigationPropertyName + id, (ODataEntry) context.getResult());
+      } else {
+        throw new RuntimeException("Invalid title");
+      }
+    } catch (EdmException e) {
+      throw new RuntimeException("Invalid title");
+    }
+  }
+
+  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");
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumerTest.java
----------------------------------------------------------------------
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 4836fd3..4f0d385 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,6 +29,7 @@ import java.util.Calendar;
 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;
@@ -36,6 +37,8 @@ import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
 import org.apache.olingo.odata2.api.ep.entry.EntryMetadata;
 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;
 
@@ -345,4 +348,143 @@ public class JsonEntryConsumerTest extends AbstractConsumerTest {
     InputStream contentBody = createContentAsStream(negativeJsonStart_2);
     new JsonEntityConsumer().readEntry(entitySet, contentBody, DEFAULT_PROPERTIES);
   }
+  /**
+   * Employee with inline entity Room with inline entity Buildings 
+   * Scenario of 1:1:1 navigation
+   * E.g: Employees('1')?$expand=ne_Room/nr_Building
+   * @throws Exception
+   */
+  @Test
+  public void employeesEntryWithEmployeeToRoomToBuilding() throws Exception {
+    InputStream stream = getFileAsStream("JsonEmployeeInlineRoomBuilding.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);
+    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());
+  }
+  
+  /**
+   * 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 RoomEntryWithInlineEmployeeInlineTeam() throws Exception {
+    InputStream stream = getFileAsStream("JsonRoom_InlineEmployeesToTeam.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);
+    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
+   * @throws Exception
+   */
+  @Test
+  public void RoomEntryWithEmptyInlineEmployeeInlineTeam() throws Exception {
+    InputStream stream = getFileAsStream("JsonRoom_EmptyInlineEmployeesToTeam.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);
+    assertEquals(5, result.getProperties().size());
+    assertEquals(0, ((ODataFeed)result.getProperties().get("nr_Employees")).getEntries().size());
+  }
+  /**
+   * @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);
+          }
+        }
+      }
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonFeedConsumerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonFeedConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonFeedConsumerTest.java
index 6495b73..0bad548 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonFeedConsumerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonFeedConsumerTest.java
@@ -26,17 +26,20 @@ import java.io.InputStream;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import junit.framework.Assert;
 
 import org.apache.olingo.odata2.api.edm.EdmEntitySet;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
 import org.apache.olingo.odata2.api.ep.entry.DeletedEntryMetadata;
 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.FeedMetadata;
 import org.apache.olingo.odata2.api.ep.feed.ODataDeltaFeed;
 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;
 
@@ -531,4 +534,150 @@ public class JsonFeedConsumerTest extends AbstractConsumerTest {
     assertNull(mediaMetadata.getEtag());
     assertNull(mediaMetadata.getSourceLink());
   }
+  /**
+   * Room has an Inline Feed Employees and Employee has an inline Entry Team
+   * E.g: Rooms?$expand=nr_Employees/ne_Team
+   * Empty Inline entity is also part of payload
+   * @throws Exception
+   */
+  @Test
+  public void roomsFeedWithRoomInlineEmployeesWithTeams() throws Exception {
+    InputStream stream = getFileAsStream("JsonRooms_InlineEmployeesTeams.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();
+    ODataDeltaFeed feed = xec.readDeltaFeed(entitySet, stream, readProperties);
+    assertNotNull(feed);
+    
+    assertEquals(3, feed.getEntries().size());
+
+    Map<String, Object> inlineEntries = callback.getNavigationProperties();
+    getExpandedData(inlineEntries, feed);
+    for (ODataEntry entry : feed.getEntries()) {
+      assertEquals(5, entry.getProperties().size());
+      for (ODataEntry innerEntry : ((ODataFeed)entry.getProperties().get("nr_Employees")).getEntries()) {
+        assertEquals(10, innerEntry.getProperties().size());
+        assertEquals(3, ((ODataEntry)innerEntry.getProperties().get("ne_Team")).getProperties().size());
+      }
+    }
+  }
+  
+  /**
+   * Rooms has an inline feed Employees and Rooms has Inline entry Buildings
+   * E.g: Rooms?$expand=nr_Employees,nr_Building
+   * Empty Inline entity is also part of payload
+   * @throws Exception
+   */
+  @Test
+  public void roomsFeedWithRoomInlineEmployeesInlineBuildings() throws Exception {
+    InputStream stream = getFileAsStream("JsonRooms_InlineEmployees_InlineBuilding.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();
+    ODataDeltaFeed feed = xec.readDeltaFeed(entitySet, stream, readProperties);
+    assertNotNull(feed);
+    assertEquals(3, feed.getEntries().size());
+
+    Map<String, Object> inlineEntries = callback.getNavigationProperties();
+    getExpandedData(inlineEntries, feed);
+    for (ODataEntry entry : feed.getEntries()) {
+      assertEquals(6, entry.getProperties().size());
+      for (ODataEntry employeeEntry : ((ODataFeed)entry.getProperties().get("nr_Employees")).getEntries()) {
+        assertEquals(9, employeeEntry.getProperties().size());
+      }
+      assertEquals(3, ((ODataEntry)entry.getProperties().get("nr_Building")).getProperties().size());
+    }
+  }
+  
+  /**
+   * Rooms navigate to Employees and has inline entry Teams
+   * E.g: Rooms('1')/nr_Employees?$expand=ne_Team
+   * @throws Exception
+   */
+  @Test
+  public void roomsFeedWithRoomsToEmployeesInlineTeams() throws Exception {
+    InputStream stream = getFileAsStream("JsonRoomsToEmployeesWithInlineTeams.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();
+    ODataDeltaFeed feed = xec.readDeltaFeed(entitySet, stream, readProperties);
+    assertNotNull(feed);
+    assertEquals(2, feed.getEntries().size());
+
+    Map<String, Object> inlineEntries = callback.getNavigationProperties();
+    getExpandedData(inlineEntries, feed);
+    for (ODataEntry entry : feed.getEntries()) {
+      assertEquals(10, entry.getProperties().size());
+      assertEquals(3, ((ODataEntry)entry.getProperties().get("ne_Team")).getProperties().size());
+    }
+  }
+  /**
+   * @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);
+          }
+        }
+      }
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java
index 2194619..b8ba340 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java
@@ -31,6 +31,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.TimeZone;
+import java.util.Map.Entry;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -2511,4 +2512,144 @@ public class XmlEntityConsumerTest extends AbstractXmlConsumerTest {
     Map<String, Object> properties = result.getProperties();
     assertEquals(9, properties.size());
   }
+  /**
+   * Employee with inline entity Room with inline entity Buildings 
+   * Scenario of 1:1:1 navigation
+   * E.g: Employees('1')?$expand=ne_Rooms/nr_Buildings
+   * @throws Exception
+   */
+  @Test
+  public void employeesEntryWithEmployeeToRoomToBuilding() throws Exception {
+    InputStream stream = getFileAsStream("Employee_InlineRoomBuilding.xml");
+    assertNotNull(stream);
+    FeedCallback callback = new FeedCallback();
+
+    EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+        .mergeSemantic(false).callback(callback).build();
+
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+    XmlEntityConsumer xec = new XmlEntityConsumer();
+    ODataEntry result =
+        xec.readEntry(entitySet, stream, readProperties);
+    assertNotNull(result);
+    assertEquals(9, result.getProperties().size());
+
+    Map<String, Object> inlineEntries = callback.getNavigationProperties();
+    getExpandedData(inlineEntries, result);
+    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());
+  }
+  
+  /**
+   * 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 RoomEntryWithInlineEmployeeInlineTeam() throws Exception {
+    InputStream stream = getFileAsStream("Room_InlineEmployeesToTeam.xml");
+    assertNotNull(stream);
+    FeedCallback callback = new FeedCallback();
+
+    EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+        .mergeSemantic(false).callback(callback).build();
+
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+    XmlEntityConsumer xec = new XmlEntityConsumer();
+    ODataEntry result =
+        xec.readEntry(entitySet, stream, readProperties);
+    assertNotNull(result);
+    assertEquals(4, result.getProperties().size());
+
+    Map<String, Object> inlineEntries = callback.getNavigationProperties();
+    getExpandedData(inlineEntries, result);
+    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
+   * @throws Exception
+   */
+  @Test
+  public void RoomEntryWithEmptyInlineEmployeeInlineTeam() throws Exception {
+    InputStream stream = getFileAsStream("Room_EmptyInlineEmployeesToTeam.xml");
+    assertNotNull(stream);
+    FeedCallback callback = new FeedCallback();
+
+    EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+        .mergeSemantic(false).callback(callback).build();
+
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+    XmlEntityConsumer xec = new XmlEntityConsumer();
+    ODataEntry result =
+        xec.readEntry(entitySet, stream, readProperties);
+    assertNotNull(result);
+    assertEquals(4, result.getProperties().size());
+
+    Map<String, Object> inlineEntries = callback.getNavigationProperties();
+    getExpandedData(inlineEntries, result);
+    assertEquals(5, result.getProperties().size());
+    assertEquals(0, ((ODataFeed)result.getProperties().get("nr_Employees")).getEntries().size());
+  }
+  /**
+   * @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);
+          }
+        }
+      }
+    }
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumerTest.java
index ec7ce71..8d22dd7 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumerTest.java
@@ -23,6 +23,8 @@ import static org.junit.Assert.assertNotNull;
 
 import java.io.InputStream;
 import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
 
 import junit.framework.Assert;
 
@@ -35,6 +37,7 @@ 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.ODataDeltaFeed;
 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;
 
@@ -180,4 +183,152 @@ public class XmlFeedConsumerTest extends AbstractXmlConsumerTest {
     assertEquals(1, deltaFeed.getEntries().size());
     assertEquals(1, deltaFeed.getDeletedEntries().size());
   }
+  /**
+   * Room has an Inline Feed Employees and Employee has an inline Entry Team
+   * E.g: Rooms?$expand=nr_Employees/ne_Team
+   * Empty Inline entity is also part of payload
+   * @throws Exception
+   */
+  @Test
+  public void roomsFeedWithRoomInlineEmployeesWithTeams() throws Exception {
+    InputStream stream = getFileAsStream("Rooms_InlineEmployeesTeams.xml");
+    assertNotNull(stream);
+    FeedCallback callback = new FeedCallback();
+
+    EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+        .mergeSemantic(false).callback(callback).build();
+
+    ODataFeed feed =
+        EntityProvider.readFeed("application/atom+xml", MockFacade.getMockEdm().getDefaultEntityContainer()
+            .getEntitySet(
+                "Rooms"), stream, readProperties);
+    assertNotNull(feed);
+    assertEquals(3, feed.getEntries().size());
+
+    Map<String, Object> inlineEntries = callback.getNavigationProperties();
+    getExpandedData(inlineEntries, feed);
+    for (ODataEntry entry : feed.getEntries()) {
+      assertEquals(5, entry.getProperties().size());
+      for (ODataEntry innerEntry : ((ODataFeed)entry.getProperties().get("nr_Employees")).getEntries()) {
+        assertEquals(10, innerEntry.getProperties().size());
+        assertEquals(3, ((ODataEntry)innerEntry.getProperties().get("ne_Team")).getProperties().size());
+      }
+    }
+  }
+  
+  /**
+   * Rooms has an inline feed Employees and Rooms has Inline entry Buildings
+   * E.g: Rooms?$expand=nr_Employees,nr_Building
+   * @throws Exception
+   */
+  @Test
+  public void roomsFeedWithRoomInlineEmployeesInlineBuildings() throws Exception {
+    InputStream stream = getFileAsStream("Rooms_InlineEmployees_InlineBuildings.xml");
+    assertNotNull(stream);
+    FeedCallback callback = new FeedCallback();
+
+    EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+        .mergeSemantic(false).callback(callback).build();
+
+    ODataFeed feed =
+        EntityProvider.readFeed("application/atom+xml", MockFacade.getMockEdm().getDefaultEntityContainer()
+            .getEntitySet(
+                "Rooms"), stream, readProperties);
+    assertNotNull(feed);
+    assertEquals(2, feed.getEntries().size());
+
+    Map<String, Object> inlineEntries = callback.getNavigationProperties();
+    getExpandedData(inlineEntries, feed);
+    for (ODataEntry entry : feed.getEntries()) {
+      assertEquals(6, entry.getProperties().size());
+      for (ODataEntry employeeEntry : ((ODataFeed)entry.getProperties().get("nr_Employees")).getEntries()) {
+        assertEquals(9, employeeEntry.getProperties().size());
+      }
+      assertEquals(3, ((ODataEntry)entry.getProperties().get("nr_Building")).getProperties().size());
+    }
+  }
+  
+  /**
+   * Rooms navigate to Employees and has inline entry Teams
+   * E.g: Rooms('1')/nr_Employees?$expand=ne_Team
+   * @throws Exception
+   */
+  @Test
+  public void roomsFeedWithRoomsToEmployeesInlineTeams() throws Exception {
+    InputStream stream = getFileAsStream("RoomsToEmployeesWithInlineTeams.xml");
+    assertNotNull(stream);
+    FeedCallback callback = new FeedCallback();
+
+    EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+        .mergeSemantic(false).callback(callback).build();
+
+    ODataFeed feed =
+        EntityProvider.readFeed("application/atom+xml", MockFacade.getMockEdm().getDefaultEntityContainer()
+            .getEntitySet(
+                "Employees"), stream, readProperties);
+    assertNotNull(feed);
+    assertEquals(2, feed.getEntries().size());
+
+    Map<String, Object> inlineEntries = callback.getNavigationProperties();
+    getExpandedData(inlineEntries, feed);
+    for (ODataEntry entry : feed.getEntries()) {
+      assertEquals(10, entry.getProperties().size());
+      assertEquals(3, ((ODataEntry)entry.getProperties().get("ne_Team")).getProperties().size());
+    }
+  }
+  
+  /**
+   * @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);
+          }
+        }
+      }
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/resources/Employee_InlineRoomBuilding.xml
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/Employee_InlineRoomBuilding.xml b/odata2-lib/odata-core/src/test/resources/Employee_InlineRoomBuilding.xml
new file mode 100644
index 0000000..37ca6e8
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/Employee_InlineRoomBuilding.xml
@@ -0,0 +1,71 @@
+<?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:8080/olingo-odata2-ref-web/ReferenceScenario.svc/">
+	<id>http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.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">
+		<m:inline>
+			<entry xml:base="http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/" m:etag="W/&quot;1&quot;">
+				<id>http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')</id>
+				<title type="text">Room 1</title>
+				<updated>2016-11-30T09:44:42.419+05:30</updated>
+				<category term="RefScenario.Room" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
+				<link href="Rooms('1')" rel="edit" title="Room"/>
+				<link href="Rooms('1')/nr_Employees" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Employees" title="nr_Employees" type="application/atom+xml;type=feed"/>
+				<link href="Rooms('1')/nr_Building" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Building" title="nr_Building" type="application/atom+xml;type=entry">
+					<m:inline>
+						<entry xml:base="http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/">
+							<id>http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('1')</id>
+							<title type="text">Buildings</title>
+							<updated>2016-11-30T09:44:42.426+05:30</updated>
+							<author>
+								<name>Building 1</name>
+							</author>
+							<category term="RefScenario.Building" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
+							<link href="Buildings('1')" rel="edit" title="Building"/>
+							<link href="Buildings('1')/nb_Rooms" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nb_Rooms" title="nb_Rooms" type="application/atom+xml;type=feed"/>
+							<content type="application/xml">
+								<m:properties>
+									<d:Id>1</d:Id>
+									<d:Name>Building 1</d:Name>
+									<d:Image m:null="true"/>
+								</m:properties>
+							</content>
+						</entry>
+					</m:inline>
+				</link>
+				<content type="application/xml">
+					<m:properties>
+						<d:Id>1</d:Id>
+						<d:Name>Room 1</d:Name>
+						<d:Seats>1</d:Seats>
+						<d:Version>1</d:Version>
+					</m:properties>
+				</content>
+			</entry>
+		</m:inline>
+	</link>
+	<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:PostalCode>69124</d:PostalCode>
+				<d:CityName>Heidelberg</d:CityName>
+			</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>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/resources/JsonEmployeeInlineRoomBuilding.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonEmployeeInlineRoomBuilding.json b/odata2-lib/odata-core/src/test/resources/JsonEmployeeInlineRoomBuilding.json
new file mode 100644
index 0000000..8f35315
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonEmployeeInlineRoomBuilding.json
@@ -0,0 +1,75 @@
+{
+  "d": {
+    "__metadata": {
+      "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+      "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+      "type": "RefScenario.Employee",
+      "content_type": "image/jpeg",
+      "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value",
+      "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value"
+    },
+    "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": {
+      "__deferred": {
+        "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Team"
+      }
+    },
+    "ne_Room": {
+      "__metadata": {
+        "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+        "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+        "type": "RefScenario.Room",
+        "etag": "W/\"1\""
+      },
+      "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": {
+        "__metadata": {
+          "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('1')",
+          "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('1')",
+          "type": "RefScenario.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

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/resources/JsonRoom_EmptyInlineEmployeesToTeam.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonRoom_EmptyInlineEmployeesToTeam.json b/odata2-lib/odata-core/src/test/resources/JsonRoom_EmptyInlineEmployeesToTeam.json
new file mode 100644
index 0000000..8495fab
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonRoom_EmptyInlineEmployeesToTeam.json
@@ -0,0 +1,22 @@
+{
+  "d": {
+    "__metadata": {
+      "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')",
+      "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')",
+      "type": "RefScenario.Room",
+      "etag": "W/\"1\""
+    },
+    "Id": "10",
+    "Name": "Room 10",
+    "Seats": 6,
+    "Version": 1,
+    "nr_Employees": {
+      "results": []
+    },
+    "nr_Building": {
+      "__deferred": {
+        "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')/nr_Building"
+      }
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/resources/JsonRoom_InlineEmployeesToTeam.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonRoom_InlineEmployeesToTeam.json b/odata2-lib/odata-core/src/test/resources/JsonRoom_InlineEmployeesToTeam.json
new file mode 100644
index 0000000..979e39a
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonRoom_InlineEmployeesToTeam.json
@@ -0,0 +1,79 @@
+{
+  "d": {
+    "__metadata": {
+      "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+      "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+      "type": "RefScenario.Room",
+      "etag": "W/\"1\""
+    },
+    "Id": "1",
+    "Name": "Room 1",
+    "Seats": 1,
+    "Version": 1,
+    "nr_Employees": {
+      "results": [
+        {
+          "__metadata": {
+            "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+            "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+            "type": "RefScenario.Employee",
+            "content_type": "image/jpeg",
+            "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value",
+            "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value"
+          },
+          "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": {
+            "__metadata": {
+              "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+              "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+              "type": "RefScenario.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

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/resources/JsonRoomsToEmployeesWithInlineTeams.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonRoomsToEmployeesWithInlineTeams.json b/odata2-lib/odata-core/src/test/resources/JsonRoomsToEmployeesWithInlineTeams.json
new file mode 100644
index 0000000..671dbb6
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonRoomsToEmployeesWithInlineTeams.json
@@ -0,0 +1,118 @@
+{
+  "d": {
+    "results": [
+      {
+        "__metadata": {
+          "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')",
+          "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')",
+          "type": "RefScenario.Employee",
+          "content_type": "image/jpeg",
+          "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/$value",
+          "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/$value"
+        },
+        "EmployeeId": "2",
+        "EmployeeName": "Frederic Fall",
+        "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": 32,
+        "EntryDate": "/Date(1057017600000)/",
+        "ImageUrl": "Employees('2')/$value",
+        "ne_Manager": {
+          "__deferred": {
+            "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/ne_Manager"
+          }
+        },
+        "ne_Team": {
+          "__metadata": {
+            "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+            "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+            "type": "RefScenario.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('2')/ne_Room"
+          }
+        }
+      },
+      {
+        "__metadata": {
+          "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('6')",
+          "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('6')",
+          "type": "RefScenario.Employee",
+          "content_type": "image/jpeg",
+          "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('6')/$value",
+          "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('6')/$value"
+        },
+        "EmployeeId": "6",
+        "EmployeeName": "Susan Bay",
+        "ManagerId": "1",
+        "RoomId": "2",
+        "TeamId": "3",
+        "Location": {
+          "__metadata": {
+            "type": "RefScenario.c_Location"
+          },
+          "City": {
+            "__metadata": {
+              "type": "RefScenario.c_City"
+            },
+            "PostalCode": "69190",
+            "CityName": "Walldorf"
+          },
+          "Country": "Germany"
+        },
+        "Age": 29,
+        "EntryDate": "/Date(1291161600000)/",
+        "ImageUrl": "Employees('6')/$value",
+        "ne_Manager": {
+          "__deferred": {
+            "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('6')/ne_Manager"
+          }
+        },
+        "ne_Team": {
+          "__metadata": {
+            "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('3')",
+            "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('3')",
+            "type": "RefScenario.Team"
+          },
+          "Id": "3",
+          "Name": "Team 3",
+          "isScrumTeam": false,
+          "nt_Employees": {
+            "__deferred": {
+              "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('3')/nt_Employees"
+            }
+          }
+        },
+        "ne_Room": {
+          "__deferred": {
+            "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('6')/ne_Room"
+          }
+        }
+      }
+    ]
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployeesTeams.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployeesTeams.json b/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployeesTeams.json
new file mode 100644
index 0000000..b466ad2
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployeesTeams.json
@@ -0,0 +1,236 @@
+{
+  "d": {
+    "results": [
+      {
+        "__metadata": {
+          "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+          "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+          "type": "RefScenario.Room",
+          "etag": "W/\"1\""
+        },
+        "Id": "1",
+        "Name": "Room 1",
+        "Seats": 1,
+        "Version": 1,
+        "nr_Employees": {
+          "results": [
+            {
+              "__metadata": {
+                "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+                "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+                "type": "RefScenario.Employee",
+                "content_type": "image/jpeg",
+                "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value",
+                "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value"
+              },
+              "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": {
+                "__metadata": {
+                  "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+                  "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+                  "type": "RefScenario.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"
+          }
+        }
+      },
+      {
+        "__metadata": {
+          "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')",
+          "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')",
+          "type": "RefScenario.Room",
+          "etag": "W/\"1\""
+        },
+        "Id": "10",
+        "Name": "Room 10",
+        "Seats": 6,
+        "Version": 1,
+        "nr_Employees": {
+          "results": []
+        },
+        "nr_Building": {
+          "__deferred": {
+            "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')/nr_Building"
+          }
+        }
+      },
+      {
+        "__metadata": {
+          "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('2')",
+          "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('2')",
+          "type": "RefScenario.Room",
+          "etag": "W/\"2\""
+        },
+        "Id": "2",
+        "Name": "Room 2",
+        "Seats": 5,
+        "Version": 2,
+        "nr_Employees": {
+          "results": [
+            {
+              "__metadata": {
+                "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')",
+                "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')",
+                "type": "RefScenario.Employee",
+                "content_type": "image/jpeg",
+                "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/$value",
+                "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/$value"
+              },
+              "EmployeeId": "2",
+              "EmployeeName": "Frederic Fall",
+              "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": 32,
+              "EntryDate": "/Date(1057017600000)/",
+              "ImageUrl": "Employees('2')/$value",
+              "ne_Manager": {
+                "__deferred": {
+                  "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/ne_Manager"
+                }
+              },
+              "ne_Team": {
+                "__metadata": {
+                  "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+                  "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+                  "type": "RefScenario.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('2')/ne_Room"
+                }
+              }
+            },
+            {
+              "__metadata": {
+                "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')",
+                "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')",
+                "type": "RefScenario.Employee",
+                "content_type": "image/jpeg",
+                "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')/$value",
+                "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/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:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')/ne_Manager"
+                }
+              },
+              "ne_Team": {
+                "__metadata": {
+                  "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+                  "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+                  "type": "RefScenario.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('3')/ne_Room"
+                }
+              }
+            }
+          ]
+        },
+        "nr_Building": {
+          "__deferred": {
+            "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('2')/nr_Building"
+          }
+        }
+      }
+    ]
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployees_InlineBuilding.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployees_InlineBuilding.json b/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployees_InlineBuilding.json
new file mode 100644
index 0000000..3d1747f
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployees_InlineBuilding.json
@@ -0,0 +1,236 @@
+{
+  "d": {
+    "results": [
+      {
+        "__metadata": {
+          "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+          "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+          "type": "RefScenario.Room",
+          "etag": "W/\"1\""
+        },
+        "Id": "1",
+        "Name": "Room 1",
+        "Seats": 1,
+        "Version": 1,
+        "nr_Employees": {
+          "results": [
+            {
+              "__metadata": {
+                "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+                "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+                "type": "RefScenario.Employee",
+                "content_type": "image/jpeg",
+                "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value",
+                "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value"
+              },
+              "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": {
+                "__deferred": {
+                  "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Team"
+                }
+              },
+              "ne_Room": {
+                "__deferred": {
+                  "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Room"
+                }
+              }
+            }
+          ]
+        },
+        "nr_Building": {
+          "__metadata": {
+            "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('1')",
+            "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('1')",
+            "type": "RefScenario.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"
+            }
+          }
+        }
+      },
+      {
+        "__metadata": {
+          "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')",
+          "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')",
+          "type": "RefScenario.Room",
+          "etag": "W/\"1\""
+        },
+        "Id": "10",
+        "Name": "Room 10",
+        "Seats": 6,
+        "Version": 1,
+        "nr_Employees": {
+          "results": []
+        },
+        "nr_Building": {
+          "__metadata": {
+            "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('3')",
+            "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('3')",
+            "type": "RefScenario.Building"
+          },
+          "Id": "3",
+          "Name": "Building 3",
+          "Image": null,
+          "nb_Rooms": {
+            "__deferred": {
+              "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('3')/nb_Rooms"
+            }
+          }
+        }
+      },
+	  {
+        "__metadata": {
+          "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('2')",
+          "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('2')",
+          "type": "RefScenario.Room",
+          "etag": "W/\"2\""
+        },
+        "Id": "2",
+        "Name": "Room 2",
+        "Seats": 5,
+        "Version": 2,
+        "nr_Employees": {
+          "results": [
+            {
+              "__metadata": {
+                "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')",
+                "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')",
+                "type": "RefScenario.Employee",
+                "content_type": "image/jpeg",
+                "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/$value",
+                "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/$value"
+              },
+              "EmployeeId": "2",
+              "EmployeeName": "Frederic Fall",
+              "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": 32,
+              "EntryDate": "/Date(1057017600000)/",
+              "ImageUrl": "Employees('2')/$value",
+              "ne_Manager": {
+                "__deferred": {
+                  "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/ne_Manager"
+                }
+              },
+              "ne_Team": {
+                "__deferred": {
+                  "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/ne_Team"
+                }
+              },
+              "ne_Room": {
+                "__deferred": {
+                  "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/ne_Room"
+                }
+              }
+            },
+            {
+              "__metadata": {
+                "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')",
+                "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')",
+                "type": "RefScenario.Employee",
+                "content_type": "image/jpeg",
+                "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')/$value",
+                "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/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:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')/ne_Manager"
+                }
+              },
+              "ne_Team": {
+                "__deferred": {
+                  "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')/ne_Team"
+                }
+              },
+              "ne_Room": {
+                "__deferred": {
+                  "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')/ne_Room"
+                }
+              }
+            }
+          ]
+        },
+        "nr_Building": {
+          "__metadata": {
+            "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('2')",
+            "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('2')",
+            "type": "RefScenario.Building"
+          },
+          "Id": "2",
+          "Name": "Building 2",
+          "Image": null,
+          "nb_Rooms": {
+            "__deferred": {
+              "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('2')/nb_Rooms"
+            }
+          }
+        }
+      }
+    ]
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/resources/Room_EmptyInlineEmployeesToTeam.xml
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/Room_EmptyInlineEmployeesToTeam.xml b/odata2-lib/odata-core/src/test/resources/Room_EmptyInlineEmployeesToTeam.xml
new file mode 100644
index 0000000..6ec35fe
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/Room_EmptyInlineEmployeesToTeam.xml
@@ -0,0 +1,30 @@
+<?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:8080/olingo-odata2-ref-web/ReferenceScenario.svc/" m:etag="W/&quot;1&quot;">
+    <id>http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')</id>
+    <title type="text">Room 10</title>
+    <updated>2016-11-30T14:30:58.658+05:30</updated>
+    <category term="RefScenario.Room" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
+    <link href="Rooms('10')" rel="edit" title="Room"/>
+    <link href="Rooms('10')/nr_Employees" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Employees" title="nr_Employees" type="application/atom+xml;type=feed">
+        <m:inline>
+            <feed xml:base="http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/">
+                <id>http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees</id>
+                <title type="text">Employees</title>
+                <updated>2016-11-30T14:30:58.658+05:30</updated>
+                <author>
+                    <name/>
+                </author>
+                <link href="Rooms('10')/nr_Employees" rel="self" title="Employees"/>
+            </feed>
+        </m:inline>
+    </link>
+    <link href="Rooms('10')/nr_Building" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Building" title="nr_Building" type="application/atom+xml;type=entry"/>
+    <content type="application/xml">
+        <m:properties>
+            <d:Id>10</d:Id>
+            <d:Name>Room 10</d:Name>
+            <d:Seats>6</d:Seats>
+            <d:Version>1</d:Version>
+        </m:properties>
+    </content>
+</entry>
\ No newline at end of file