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

olingo-odata4 git commit: [OLINGO-1207] Sample project supporting containment navigation

Repository: olingo-odata4
Updated Branches:
  refs/heads/master 73d1e2e07 -> b86aa5d97


[OLINGO-1207] Sample project supporting containment navigation


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

Branch: refs/heads/master
Commit: b86aa5d9777854db77d8d29663d79dd58d904c89
Parents: 73d1e2e
Author: ramya vasanth <ra...@sap.com>
Authored: Fri Dec 1 09:56:36 2017 +0530
Committer: ramya vasanth <ra...@sap.com>
Committed: Fri Dec 1 09:56:36 2017 +0530

----------------------------------------------------------------------
 .../olingo/server/tecsvc/data/DataCreator.java  | 296 ++++++++++++++++++-
 .../olingo/server/tecsvc/data/DataProvider.java | 106 +++++++
 .../processor/TechnicalEntityProcessor.java     | 100 +++++--
 .../tecsvc/processor/TechnicalProcessor.java    |  20 +-
 .../tecsvc/provider/ComplexTypeProvider.java    |   4 +-
 .../tecsvc/provider/EntityTypeProvider.java     |  52 +++-
 .../tecsvc/provider/PropertyProvider.java       |  66 +++++
 .../server/tecsvc/provider/SchemaProvider.java  |   3 +
 .../json/ODataJsonSerializerTest.java           |  78 +++++
 .../myservice/mynamespace/data/Storage.java     | 182 +++++++++++-
 .../mynamespace/service/DemoEdmProvider.java    |  53 ++++
 .../service/DemoEntityCollectionProcessor.java  |  36 ++-
 .../service/DemoEntityProcessor.java            |  31 +-
 13 files changed, 983 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b86aa5d9/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
index 2bed5a2..10e951c 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
@@ -94,7 +94,11 @@ public class DataCreator {
     data.put("ESCompCollDerived", createESCompCollDerived(edm, odata));
     data.put("ESTwoPrimDerived", createESTwoPrimDerived(edm, odata));
     data.put("ESAllPrimDerived", createESAllPrimDerived(edm, odata));
-    data.put("ESDelta", createESDelta(edm, odata)); 
+    data.put("ESDelta", createESDelta(edm, odata));
+    data.put("ESKeyNavCont", createESKeyNavCont(edm, odata));
+    data.put("ETCont", createETCont(edm, odata));
+    data.put("ETBaseCont", createETBaseCont(edm, odata));
+    data.put("ETTwoCont", createETTwoCont(edm, odata));
     
     linkSINav(data);
     linkESTwoPrim(data);
@@ -104,6 +108,8 @@ public class DataCreator {
     linkESTwoKeyNav(data);
     linkESPeople(data);
     linkESDelta(data);
+    linkESKeyNavCont(data);
+    linkETBaseCont(data);
   }
   
 
@@ -1696,6 +1702,35 @@ public class DataCreator {
      setLinks(entityCollection.getEntities().get(0), "NavPropertyETTwoKeyNavMany", esTwoKeyNavTargets.get(0),
          esTwoKeyNavTargets.get(1));
   }
+   
+   private void linkESKeyNavCont(final Map<String, EntityCollection> data) {
+     final EntityCollection entityCollection = data.get("ESKeyNavCont");
+     final List<Entity> targetEntities = data.get("ETCont").getEntities();
+     final List<Entity> etBaseContEntities = data.get("ETBaseCont").getEntities();
+     
+     setLinks(entityCollection.getEntities().get(1), "NavPropertyETContMany", targetEntities.get(1),
+         targetEntities.get(2));
+     
+     setLinkForContNav(entityCollection.getEntities().get(3), "NavPropertyETContOne", targetEntities.get(0));
+     
+     setLinks(entityCollection.getEntities().get(2), "NavPropertyETBaseContMany", etBaseContEntities.get(1),
+         etBaseContEntities.get(2));
+   }
+   
+   protected static void setLinkForContNav(final Entity entity, 
+       final String navigationPropertyName, final Entity target) {
+     Link link = entity.getNavigationLink(navigationPropertyName);
+     if (link == null) {
+       link = new Link();
+       link.setRel(Constants.NS_NAVIGATION_LINK_REL + navigationPropertyName);
+       link.setType(Constants.ENTITY_NAVIGATION_LINK_TYPE);
+       link.setTitle(navigationPropertyName);
+       link.setHref(entity.getId().toASCIIString() + 
+           (navigationPropertyName != null && navigationPropertyName.length() > 0 ? "/" + navigationPropertyName: ""));
+       entity.getNavigationLinks().add(link);
+     }
+     link.setInlineEntity(target);
+   }
 
   protected static Property createPrimitive(final String name, final Object value) {
     return new Property(null, name, ValueType.PRIMITIVE, value);
@@ -1848,4 +1883,263 @@ public class DataCreator {
       }
     }
   }
+  
+  private EntityCollection createESKeyNavCont(final Edm edm, final OData odata) {
+    EntityCollection entityCollection = new EntityCollection();
+
+    entityCollection.getEntities().add(new Entity()
+        .addProperty(createPrimitive("PropertyInt16", (short) 32766))
+        .addProperty(createPrimitive("PropertyString", "Test String1"))
+        .addProperty(createComplex("PropertyCompNavCont",
+            ComplexTypeProvider.nameCTNavCont.getFullQualifiedNameAsString())));
+
+    entityCollection.getEntities().add(new Entity()
+        .addProperty(createPrimitive("PropertyInt16", (short) -365))
+        .addProperty(createPrimitive("PropertyString", "Test String2"))
+        .addProperty(createComplex("PropertyCompNavCont",
+            ComplexTypeProvider.nameCTNavCont.getFullQualifiedNameAsString())));
+
+    entityCollection.getEntities().add(new Entity()
+        .addProperty(createPrimitive("PropertyInt16", (short) -32766))
+        .addProperty(createPrimitive("PropertyString", "Test String3"))
+        .addProperty(createComplex("PropertyCompNavCont",
+            ComplexTypeProvider.nameCTNavCont.getFullQualifiedNameAsString())));
+
+    entityCollection.getEntities().add(new Entity()
+        .addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE))
+        .addProperty(createPrimitive("PropertyString", "Test String4"))
+        .addProperty(createComplex("PropertyCompNavCont",
+            ComplexTypeProvider.nameCTNavCont.getFullQualifiedNameAsString())));
+
+    setEntityType(entityCollection, edm.getEntityType(EntityTypeProvider.nameETKeyNavCont));
+    createEntityId(edm, odata, "ESKeyNavCont", entityCollection);
+    createOperations("ESKeyNavCont", entityCollection, EntityTypeProvider.nameETKeyNavCont);
+    return entityCollection;
+  }
+  
+  private EntityCollection createETCont(final Edm edm, final OData odata) {
+    EntityCollection entityCollection = new EntityCollection();
+
+    entityCollection.getEntities().add(new Entity()
+        .addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE))
+        .addProperty(createPrimitive("PropertyString", "First Resource - positive values"))
+        .addProperty(createPrimitive("PropertyBoolean", true))
+        .addProperty(createPrimitive("PropertyByte", (short) 255))
+        .addProperty(createPrimitive("PropertySByte", Byte.MAX_VALUE))
+        .addProperty(createPrimitive("PropertyInt32", Integer.MAX_VALUE))
+        .addProperty(createPrimitive("PropertyInt64", Long.MAX_VALUE))
+        .addProperty(createPrimitive("PropertySingle", (float) 1.79000000E+20))
+        .addProperty(createPrimitive("PropertyDouble", -1.7900000000000000E+19))
+        .addProperty(createPrimitive("PropertyDecimal", BigDecimal.valueOf(34)))
+        .addProperty(createPrimitive("PropertyBinary",
+            new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF }))
+        .addProperty(createPrimitive("PropertyDate", getDate(2012, 12, 3)))
+        .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2012, 12, 3, 7, 16, 23)))
+        .addProperty(createPrimitive("PropertyDuration", BigDecimal.valueOf(6)))
+        .addProperty(createPrimitive("PropertyGuid", GUID))
+        .addProperty(createPrimitive("PropertyTimeOfDay", getTime(3, 26, 5))));
+
+    entityCollection.getEntities().add(new Entity()
+        .addProperty(createPrimitive("PropertyInt16", Short.MIN_VALUE))
+        .addProperty(createPrimitive("PropertyString", "Second Resource - negative values"))
+        .addProperty(createPrimitive("PropertyBoolean", false))
+        .addProperty(createPrimitive("PropertyByte", (short) 0))
+        .addProperty(createPrimitive("PropertySByte", Byte.MIN_VALUE))
+        .addProperty(createPrimitive("PropertyInt32", Integer.MIN_VALUE))
+        .addProperty(createPrimitive("PropertyInt64", Long.MIN_VALUE))
+        .addProperty(createPrimitive("PropertySingle", (float) -1.79000000E+08))
+        .addProperty(createPrimitive("PropertyDouble", -1.7900000000000000E+05))
+        .addProperty(createPrimitive("PropertyDecimal", BigDecimal.valueOf(-34)))
+        .addProperty(createPrimitive("PropertyBinary",
+            new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF }))
+        .addProperty(createPrimitive("PropertyDate", getDate(2015, 11, 5)))
+        .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2005, 12, 3, 7, 17, 8)))
+        .addProperty(createPrimitive("PropertyDuration", BigDecimal.valueOf(9)))
+        .addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789dddfff")))
+        .addProperty(createPrimitive("PropertyTimeOfDay", getTime(23, 49, 14))));
+
+    entityCollection.getEntities().add(new Entity()
+        .addProperty(createPrimitive("PropertyInt16", (short) 0))
+        .addProperty(createPrimitive("PropertyString", ""))
+        .addProperty(createPrimitive("PropertyBoolean", false))
+        .addProperty(createPrimitive("PropertyByte", (short) 0))
+        .addProperty(createPrimitive("PropertySByte", 0))
+        .addProperty(createPrimitive("PropertyInt32", 0))
+        .addProperty(createPrimitive("PropertyInt64", 0L))
+        .addProperty(createPrimitive("PropertySingle", (float) 0))
+        .addProperty(createPrimitive("PropertyDouble", 0D))
+        .addProperty(createPrimitive("PropertyDecimal", BigDecimal.valueOf(0)))
+        .addProperty(createPrimitive("PropertyBinary", new byte[] {}))
+        .addProperty(createPrimitive("PropertyDate", getDate(1970, 1, 1)))
+        .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2005, 12, 3, 0, 0, 0)))
+        .addProperty(createPrimitive("PropertyDuration", BigDecimal.valueOf(0)))
+        .addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789cccddd")))
+        .addProperty(createPrimitive("PropertyTimeOfDay", getTime(0, 1, 1))));
+
+    setEntityType(entityCollection, edm.getEntityType(EntityTypeProvider.nameETCont));
+    createEntityId(edm, odata, "ESKeyNavCont", entityCollection);
+    String id = "ESKeyNavCont(-365)";
+    id = id + "/NavPropertyETContMany(" + 
+    entityCollection.getEntities().get(1).getProperty("PropertyInt16").getValue() + ")";
+    entityCollection.getEntities().get(1).setId(URI.create(id));
+    id = "ESKeyNavCont(-365)";
+    id = id + "/NavPropertyETContMany(" + 
+    entityCollection.getEntities().get(2).getProperty("PropertyInt16").getValue() + ")";
+    entityCollection.getEntities().get(2).setId(URI.create(id));
+    id = "ESKeyNavCont(32766)";
+    id = id + "/NavPropertyETContOne(" + 
+    entityCollection.getEntities().get(0).getProperty("PropertyInt16").getValue() + ")";
+    entityCollection.getEntities().get(0).setId(URI.create(id));
+    return entityCollection;
+  }
+  
+  private EntityCollection createETBaseCont(final Edm edm, final OData odata) {
+    EntityCollection entityCollection = new EntityCollection();
+
+    entityCollection.getEntities().add(new Entity()
+        .addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE))
+        .addProperty(createPrimitive("PropertyString", "First Resource - positive values"))
+        .addProperty(createPrimitive("PropertyInt32", Integer.MAX_VALUE))
+        .addProperty(createPrimitive("PropertyInt64", Long.MAX_VALUE))
+        .addProperty(createPrimitive("PropertySingle", (float) 1.79000000E+20))
+        .addProperty(createPrimitive("PropertyDouble", -1.7900000000000000E+19))
+        .addProperty(createPrimitive("PropertyDecimal", BigDecimal.valueOf(34)))
+        .addProperty(createPrimitive("PropertyBinary",
+            new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF }))
+        .addProperty(createPrimitive("PropertyDate", getDate(2012, 12, 3)))
+        .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2012, 12, 3, 7, 16, 23)))
+        .addProperty(createPrimitive("PropertyDuration", BigDecimal.valueOf(6)))
+        .addProperty(createPrimitive("PropertyGuid", GUID))
+        .addProperty(createPrimitive("PropertyTimeOfDay", getTime(3, 26, 5))));
+
+    entityCollection.getEntities().add(new Entity()
+        .addProperty(createPrimitive("PropertyInt16", Short.MIN_VALUE))
+        .addProperty(createPrimitive("PropertyString", "Second Resource - negative values"))
+        .addProperty(createPrimitive("PropertyInt32", Integer.MIN_VALUE))
+        .addProperty(createPrimitive("PropertyInt64", Long.MIN_VALUE))
+        .addProperty(createPrimitive("PropertySingle", (float) -1.79000000E+08))
+        .addProperty(createPrimitive("PropertyDouble", -1.7900000000000000E+05))
+        .addProperty(createPrimitive("PropertyDecimal", BigDecimal.valueOf(-34)))
+        .addProperty(createPrimitive("PropertyBinary",
+            new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF }))
+        .addProperty(createPrimitive("PropertyDate", getDate(2015, 11, 5)))
+        .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2005, 12, 3, 7, 17, 8)))
+        .addProperty(createPrimitive("PropertyDuration", BigDecimal.valueOf(9)))
+        .addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789dddfff")))
+        .addProperty(createPrimitive("PropertyTimeOfDay", getTime(23, 49, 14))));
+
+    entityCollection.getEntities().add(new Entity()
+        .addProperty(createPrimitive("PropertyInt16", (short) 0))
+        .addProperty(createPrimitive("PropertyString", ""))
+        .addProperty(createPrimitive("PropertyInt32", 0))
+        .addProperty(createPrimitive("PropertyInt64", 0L))
+        .addProperty(createPrimitive("PropertySingle", (float) 0))
+        .addProperty(createPrimitive("PropertyDouble", 0D))
+        .addProperty(createPrimitive("PropertyDecimal", BigDecimal.valueOf(0)))
+        .addProperty(createPrimitive("PropertyBinary", new byte[] {}))
+        .addProperty(createPrimitive("PropertyDate", getDate(1970, 1, 1)))
+        .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2005, 12, 3, 0, 0, 0)))
+        .addProperty(createPrimitive("PropertyDuration", BigDecimal.valueOf(0)))
+        .addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789cccddd")))
+        .addProperty(createPrimitive("PropertyTimeOfDay", getTime(0, 1, 1))));
+
+    setEntityType(entityCollection, edm.getEntityType(EntityTypeProvider.nameETBaseCont));
+    createEntityId(edm, odata, "ESKeyNavCont", entityCollection);
+    String id = "ESKeyNavCont(-32766)";
+    id = id + "/NavPropertyETBaseContMany(" + 
+    entityCollection.getEntities().get(1).getProperty("PropertyInt16").getValue() + ")";
+    entityCollection.getEntities().get(1).setId(URI.create(id));
+    id = "ESKeyNavCont(-32766)";
+    id = id + "/NavPropertyETBaseContMany(" + 
+    entityCollection.getEntities().get(2).getProperty("PropertyInt16").getValue() + ")";
+    entityCollection.getEntities().get(2).setId(URI.create(id));
+    return entityCollection;
+  }
+  
+  private void linkETBaseCont(final Map<String, EntityCollection> data) {
+    final EntityCollection entityCollection = data.get("ETBaseCont");
+    final List<Entity> etTwoContEntities = data.get("ETTwoCont").getEntities();
+    
+    setLinkForContNav(entityCollection.getEntities().get(1), 
+        "NavPropertyETBaseContTwoContOne", etTwoContEntities.get(0));
+    
+    setLinks(entityCollection.getEntities().get(2), "NavPropertyETBaseContTwoContMany", etTwoContEntities.get(1),
+        etTwoContEntities.get(2));
+  }
+  
+  private EntityCollection createETTwoCont(final Edm edm, final OData odata) {
+    EntityCollection entityCollection = new EntityCollection();
+
+    entityCollection.getEntities().add(new Entity()
+        .addProperty(createPrimitive("PropertyInt16", Short.MAX_VALUE))
+        .addProperty(createPrimitive("PropertyString", "First Resource - positive values"))
+        .addProperty(createPrimitive("PropertyBoolean", true))
+        .addProperty(createPrimitive("PropertyByte", (short) 255))
+        .addProperty(createPrimitive("PropertySByte", Byte.MAX_VALUE))
+        .addProperty(createPrimitive("PropertyInt32", Integer.MAX_VALUE))
+        .addProperty(createPrimitive("PropertyInt64", Long.MAX_VALUE))
+        .addProperty(createPrimitive("PropertySingle", (float) 1.79000000E+20))
+        .addProperty(createPrimitive("PropertyDouble", -1.7900000000000000E+19))
+        .addProperty(createPrimitive("PropertyDecimal", BigDecimal.valueOf(34)))
+        .addProperty(createPrimitive("PropertyBinary",
+            new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF }))
+        .addProperty(createPrimitive("PropertyDate", getDate(2012, 12, 3)))
+        .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2012, 12, 3, 7, 16, 23)))
+        .addProperty(createPrimitive("PropertyDuration", BigDecimal.valueOf(6)))
+        .addProperty(createPrimitive("PropertyGuid", GUID))
+        .addProperty(createPrimitive("PropertyTimeOfDay", getTime(3, 26, 5))));
+
+    entityCollection.getEntities().add(new Entity()
+        .addProperty(createPrimitive("PropertyInt16", Short.MIN_VALUE))
+        .addProperty(createPrimitive("PropertyString", "Second Resource - negative values"))
+        .addProperty(createPrimitive("PropertyBoolean", false))
+        .addProperty(createPrimitive("PropertyByte", (short) 0))
+        .addProperty(createPrimitive("PropertySByte", Byte.MIN_VALUE))
+        .addProperty(createPrimitive("PropertyInt32", Integer.MIN_VALUE))
+        .addProperty(createPrimitive("PropertyInt64", Long.MIN_VALUE))
+        .addProperty(createPrimitive("PropertySingle", (float) -1.79000000E+08))
+        .addProperty(createPrimitive("PropertyDouble", -1.7900000000000000E+05))
+        .addProperty(createPrimitive("PropertyDecimal", BigDecimal.valueOf(-34)))
+        .addProperty(createPrimitive("PropertyBinary",
+            new byte[] { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF }))
+        .addProperty(createPrimitive("PropertyDate", getDate(2015, 11, 5)))
+        .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2005, 12, 3, 7, 17, 8)))
+        .addProperty(createPrimitive("PropertyDuration", BigDecimal.valueOf(9)))
+        .addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789dddfff")))
+        .addProperty(createPrimitive("PropertyTimeOfDay", getTime(23, 49, 14))));
+
+    entityCollection.getEntities().add(new Entity()
+        .addProperty(createPrimitive("PropertyInt16", (short) 0))
+        .addProperty(createPrimitive("PropertyString", ""))
+        .addProperty(createPrimitive("PropertyBoolean", false))
+        .addProperty(createPrimitive("PropertyByte", (short) 0))
+        .addProperty(createPrimitive("PropertySByte", 0))
+        .addProperty(createPrimitive("PropertyInt32", 0))
+        .addProperty(createPrimitive("PropertyInt64", 0L))
+        .addProperty(createPrimitive("PropertySingle", (float) 0))
+        .addProperty(createPrimitive("PropertyDouble", 0D))
+        .addProperty(createPrimitive("PropertyDecimal", BigDecimal.valueOf(0)))
+        .addProperty(createPrimitive("PropertyBinary", new byte[] {}))
+        .addProperty(createPrimitive("PropertyDate", getDate(1970, 1, 1)))
+        .addProperty(createPrimitive("PropertyDateTimeOffset", getDateTime(2005, 12, 3, 0, 0, 0)))
+        .addProperty(createPrimitive("PropertyDuration", BigDecimal.valueOf(0)))
+        .addProperty(createPrimitive("PropertyGuid", UUID.fromString("76543201-23ab-cdef-0123-456789cccddd")))
+        .addProperty(createPrimitive("PropertyTimeOfDay", getTime(0, 1, 1))));
+
+    setEntityType(entityCollection, edm.getEntityType(EntityTypeProvider.nameETTwoCont));
+    createEntityId(edm, odata, "ESKeyNavCont", entityCollection);
+    String id = "ESKeyNavCont(-32766)/NavPropertyETBaseContMany(-32768)";
+    id = id + "/NavPropertyETBaseContTwoContOne(" + 
+    entityCollection.getEntities().get(0).getProperty("PropertyInt16").getValue() + ")";
+    entityCollection.getEntities().get(0).setId(URI.create(id));
+    id = "ESKeyNavCont(-32766)/NavPropertyETBaseContMany(0)";
+    id = id + "/NavPropertyETBaseContTwoContMany(" + 
+    entityCollection.getEntities().get(1).getProperty("PropertyInt16").getValue() + ")";
+    entityCollection.getEntities().get(1).setId(URI.create(id));
+    id = "ESKeyNavCont(-32766)/NavPropertyETBaseContMany(0)";
+    id = id + "/NavPropertyETBaseContTwoContMany(" + 
+        entityCollection.getEntities().get(2).getProperty("PropertyInt16").getValue() + ")";
+        entityCollection.getEntities().get(2).setId(URI.create(id));
+    return entityCollection;
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b86aa5d9/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
index c76f04b..0682c15 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
@@ -31,6 +31,7 @@ import java.util.UUID;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
+import org.apache.olingo.commons.api.Constants;
 import org.apache.olingo.commons.api.data.ComplexValue;
 import org.apache.olingo.commons.api.data.DeletedEntity;
 import org.apache.olingo.commons.api.data.DeletedEntity.Reason;
@@ -870,4 +871,109 @@ public class DataProvider {
     }
     return null;
   }
+  
+  public Entity createContNav(final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType, 
+      final Entity newEntity, List<UriParameter> keys, String navPropertyName) throws DataProviderException {
+    List<Entity> rootEntity = data.get(edmEntitySet.getName()).getEntities();
+    EntityCollection entitySet = data.get(edmEntityType.getName());
+    entitySet.getEntities().add(newEntity);
+    
+    
+    
+    for (Entity entity : rootEntity) {
+      if (isRootEntity(entity, keys)){
+        String id = entity.getId().toASCIIString() + "/" + navPropertyName + 
+            appendKeys(newEntity.getProperties(), edmEntityType.getKeyPredicateNames());
+        newEntity.setId(URI.create(id));
+        
+        Link link = entity.getNavigationLink(navPropertyName);
+        if (link == null) {
+          link = new Link();
+          link.setRel(Constants.NS_NAVIGATION_LINK_REL + navPropertyName);
+          link.setType(Constants.ENTITY_NAVIGATION_LINK_TYPE);
+          link.setTitle(navPropertyName);
+          link.setHref(entity.getId().toASCIIString() + 
+              (navPropertyName != null && navPropertyName.length() > 0 ? "/" + navPropertyName: ""));
+          entity.getNavigationLinks().add(link);
+        }
+        if (link.getInlineEntitySet() != null) {
+          link.getInlineEntitySet().getEntities().add(newEntity);
+        } else {
+          EntityCollection collection = new EntityCollection();
+          collection.getEntities().add(newEntity);
+          link.setInlineEntitySet(collection);
+        }
+      }
+    }
+    
+    return newEntity;
+  }
+
+  private String appendKeys(List<Property> properties, List<String> keyNames) {
+    StringBuilder keyValue = new StringBuilder();
+    keyValue.append("(");
+    for (int i = 0; i < keyNames.size(); i++) {
+      for (Property property : properties) {
+        if (property.getName().equals(keyNames.get(i))) {
+          keyValue.append(property.getName()).append("=");
+          keyValue.append(property.getValue());
+        }
+        if (i < keyNames.size() - 1) {
+          keyValue.append(",");
+        }
+      }
+    }
+    keyValue.append(")");
+    return keyValue.toString();
+  }
+
+  private boolean isRootEntity(Entity entity, List<UriParameter> keys) {
+    boolean found = false;
+    for (UriParameter key : keys) {
+      if (entity.getProperty(key.getName()).getValue().toString().equals(key.getText())) {
+        found = true;
+      } else {
+        found = false;
+      }
+    }
+    return found;
+  }
+  
+  public Entity readDataFromEntity(final EdmEntityType edmEntityType,
+      final List<UriParameter> keys) throws DataProviderException {
+    EntityCollection coll = data.get(edmEntityType.getName());
+    List<Entity> entities = coll.getEntities();
+    try {
+      for (final Entity entity : entities) {
+        boolean found = true;
+        for (final UriParameter key : keys) {
+          EdmKeyPropertyRef refType = edmEntityType.getKeyPropertyRef(key.getName());
+          Object value =  findPropertyRefValue(entity, refType);
+          
+          final EdmProperty property = refType.getProperty();
+          final EdmPrimitiveType type = (EdmPrimitiveType) property.getType();
+          
+          if (key.getExpression() != null && !(key.getExpression() instanceof Literal)) {
+            throw new DataProviderException("Expression in key value is not supported yet!",
+                HttpStatusCode.NOT_IMPLEMENTED);
+          }
+          final String text = key.getAlias() == null ? key.getText() : ((Literal) key.getExpression()).getText();
+          final Object keyValue = type.valueOfString(type.fromUriLiteral(text),
+              property.isNullable(), property.getMaxLength(), property.getPrecision(), property.getScale(),
+              property.isUnicode(),
+              Calendar.class.isAssignableFrom(value.getClass()) ? Calendar.class : value.getClass());
+          if (!value.equals(keyValue)) {
+            found = false;
+            break;
+          }
+        }
+        if (found) {
+          return entity;
+        }
+      }
+      return null;
+    } catch (final EdmPrimitiveTypeException e) {
+      throw new DataProviderException("Wrong key!", HttpStatusCode.BAD_REQUEST, e);
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b86aa5d9/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
index 207a0f2..f7bf618 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
@@ -175,7 +175,9 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
   public void createEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
       final ContentType requestFormat, final ContentType responseFormat)
       throws ODataApplicationException, ODataLibraryException {
-    if (uriInfo.asUriInfoResource().getUriResourceParts().size() > 1) {
+    final boolean isContNav = checkIfContNavigation(uriInfo);
+    if (uriInfo.asUriInfoResource().getUriResourceParts().size() > 1 && !isContNav ||
+        isContNav && uriInfo.asUriInfoResource().getUriResourceParts().size() > 2) {
       throw new ODataApplicationException("Invalid resource type.",
           HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
     }
@@ -194,7 +196,11 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
 
     final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
     final EdmEntitySet edmEntitySet = resourceEntitySet.getEntitySet();
-    final EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+    EdmEntityType edmEntityType = null;
+    edmEntityType = getEdmTypeForContNavProperty(uriInfo);
+    if (edmEntityType == null) {
+      edmEntityType = edmEntitySet.getEntityType();
+    }
 
     final Entity entity;
     ExpandOption expand = null;
@@ -208,8 +214,14 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
       new RequestValidator(dataProvider, request.getRawBaseUri())
           .validate(edmEntitySet, deserializerResult.getEntity());
 
-      entity = dataProvider.create(edmEntitySet);
-      dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, deserializerResult.getEntity(), false, true);
+      if (isContNav) {
+        entity = dataProvider.createContNav(edmEntitySet, edmEntityType, deserializerResult.getEntity(), 
+            ((UriResourceEntitySet)uriInfo.getUriResourceParts().get(0)).getKeyPredicates(), 
+            ((UriResourceNavigation)uriInfo.getUriResourceParts().get(1)).getSegmentValue());
+      } else {
+        entity = dataProvider.create(edmEntitySet);
+        dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, deserializerResult.getEntity(), false, true);
+      }
       expand = deserializerResult.getExpandTree();
     }
 
@@ -217,8 +229,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
         + odata.createUriHelper().buildCanonicalURL(edmEntitySet, entity);
     final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
     if (returnPreference == null || returnPreference == Return.REPRESENTATION) {
-      response.setContent(serializeEntity(request, entity, edmEntitySet, edmEntityType, responseFormat, expand, null)
-          .getContent());
+      response.setContent(serializeEntity(request, entity, edmEntitySet, edmEntityType, responseFormat, 
+          expand, null, isContNav).getContent());
       response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
       response.setStatusCode(HttpStatusCode.CREATED.getStatusCode());
     } else {
@@ -450,7 +462,12 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
     //for Singleton/$ref edmEntityset will be null throw error
     validateSingletonRef(isReference,edmEntitySet);
    
-    final EdmEntityType edmEntityType = getEdmType(uriInfo, edmEntitySet);
+    EdmEntityType edmEntityType = null;
+    edmEntityType = getEdmTypeForContNavProperty(uriInfo);
+    final boolean iscontNav = checkIfContNavigation(uriInfo);
+    if (edmEntityType == null) {
+      edmEntityType = getEdmType(uriInfo, edmEntitySet);
+    }
 
     final Entity entity = readEntity(uriInfo);
 
@@ -472,7 +489,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
 
     final SerializerResult serializerResult = isReference ?
         serializeReference(entity, edmEntitySet, requestedFormat) :
-        serializeEntity(request, entitySerialization, edmEntitySet, edmEntityType, requestedFormat, expand, select);
+        serializeEntity(request, entitySerialization, edmEntitySet, edmEntityType, 
+            requestedFormat, expand, select, iscontNav);
 
     if (entity.getETag() != null) {
       response.setHeader(HttpHeader.ETAG, entity.getETag());
@@ -481,6 +499,39 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
     response.setStatusCode(HttpStatusCode.OK.getStatusCode());
     response.setHeader(HttpHeader.CONTENT_TYPE, requestedFormat.toContentTypeString());
   }
+  
+  private boolean checkIfContNavigation(UriInfo uriInfo) {
+    List<UriResource> pathSegments = uriInfo.getUriResourceParts();
+    for(UriResource resource : pathSegments) {
+      if (resource instanceof UriResourceNavigation) {
+        UriResourceNavigation navResource = (UriResourceNavigation) resource;
+        if (navResource.getProperty().containsTarget()) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  private EdmEntityType getEdmTypeForContNavProperty(UriInfo uriInfo) {
+    List<UriResource> pathSegments = uriInfo.getUriResourceParts();
+    EdmEntityType type = null;
+    for(UriResource resource : pathSegments) {
+      if (resource instanceof UriResourceNavigation) {
+        UriResourceNavigation navResource = (UriResourceNavigation) resource;
+        if (navResource.getProperty().containsTarget()) {
+          if (navResource.getTypeFilterOnCollection() != null) {
+            type = ((EdmEntityType) navResource.getTypeFilterOnCollection());
+          } else if (navResource.getTypeFilterOnEntry() != null) {
+            type = ((EdmEntityType) navResource.getTypeFilterOnEntry());
+          } else {
+            type = ((EdmEntityType) navResource.getType());
+          }
+        }
+      }
+    }
+    return type;
+  }
 
   /*This method validates if the $ref is called directly on Singleton
    * Error is thrown when $ref is called on a Singleton as it is not implemented*/
@@ -530,10 +581,15 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
     //
 
     final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
-    final EdmEntityType edmEntityType = edmEntitySet == null ?
-        (EdmEntityType) ((UriResourcePartTyped) uriInfo.getUriResourceParts()
-            .get(uriInfo.getUriResourceParts().size() - 1)).getType() :
-        edmEntitySet.getEntityType();
+    final boolean isContNav = checkIfContNavigation(uriInfo);
+    EdmEntityType edmEntityType = null;
+    edmEntityType = getEdmTypeForContNavProperty(uriInfo);
+    if (edmEntityType == null) {
+      edmEntityType = edmEntitySet == null ?
+          (EdmEntityType) ((UriResourcePartTyped) uriInfo.getUriResourceParts()
+              .get(uriInfo.getUriResourceParts().size() - 1)).getType() :
+          edmEntitySet.getEntityType();
+    }
 
     EntityCollection entitySetInitial = readEntityCollection(uriInfo);
     Delta delta = null;
@@ -640,7 +696,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
       final SerializerResult serializerResult =
           serializeEntityCollection(request,
               entitySetSerialization, edmEntitySet, edmEntityType, requestedContentType,
-              expand, select, countOption, id);
+              expand, select, countOption, id, isContNav);
       response.setContent(serializerResult.getContent());
     }
 
@@ -681,7 +737,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
         edmEntityType, delta,
         EntityCollectionSerializerOptions.with()
         .contextURL(isODataMetadataNone(requestedFormat) ? null :
-          getContextUrl(request.getRawODataPath(), edmEntitySet, edmEntityType, false, expand, select))
+          getContextUrl(request.getRawODataPath(), edmEntitySet, edmEntityType, false, expand, select, false))
       .count(countOption)
       .expand(expand).select(select)
       .id(id)
@@ -707,7 +763,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
   private SerializerResult serializeEntityCollection(final ODataRequest request, final EntityCollection
       entityCollection, final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType,
       final ContentType requestedFormat, final ExpandOption expand, final SelectOption select,
-      final CountOption countOption, String id) throws ODataLibraryException {
+      final CountOption countOption, String id, final boolean isContNav) throws ODataLibraryException {
 
     return odata.createSerializer(requestedFormat, request.getHeaders(HttpHeader.ODATA_VERSION))
         .entityCollection(
@@ -716,7 +772,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
         entityCollection,
         EntityCollectionSerializerOptions.with()
             .contextURL(isODataMetadataNone(requestedFormat) ? null :
-                getContextUrl(request.getRawODataPath(), edmEntitySet, edmEntityType, false, expand, select))
+                getContextUrl(request.getRawODataPath(), edmEntitySet, edmEntityType, false, expand, select, isContNav))
             .count(countOption)
             .expand(expand).select(select)
             .id(id)
@@ -797,7 +853,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
         streamCollection,
         EntityCollectionSerializerOptions.with()
             .contextURL(isODataMetadataNone(requestedFormat) ? null :
-                getContextUrl(request.getRawODataPath(), edmEntitySet, edmEntityType, false, expand, select))
+                getContextUrl(request.getRawODataPath(), edmEntitySet, edmEntityType, false, expand, select, false))
             .count(countOption)
             .expand(expand).select(select)
             .id(id)
@@ -826,17 +882,17 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
   private SerializerResult serializeEntity(final ODataRequest request, final Entity entity,
       final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType,
       final ContentType requestedFormat) throws ODataLibraryException {
-    return serializeEntity(request, entity, edmEntitySet, edmEntityType, requestedFormat, null, null);
+    return serializeEntity(request, entity, edmEntitySet, edmEntityType, requestedFormat, null, null, false);
   }
 
   private SerializerResult serializeEntity(final ODataRequest request, final Entity entity,
       final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType,
       final ContentType requestedFormat,
-      final ExpandOption expand, final SelectOption select)
+      final ExpandOption expand, final SelectOption select, final boolean isContNav)
       throws ODataLibraryException {
 
     ContextURL contextUrl = isODataMetadataNone(requestedFormat) ? null :
-        getContextUrl(request.getRawODataPath(), edmEntitySet, edmEntityType, true, expand, null);
+        getContextUrl(request.getRawODataPath(), edmEntitySet, edmEntityType, true, expand, null,isContNav);
     return odata.createSerializer(requestedFormat, request.getHeaders(HttpHeader.ODATA_VERSION)).entity(
         serviceMetadata,
         edmEntityType,
@@ -848,12 +904,12 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
   }
 
   private ContextURL getContextUrl(String rawODataPath, final EdmEntitySet entitySet, final EdmEntityType entityType,
-      final boolean isSingleEntity, final ExpandOption expand, final SelectOption select)
+      final boolean isSingleEntity, final ExpandOption expand, final SelectOption select, final boolean isContNav)
       throws ODataLibraryException {
     Builder builder = ContextURL.with().oDataPath(rawODataPath);
     builder = entitySet == null ?
         isSingleEntity ? builder.type(entityType) : builder.asCollection().type(entityType) :
-        builder.entitySet(entitySet);
+          !isContNav ? builder.entitySet(entitySet) : builder.entitySetOrSingletonOrType(rawODataPath.substring(1));
     builder = builder
         .selectList(odata.createUriHelper().buildContextURLSelectList(entityType, expand, select))
         .suffix(isSingleEntity && entitySet != null ? Suffix.ENTITY : null);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b86aa5d9/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
index 31afcfa..42627eb 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
@@ -111,8 +111,7 @@ public abstract class TechnicalProcessor implements Processor {
             (UriResourceNavigation) resourcePaths.get(navigationCount);
         blockTypeFilters(uriResourceNavigation);
         if (uriResourceNavigation.getProperty().containsTarget()) {
-          throw new ODataApplicationException("Containment navigation is not supported.",
-              HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+          return entitySet;
         }
         EdmBindingTarget target = null ;
         if(entitySet!=null){
@@ -203,6 +202,8 @@ public abstract class TechnicalProcessor implements Processor {
           key.isEmpty() ?
               link.getInlineEntity() :
               dataProvider.read(navigationProperty.getType(), link.getInlineEntitySet(), key);
+      EdmEntityType edmEntityType = getEntityTypeBasedOnNavPropertyTypeCast(uriNavigationResource);
+      entity = edmEntityType != null ? dataProvider.readDataFromEntity(edmEntityType, key) : entity;
       if (entity == null) {
         throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
       }
@@ -210,6 +211,16 @@ public abstract class TechnicalProcessor implements Processor {
 
     return entity;
   }
+  
+  private EdmEntityType getEntityTypeBasedOnNavPropertyTypeCast(UriResourceNavigation uriNavigationResource) {
+    if (uriNavigationResource.getTypeFilterOnCollection() != null) {
+      return (EdmEntityType) uriNavigationResource.getTypeFilterOnCollection();
+    } else if (uriNavigationResource.getTypeFilterOnEntry() != null) {
+      return (EdmEntityType) uriNavigationResource.getTypeFilterOnEntry();
+    }
+    return null;
+    
+  }
 
   protected EdmEntitySet getEntitySetBasedOnTypeCast(UriResourceEntitySet uriResource) {
     EdmEntitySet entitySet = null;
@@ -301,10 +312,7 @@ public abstract class TechnicalProcessor implements Processor {
   private void blockTypeFilters(final UriResource uriResource) throws ODataApplicationException {
     if (uriResource instanceof UriResourceFunction
         && (((UriResourceFunction) uriResource).getTypeFilterOnCollection() != null
-        || ((UriResourceFunction) uriResource).getTypeFilterOnEntry() != null)
-        || uriResource instanceof UriResourceNavigation
-        && (((UriResourceNavigation) uriResource).getTypeFilterOnCollection() != null
-        || ((UriResourceNavigation) uriResource).getTypeFilterOnEntry() != null)) {
+        || ((UriResourceFunction) uriResource).getTypeFilterOnEntry() != null)) {
       throw new ODataApplicationException("Type filters are not supported.",
           HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b86aa5d9/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
index 114acef..0b4d726 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
@@ -182,7 +182,9 @@ public class ComplexTypeProvider {
               PropertyProvider.navPropertyETKeyNavOne_CT_ETeyNav,
               PropertyProvider.collectionNavPropertyETKeyNavMany_CT_ETKeyNav,
               PropertyProvider.navPropertyETTwoKeyNavOne_CT_ETTwoKeyNav,
-              PropertyProvider.collectionNavPropertyETTwoKeyNavMany_CT_ETTwoKeyNav
+              PropertyProvider.collectionNavPropertyETTwoKeyNavMany_CT_ETTwoKeyNav,
+              PropertyProvider.navPropertyETTwoKeyNavMany_CT_ETCont,
+              PropertyProvider.collectionNavPropertyETTwoKeyNavMany_CT_ETBaseCont
               ));
 
     } else if (complexTypeName.equals(nameCTBasePrimCompNav)) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b86aa5d9/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java
index 6178c48..079a1f8 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/EntityTypeProvider.java
@@ -91,7 +91,13 @@ public class EntityTypeProvider {
       new FullQualifiedName(SchemaProvider.NAMESPACE, "ETDelta"); 
   
   public static final FullQualifiedName nameETPeople = new FullQualifiedName(SchemaProvider.NAMESPACE, "ETPeople");
-
+  
+ public static final FullQualifiedName nameETCont = new FullQualifiedName(SchemaProvider.NAMESPACE, "ETCont");
+  
+  public static final FullQualifiedName nameETBaseCont = new FullQualifiedName(SchemaProvider.NAMESPACE, "ETBaseCont");
+  
+  public static final FullQualifiedName nameETTwoCont = new FullQualifiedName(SchemaProvider.NAMESPACE, "ETTwoCont");
+  
   public CsdlEntityType getEntityType(final FullQualifiedName entityTypeName) throws ODataException {
     if(entityTypeName.equals(nameETAllPrimDefaultValues)){        
         return new CsdlEntityType()
@@ -382,7 +388,10 @@ public class EntityTypeProvider {
               PropertyProvider.navPropertyETTwoKeyNavOneCT_ETTwoKeyNav,
               PropertyProvider.collectionNavPropertyETTwoKeyNavMany_CT_ETTwoKeyNav,
               PropertyProvider.navPropertyETTwoKeyNavContOne_ETTwoKeyNav,
-              PropertyProvider.collectionNavPropertyETTwoKeyNavContMany_ETTwoKeyNav
+              PropertyProvider.collectionNavPropertyETTwoKeyNavContMany_ETTwoKeyNav,
+              PropertyProvider.navPropertyETTwoKeyNavContOne_ETCont,
+              PropertyProvider.collectionNavPropertyETTwoKeyNavContMany_ETCont,
+              PropertyProvider.collectionNavPropertyETTwoKeyNavContMany_ETBaseCont
               ));
 
     } else if (entityTypeName.equals(nameETTwoKeyNavCont)) {
@@ -514,7 +523,44 @@ public class EntityTypeProvider {
           .setNavigationProperties(
               Arrays.asList(PropertyProvider.navPropertyETAllPrimOne_ETAllPrim,
                   PropertyProvider.collectionNavPropertyETAllPrimMany_ETAllPrim));
-    } 
+    } else if (entityTypeName.equals(nameETCont)) {
+      return new CsdlEntityType()
+          .setName("ETCont").setBaseType(nameETBaseCont)
+          .setProperties(Arrays.asList(
+              PropertyProvider.propertyBoolean, PropertyProvider.propertyByte, PropertyProvider.propertySByte
+              ))
+          .setNavigationProperties(Arrays.asList(PropertyProvider.navPropertyETCont_ETTwoPrim,
+              PropertyProvider.collectionNavPropertyETContMany_ETTwoPrim));
+    } else if (entityTypeName.equals(nameETBaseCont)) {
+      return new CsdlEntityType()
+          .setName("ETBaseCont")
+          .setKey(Arrays.asList(
+              new CsdlPropertyRef().setName("PropertyInt16")))
+          .setProperties(Arrays.asList(
+              PropertyProvider.propertyInt16_NotNullable, PropertyProvider.propertyString,
+              PropertyProvider.propertyInt32, PropertyProvider.propertyInt64,
+              PropertyProvider.propertySingle, PropertyProvider.propertyDouble, PropertyProvider.propertyDecimal_Scale,
+              PropertyProvider.propertyBinary, PropertyProvider.propertyDate, PropertyProvider.propertyDateTimeOffset,
+              PropertyProvider.propertyDuration, PropertyProvider.propertyGuid, PropertyProvider.propertyTimeOfDay
+              ))
+          .setNavigationProperties(Arrays.asList(PropertyProvider.navPropertyETBaseCont_ETTwoPrim,
+              PropertyProvider.collectionNavPropertyETBaseContMany_ETTwoPrim,
+              PropertyProvider.collectionNavPropertyETBaseContMany_ETTwoCont,
+              PropertyProvider.navPropertyETBaseCont_ETTwoCont));
+    } else if (entityTypeName.equals(nameETTwoCont)) {
+      return new CsdlEntityType()
+          .setName("ETTwoCont")
+          .setKey(Arrays.asList(
+              new CsdlPropertyRef().setName("PropertyInt16"),
+              new CsdlPropertyRef().setName("PropertyString")))
+          .setProperties(Arrays.asList(
+              PropertyProvider.propertyInt16_NotNullable, PropertyProvider.propertyString_NotNullable,
+              PropertyProvider.propertyInt32, PropertyProvider.propertyInt64,
+              PropertyProvider.propertySingle, PropertyProvider.propertyDouble, PropertyProvider.propertyDecimal_Scale,
+              PropertyProvider.propertyBinary, PropertyProvider.propertyDate, PropertyProvider.propertyDateTimeOffset,
+              PropertyProvider.propertyDuration, PropertyProvider.propertyGuid, PropertyProvider.propertyTimeOfDay
+              ));
+    }
     return null;
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b86aa5d9/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java
index f991d7f..e74fd6d 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java
@@ -952,4 +952,70 @@ public class PropertyProvider {
     .setType(EntityTypeProvider.nameETPeople)
     .setNullable(true)
     .setCollection(true);
+  
+  public static final CsdlNavigationProperty navPropertyETCont_ETTwoPrim = new CsdlNavigationProperty()
+      .setName("NavPropertyETContOne")
+      .setType(EntityTypeProvider.nameETTwoPrim)
+      .setNullable(false);
+  
+  public static final CsdlNavigationProperty collectionNavPropertyETContMany_ETTwoPrim =
+      new CsdlNavigationProperty()
+          .setName("NavPropertyETContMany")
+          .setType(EntityTypeProvider.nameETTwoPrim)
+          .setCollection(true);
+  
+  public static final CsdlNavigationProperty navPropertyETBaseCont_ETTwoPrim = new CsdlNavigationProperty()
+      .setName("NavPropertyETBaseContOne")
+      .setType(EntityTypeProvider.nameETTwoBase)
+      .setNullable(false);
+  
+  public static final CsdlNavigationProperty collectionNavPropertyETBaseContMany_ETTwoPrim =
+      new CsdlNavigationProperty()
+          .setName("NavPropertyETBaseContMany")
+          .setType(EntityTypeProvider.nameETTwoBase)
+          .setCollection(true);
+  
+  public static final CsdlNavigationProperty navPropertyETBaseCont_ETTwoCont = new CsdlNavigationProperty()
+      .setName("NavPropertyETBaseContTwoContOne")
+      .setType(EntityTypeProvider.nameETTwoCont).setContainsTarget(true)
+      .setNullable(false);
+  
+  public static final CsdlNavigationProperty collectionNavPropertyETBaseContMany_ETTwoCont =
+      new CsdlNavigationProperty()
+          .setName("NavPropertyETBaseContTwoContMany")
+          .setType(EntityTypeProvider.nameETTwoCont).setContainsTarget(true)
+          .setCollection(true);
+  
+  public static final CsdlNavigationProperty navPropertyETTwoKeyNavContOne_ETCont = new CsdlNavigationProperty()
+      .setName("NavPropertyETContOne")
+      .setContainsTarget(true)
+      .setType(EntityTypeProvider.nameETCont);
+  
+  public static final CsdlNavigationProperty collectionNavPropertyETTwoKeyNavContMany_ETCont = 
+      new CsdlNavigationProperty()
+      .setName("NavPropertyETContMany")
+      .setContainsTarget(true)
+      .setType(EntityTypeProvider.nameETCont)
+      .setCollection(true);
+  
+  public static final CsdlNavigationProperty collectionNavPropertyETTwoKeyNavContMany_ETBaseCont = 
+      new CsdlNavigationProperty()
+      .setName("NavPropertyETBaseContMany")
+      .setContainsTarget(true)
+      .setType(EntityTypeProvider.nameETBaseCont)
+      .setCollection(true);
+  
+  public static final CsdlNavigationProperty navPropertyETTwoKeyNavMany_CT_ETCont =
+      new CsdlNavigationProperty()
+          .setName("NavPropertyETTwoKeyNavETContOne")
+          .setContainsTarget(true)
+          .setType(EntityTypeProvider.nameETCont);
+  
+  public static final CsdlNavigationProperty collectionNavPropertyETTwoKeyNavMany_CT_ETBaseCont =
+      new CsdlNavigationProperty()
+          .setName("NavPropertyETTwoKeyNavETContMany")
+          .setContainsTarget(true)
+          .setCollection(true)
+          .setType(EntityTypeProvider.nameETBaseCont);
+  
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b86aa5d9/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java
index 074870e..72c4f27 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java
@@ -87,6 +87,9 @@ public class SchemaProvider {
     entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETKeyPrimNav));
     entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETStream));
     entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETDelta)); 
+    entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETCont)); 
+    entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETBaseCont)); 
+    entityTypes.add(prov.getEntityType(EntityTypeProvider.nameETTwoCont)); 
     
     // ComplexTypes
     List<CsdlComplexType> complexTypes = new ArrayList<CsdlComplexType>();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b86aa5d9/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
index f092246..80b00fd 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
@@ -39,6 +39,7 @@ import org.apache.olingo.commons.api.data.ContextURL.Suffix;
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntityCollection;
 import org.apache.olingo.commons.api.data.EntityIterator;
+import org.apache.olingo.commons.api.data.Link;
 import org.apache.olingo.commons.api.data.Operation;
 import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.data.ValueType;
@@ -2514,4 +2515,81 @@ public class ODataJsonSerializerTest {
     Mockito.when(complexType.getNamespace()).thenReturn("olingo.odata.test1");
     return complexType;
   }  
+  
+  @Test
+  public void entityESKeyNavContFullMetadata() throws Exception {
+    final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESKeyNavCont");
+    final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
+    InputStream result = serializerFullMetadata.entity(metadata, edmEntitySet.getEntityType(), entity,
+        EntitySerializerOptions.with()
+            .contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
+            .build()).getContent();
+    final String resultString = IOUtils.toString(result);
+    final String expected = "{\"@odata.context\":\"$metadata#ESKeyNavCont/$entity\","
+        + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\",\"@odata.type\":"
+        + "\"#olingo.odata.test1.ETKeyNavCont\",\"@odata.id\":\"ESKeyNavCont(32766)\","
+        + "\"PropertyInt16@odata.type\":\"#Int16\",\"PropertyInt16\":32766,"
+        + "\"PropertyString\":\"Test String1\",\"PropertyCompNavCont\":"
+        + "{\"@odata.type\":\"#olingo.odata.test1.CTNavCont\"}}";        
+
+    Assert.assertEquals(expected, resultString);
+  }
+  
+  @Test
+  public void entityESKeyNavContFullMetadataWithContNav() throws Exception {
+    final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESKeyNavCont");
+    final Entity entity = data.readAll(edmEntitySet).getEntities().get(1);
+    Link link = entity.getNavigationLink("NavPropertyETContMany");
+    InputStream result = serializerFullMetadata.entityCollection(metadata, 
+        edmEntitySet.getEntityType().getNavigationProperty("NavPropertyETContMany").getType(), 
+        link.getInlineEntitySet(),
+        EntityCollectionSerializerOptions.with()
+            .contextURL(ContextURL.with().
+                type(edmEntitySet.getEntityType().getNavigationProperty("NavPropertyETContMany").getType())
+                .entitySetOrSingletonOrType("ESKeyNavCont(-365)/NavPropertyETContMany").build())
+            .build()).getContent();
+    final String resultString = IOUtils.toString(result);
+    final String expected = "{\"@odata.context\":\"$metadata#ESKeyNavCont%28-365%29%2FNavPropertyETContMany\","
+        + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\",\"value\":[{"
+        + "\"@odata.type\":\"#olingo.odata.test1.ETCont\",\"@odata.id\":"
+        + "\"ESKeyNavCont(-365)/NavPropertyETContMany(-32768)\","
+        + "\"PropertyInt16@odata.type\":\"#Int16\",\"PropertyInt16\":-32768,"
+        + "\"PropertyString\":\"Second Resource - negative values\",\"PropertyInt32@odata.type\":"
+        + "\"#Int32\",\"PropertyInt32\":-2147483648,\"PropertyInt64@odata.type\":\"#Int64\","
+        + "\"PropertyInt64\":-9223372036854775808,\"PropertySingle@odata.type\":\"#Single\","
+        + "\"PropertySingle\":-1.79E8,\"PropertyDouble\":-179000.0,"
+        + "\"PropertyDecimal@odata.type\":\"#Decimal\",\"PropertyDecimal\":-34,"
+        + "\"PropertyBinary@odata.type\":\"#Binary\",\"PropertyBinary\":\"ASNFZ4mrze8=\","
+        + "\"PropertyDate@odata.type\":\"#Date\",\"PropertyDate\":\"2015-11-05\","
+        + "\"PropertyDateTimeOffset@odata.type\":\"#DateTimeOffset\","
+        + "\"PropertyDateTimeOffset\":\"2005-12-03T07:17:08Z\","
+        + "\"PropertyDuration@odata.type\":\"#Duration\","
+        + "\"PropertyDuration\":\"PT9S\",\"PropertyGuid@odata.type\":"
+        + "\"#Guid\",\"PropertyGuid\":\"76543201-23ab-cdef-0123-456789dddfff\","
+        + "\"PropertyTimeOfDay@odata.type\":\"#TimeOfDay\","
+        + "\"PropertyTimeOfDay\":\"23:49:14\",\"PropertyBoolean\":false,"
+        + "\"PropertyByte@odata.type\":\"#Byte\",\"PropertyByte\":0,"
+        + "\"PropertySByte@odata.type\":\"#SByte\",\"PropertySByte\":-128},"
+        + "{\"@odata.type\":\"#olingo.odata.test1.ETCont\","
+        + "\"@odata.id\":\"ESKeyNavCont(-365)/NavPropertyETContMany(0)\","
+        + "\"PropertyInt16@odata.type\":\"#Int16\",\"PropertyInt16\":0,"
+        + "\"PropertyString\":\"\",\"PropertyInt32@odata.type\":\"#Int32\","
+        + "\"PropertyInt32\":0,\"PropertyInt64@odata.type\":\"#Int64\","
+        + "\"PropertyInt64\":0,\"PropertySingle@odata.type\":\"#Single\","
+        + "\"PropertySingle\":0.0,\"PropertyDouble\":0.0,"
+        + "\"PropertyDecimal@odata.type\":\"#Decimal\",\"PropertyDecimal\":0,"
+        + "\"PropertyBinary@odata.type\":\"#Binary\",\"PropertyBinary\":\"\","
+        + "\"PropertyDate@odata.type\":\"#Date\",\"PropertyDate\":\"1970-01-01\","
+        + "\"PropertyDateTimeOffset@odata.type\":\"#DateTimeOffset\","
+        + "\"PropertyDateTimeOffset\":\"2005-12-03T00:00:00Z\","
+        + "\"PropertyDuration@odata.type\":\"#Duration\",\"PropertyDuration\":\"PT0S\","
+        + "\"PropertyGuid@odata.type\":\"#Guid\","
+        + "\"PropertyGuid\":\"76543201-23ab-cdef-0123-456789cccddd\","
+        + "\"PropertyTimeOfDay@odata.type\":\"#TimeOfDay\","
+        + "\"PropertyTimeOfDay\":\"00:01:01\",\"PropertyBoolean\":false,"
+        + "\"PropertyByte@odata.type\":\"#Byte\",\"PropertyByte\":0,"
+        + "\"PropertySByte@odata.type\":\"#SByte\",\"PropertySByte\":0}]}";        
+
+    Assert.assertEquals(expected, resultString);
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b86aa5d9/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/data/Storage.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/data/Storage.java b/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/data/Storage.java
index 9b2d342..6b8d673 100755
--- a/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/data/Storage.java
+++ b/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/data/Storage.java
@@ -23,9 +23,7 @@ import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.List;
 
-import myservice.mynamespace.service.DemoEdmProvider;
-import myservice.mynamespace.util.Util;
-
+import org.apache.olingo.commons.api.data.ComplexValue;
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntityCollection;
 import org.apache.olingo.commons.api.data.Property;
@@ -36,20 +34,26 @@ import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.ex.ODataRuntimeException;
 import org.apache.olingo.server.api.uri.UriParameter;
 
+import myservice.mynamespace.service.DemoEdmProvider;
+import myservice.mynamespace.util.Util;
+
 public class Storage {
 
   // represent our database
   private List<Entity> productList;
   private List<Entity> categoryList;
+  private List<Entity> supplierList;
 
   public Storage() {
 
     productList = new ArrayList<Entity>();
     categoryList = new ArrayList<Entity>();
+    supplierList = new ArrayList<Entity>();
 
     // creating some sample data
     initProductSampleData();
     initCategorySampleData();
+    initSupplierSampleData();
   }
 
   /* PUBLIC FACADE */
@@ -75,6 +79,8 @@ public class Storage {
       entity = getProduct(edmEntityType, keyParams);
     } else if (edmEntityType.getName().equals(DemoEdmProvider.ET_CATEGORY_NAME)) {
       entity = getCategory(edmEntityType, keyParams);
+    } else if (edmEntityType.getName().equals(DemoEdmProvider.ET_SUPPLIER_NAME)) {
+      entity = getSupplier(edmEntityType, keyParams);
     }
 
     return entity;
@@ -127,6 +133,23 @@ public class Storage {
         // the first 2 products are monitors
         navigationTargetEntityCollection.getEntities().addAll(productList.subList(4, 6));
       }
+    } else if (sourceEntityFqn.equals(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString())
+        && relatedEntityFqn.equals(DemoEdmProvider.ET_SUPPLIER_FQN)) {
+      int productID = (Integer) sourceEntity.getProperty("ID").getValue();
+      if (productID == 1) {
+        navigationTargetEntityCollection.getEntities().add(supplierList.get(0));
+        navigationTargetEntityCollection.getEntities().add(supplierList.get(1));
+      } else if (productID == 2) {
+        navigationTargetEntityCollection.getEntities().add(supplierList.get(2));
+      } else if (productID == 3) {
+        navigationTargetEntityCollection.getEntities().add(supplierList.get(3));
+      } else if (productID == 4) {
+        navigationTargetEntityCollection.getEntities().add(supplierList.get(4));
+      } else if (productID == 5) {
+        navigationTargetEntityCollection.getEntities().add(supplierList.get(5));
+      } else if (productID == 6) {
+        navigationTargetEntityCollection.getEntities().add(supplierList.get(6));
+      }
     }
 
     if (navigationTargetEntityCollection.getEntities().isEmpty()) {
@@ -147,6 +170,16 @@ public class Storage {
 
     return retEntitySet;
   }
+  
+  private EntityCollection getSuppliers() {
+    EntityCollection retEntitySet = new EntityCollection();
+
+    for (Entity supplierEntity : this.supplierList) {
+      retEntitySet.getEntities().add(supplierEntity);
+    }
+
+    return retEntitySet;
+  }
 
   private Entity getProduct(EdmEntityType edmEntityType, List<UriParameter> keyParams) {
 
@@ -156,6 +189,15 @@ public class Storage {
     /* generic approach to find the requested entity */
     return Util.findEntity(edmEntityType, entityCollection, keyParams);
   }
+  
+  private Entity getSupplier(EdmEntityType edmEntityType, List<UriParameter> keyParams) {
+
+    // the list of entities at runtime
+    EntityCollection entityCollection = getSuppliers();
+
+    /* generic approach to find the requested entity */
+    return Util.findEntity(edmEntityType, entityCollection, keyParams);
+  }
 
   private EntityCollection getCategories() {
     EntityCollection entitySet = new EntityCollection();
@@ -260,6 +302,123 @@ public class Storage {
     entity.setId(createId(entity, "ID"));
     categoryList.add(entity);
   }
+  
+  private void initSupplierSampleData() {
+
+    Entity entity = new Entity();
+
+    entity.addProperty(new Property(null, "SupplierID", ValueType.PRIMITIVE, 1));
+    entity.addProperty(new Property(null, "CompanyName", ValueType.PRIMITIVE, "DESIGN INDEX INDIA"));
+    entity.addProperty(new Property(null, "Fax", ValueType.PRIMITIVE,
+        "null"));
+    
+    Property p1 = new Property(null, "City", ValueType.PRIMITIVE, "Delhi");
+    Property p2 = new Property(null, "Country", ValueType.PRIMITIVE, "India");
+    ComplexValue complexValue = new ComplexValue();
+    complexValue.getValue().add(p1);
+    complexValue.getValue().add(p2);
+    
+    entity.addProperty(new Property(null, "Address", ValueType.COMPLEX, complexValue));
+    entity.setType(DemoEdmProvider.ET_SUPPLIER_FQN.getFullQualifiedNameAsString());
+    entity.setId(createId(entity, "SupplierID", "Suppliers", "1"));
+    supplierList.add(entity);
+
+    entity = new Entity();
+    entity.addProperty(new Property(null, "SupplierID", ValueType.PRIMITIVE, 2));
+    entity.addProperty(new Property(null, "CompanyName", ValueType.PRIMITIVE, "Advance Label Ltd"));
+    entity.addProperty(new Property(null, "Fax", ValueType.PRIMITIVE,
+        "(617) 555-3389"));
+    p1 = new Property(null, "City", ValueType.PRIMITIVE, "Tsuen Wan");
+    p2 = new Property(null, "Country", ValueType.PRIMITIVE, "Hong Kong");
+    complexValue = new ComplexValue();
+    complexValue.getValue().add(p1);
+    complexValue.getValue().add(p2);
+    
+    entity.addProperty(new Property(null, "Address", ValueType.COMPLEX, complexValue));
+    entity.setType(DemoEdmProvider.ET_SUPPLIER_FQN.getFullQualifiedNameAsString());
+    entity.setId(createId(entity, "SupplierID", "Suppliers", "1"));
+    supplierList.add(entity);
+
+    entity = new Entity();
+    entity.addProperty(new Property(null, "SupplierID", ValueType.PRIMITIVE, 3));
+    entity.addProperty(new Property(null, "CompanyName", ValueType.PRIMITIVE, "TECH GROUP INTERNATIONAL LIMITED "));
+    entity.addProperty(new Property(null, "Fax", ValueType.PRIMITIVE,
+        "null"));
+    p1 = new Property(null, "City", ValueType.PRIMITIVE, "Bangalore");
+    p2 = new Property(null, "Country", ValueType.PRIMITIVE, "India");
+    complexValue = new ComplexValue();
+    complexValue.getValue().add(p1);
+    complexValue.getValue().add(p2);
+    
+    entity.addProperty(new Property(null, "Address", ValueType.COMPLEX, complexValue));
+    entity.setType(DemoEdmProvider.ET_SUPPLIER_FQN.getFullQualifiedNameAsString());
+    entity.setId(createId(entity, "SupplierID", "Suppliers", "2"));
+    supplierList.add(entity);
+
+    entity = new Entity();
+    entity.addProperty(new Property(null, "SupplierID", ValueType.PRIMITIVE, 4));
+    entity.addProperty(new Property(null, "CompanyName", ValueType.PRIMITIVE, "BenQ India Pvt Ltd"));
+    entity.addProperty(new Property(null, "Fax", ValueType.PRIMITIVE,
+        "43844115"));
+    p1 = new Property(null, "City", ValueType.PRIMITIVE, "Gurgaon");
+    p2 = new Property(null, "Country", ValueType.PRIMITIVE, "India");
+    complexValue = new ComplexValue();
+    complexValue.getValue().add(p1);
+    complexValue.getValue().add(p2);
+    
+    entity.addProperty(new Property(null, "Address", ValueType.COMPLEX, complexValue));
+    entity.setType(DemoEdmProvider.ET_SUPPLIER_FQN.getFullQualifiedNameAsString());
+    entity.setId(createId(entity, "SupplierID", "Suppliers", "3"));
+    supplierList.add(entity);
+
+    entity = new Entity();
+    entity.addProperty(new Property(null, "SupplierID", ValueType.PRIMITIVE, 5));
+    entity.addProperty(new Property(null, "CompanyName", ValueType.PRIMITIVE, "Sharp"));
+    entity.addProperty(new Property(null, "Fax", ValueType.PRIMITIVE,
+        "(12345) 1210"));
+    p1 = new Property(null, "City", ValueType.PRIMITIVE, "Osaka");
+    p2 = new Property(null, "Country", ValueType.PRIMITIVE, "Japan");
+    complexValue = new ComplexValue();
+    complexValue.getValue().add(p1);
+    complexValue.getValue().add(p2);
+    
+    entity.addProperty(new Property(null, "Address", ValueType.COMPLEX, complexValue));
+    entity.setType(DemoEdmProvider.ET_SUPPLIER_FQN.getFullQualifiedNameAsString());
+    entity.setId(createId(entity, "SupplierID", "Suppliers", "4"));
+    supplierList.add(entity);
+
+    entity = new Entity();
+    entity.addProperty(new Property(null, "SupplierID", ValueType.PRIMITIVE, 6));
+    entity.addProperty(new Property(null, "CompanyName", ValueType.PRIMITIVE, "Wonder World"));
+    entity.addProperty(new Property(null, "Fax", ValueType.PRIMITIVE,
+        "43844115"));
+    p1 = new Property(null, "City", ValueType.PRIMITIVE, "Zürich");
+    p2 = new Property(null, "Country", ValueType.PRIMITIVE, "Switzerland");
+    complexValue = new ComplexValue();
+    complexValue.getValue().add(p1);
+    complexValue.getValue().add(p2);
+    
+    entity.addProperty(new Property(null, "Address", ValueType.COMPLEX, complexValue));
+    entity.setType(DemoEdmProvider.ET_SUPPLIER_FQN.getFullQualifiedNameAsString());
+    entity.setId(createId(entity, "SupplierID", "Suppliers", "5"));
+    supplierList.add(entity);
+    
+    entity = new Entity();
+    entity.addProperty(new Property(null, "SupplierID", ValueType.PRIMITIVE, 7));
+    entity.addProperty(new Property(null, "CompanyName", ValueType.PRIMITIVE, "Touch International"));
+    entity.addProperty(new Property(null, "Fax", ValueType.PRIMITIVE,
+        "43847115"));
+    p1 = new Property(null, "City", ValueType.PRIMITIVE, "Austin");
+    p2 = new Property(null, "Country", ValueType.PRIMITIVE, "USA");
+    complexValue = new ComplexValue();
+    complexValue.getValue().add(p1);
+    complexValue.getValue().add(p2);
+    
+    entity.addProperty(new Property(null, "Address", ValueType.COMPLEX, complexValue));
+    entity.setType(DemoEdmProvider.ET_SUPPLIER_FQN.getFullQualifiedNameAsString());
+    entity.setId(createId(entity, "SupplierID", "Suppliers", "6"));
+    supplierList.add(entity);
+  }
 
   private URI createId(Entity entity, String idPropertyName) {
     return createId(entity, idPropertyName, null);
@@ -278,12 +437,29 @@ public class Storage {
       throw new ODataRuntimeException("Unable to create (Atom) id for entity: " + entity, e);
     }
   }
+  
+  private URI createId(Entity entity, String idPropertyName, String navigationName, String sourceId) {
+    try {
+      StringBuilder sb = new StringBuilder(getEntitySetName(entity)).append("(");
+      final Property property = entity.getProperty(idPropertyName);
+      sb.append(sourceId).append(")");
+      if(navigationName != null) {
+        sb.append("/").append(navigationName);
+        sb.append("(").append(property.asPrimitive()).append(")");
+      }
+      return new URI(sb.toString());
+    } catch (URISyntaxException e) {
+      throw new ODataRuntimeException("Unable to create (Atom) id for entity: " + entity, e);
+    }
+  }
 
   private String getEntitySetName(Entity entity) {
     if(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString().equals(entity.getType())) {
       return DemoEdmProvider.ES_CATEGORIES_NAME;
     } else if(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString().equals(entity.getType())) {
       return DemoEdmProvider.ES_PRODUCTS_NAME;
+    } else if(DemoEdmProvider.ET_SUPPLIER_FQN.getFullQualifiedNameAsString().equals(entity.getType())) {
+      return DemoEdmProvider.ES_PRODUCTS_NAME;
     }
     return entity.getType();
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b86aa5d9/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java b/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
index 8ce9bac..5599ecb 100755
--- a/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
+++ b/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
@@ -25,6 +25,7 @@ import java.util.List;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
+import org.apache.olingo.commons.api.edm.provider.CsdlComplexType;
 import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
 import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo;
 import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet;
@@ -50,10 +51,17 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
 
   public static final String ET_CATEGORY_NAME = "Category";
   public static final FullQualifiedName ET_CATEGORY_FQN = new FullQualifiedName(NAMESPACE, ET_CATEGORY_NAME);
+  
+  public static final String ET_SUPPLIER_NAME = "Supplier";
+  public static final FullQualifiedName ET_SUPPLIER_FQN = new FullQualifiedName(NAMESPACE, ET_SUPPLIER_NAME);
+  
+  public static final String CT_ADDRESS_NAME = "Address";
+  public static final FullQualifiedName CT_ADDRESS_FQN = new FullQualifiedName(NAMESPACE, CT_ADDRESS_NAME);
 
   // Entity Set Names
   public static final String ES_PRODUCTS_NAME = "Products";
   public static final String ES_CATEGORIES_NAME = "Categories";
+  public static final String ES_SUPPLIERS_NAME = "Suppliers";
 
   @Override
   public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) {
@@ -77,8 +85,11 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
       // navigation property: many-to-one, null not allowed (product must have a category)
       CsdlNavigationProperty navProp = new CsdlNavigationProperty().setName("Category")
           .setType(ET_CATEGORY_FQN).setNullable(false).setPartner("Products");
+      CsdlNavigationProperty contNavProp = new CsdlNavigationProperty().setName("Suppliers")
+          .setType(ET_SUPPLIER_FQN).setContainsTarget(true).setCollection(true);
       List<CsdlNavigationProperty> navPropList = new ArrayList<CsdlNavigationProperty>();
       navPropList.add(navProp);
+      navPropList.add(contNavProp);
 
       // configure EntityType
       entityType = new CsdlEntityType();
@@ -110,11 +121,47 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
       entityType.setProperties(Arrays.asList(id, name));
       entityType.setKey(Arrays.asList(propertyRef));
       entityType.setNavigationProperties(navPropList);
+    } else if (entityTypeName.equals(ET_SUPPLIER_FQN)) {
+      // create EntityType properties
+      CsdlProperty supplierId = new CsdlProperty().setName("SupplierID")
+          .setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
+      CsdlProperty companyName = new CsdlProperty().setName("CompanyName")
+          .setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
+      CsdlProperty fax = new CsdlProperty().setName("Fax")
+          .setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
+      CsdlProperty address = new CsdlProperty().setName(CT_ADDRESS_NAME)
+          .setType(CT_ADDRESS_FQN);
+
+      // create PropertyRef for Key element
+      CsdlPropertyRef propertyRef = new CsdlPropertyRef();
+      propertyRef.setName("SupplierID");
+
+      // configure EntityType
+      entityType = new CsdlEntityType();
+      entityType.setName(ET_SUPPLIER_NAME);
+      entityType.setProperties(Arrays.asList(supplierId, companyName, fax, address));
+      entityType.setKey(Arrays.asList(propertyRef));
     }
 
     return entityType;
 
   }
+  
+  @Override
+  public CsdlComplexType getComplexType(final FullQualifiedName complexTypeName) {
+    CsdlComplexType complexType = null;
+    if (complexTypeName.equals(CT_ADDRESS_FQN)) {
+      complexType = new CsdlComplexType().setName(CT_ADDRESS_NAME)
+          .setProperties(Arrays.asList(
+              new CsdlProperty()
+                  .setName("City")
+                  .setType(EdmPrimitiveTypeKind.String.getFullQualifiedName()),
+              new CsdlProperty()
+              .setName("Country")
+              .setType(EdmPrimitiveTypeKind.String.getFullQualifiedName())));
+    }
+    return complexType;
+  }
 
   @Override
   public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) {
@@ -180,8 +227,14 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
     List<CsdlEntityType> entityTypes = new ArrayList<CsdlEntityType>();
     entityTypes.add(getEntityType(ET_PRODUCT_FQN));
     entityTypes.add(getEntityType(ET_CATEGORY_FQN));
+    entityTypes.add(getEntityType(ET_SUPPLIER_FQN));
     schema.setEntityTypes(entityTypes);
 
+    // add Complex Types
+    List<CsdlComplexType> complexTypes = new ArrayList<CsdlComplexType>();
+    complexTypes.add(getComplexType(CT_ADDRESS_FQN));
+    schema.setComplexTypes(complexTypes);
+    
     // add EntityContainer
     schema.setEntityContainer(getEntityContainer());
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b86aa5d9/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java b/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java
index 058dd83..018931f 100755
--- a/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java
+++ b/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java
@@ -81,6 +81,7 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
 
     EdmEntitySet responseEdmEntitySet = null; // we'll need this to build the ContextURL
     EntityCollection responseEntityCollection = null; // we'll need this to set the response body
+    EdmEntityType responseEdmEntityType = null;
 
     // 1st retrieve the requested EntitySet from the uriInfo (representation of the parsed URI)
     List<UriResource> resourceParts = uriInfo.getUriResourceParts();
@@ -107,8 +108,13 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
         UriResourceNavigation uriResourceNavigation = (UriResourceNavigation) lastSegment;
         EdmNavigationProperty edmNavigationProperty = uriResourceNavigation.getProperty();
         EdmEntityType targetEntityType = edmNavigationProperty.getType();
-        // from Categories(1) to Products
-        responseEdmEntitySet = Util.getNavigationTargetEntitySet(startEdmEntitySet, edmNavigationProperty);
+        if (!edmNavigationProperty.containsTarget()) {
+       // from Categories(1) to Products
+          responseEdmEntitySet = Util.getNavigationTargetEntitySet(startEdmEntitySet, edmNavigationProperty);
+        } else {
+          responseEdmEntitySet = startEdmEntitySet;
+          responseEdmEntityType = targetEntityType;
+        }
 
         // 2nd: fetch the data from backend
         // first fetch the entity where the first segment of the URI points to
@@ -130,13 +136,20 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
           HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
     }
 
+    ContextURL contextUrl = null;
+    EdmEntityType edmEntityType = null;
     // 3rd: create and configure a serializer
-    ContextURL contextUrl = ContextURL.with().entitySet(responseEdmEntitySet).build();
+    if (isContNav(uriInfo)) {
+      contextUrl = ContextURL.with().entitySetOrSingletonOrType(request.getRawODataPath()).build();
+      edmEntityType = responseEdmEntityType;
+    } else {
+      contextUrl = ContextURL.with().entitySet(responseEdmEntitySet).build(); 
+      edmEntityType = responseEdmEntitySet.getEntityType();
+    }
     final String id = request.getRawBaseUri() + "/" + responseEdmEntitySet.getName();
     EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with()
         .contextURL(contextUrl).id(id).build();
-    EdmEntityType edmEntityType = responseEdmEntitySet.getEntityType();
-
+    
     ODataSerializer serializer = odata.createSerializer(responseFormat);
     SerializerResult serializerResult = serializer.entityCollection(this.srvMetadata, edmEntityType,
         responseEntityCollection, opts);
@@ -147,4 +160,17 @@ public class DemoEntityCollectionProcessor implements EntityCollectionProcessor
     response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
   }
 
+  private boolean isContNav(UriInfo uriInfo) {
+    List<UriResource> resourceParts = uriInfo.getUriResourceParts();
+    for (UriResource resourcePart : resourceParts) {
+      if (resourcePart instanceof UriResourceNavigation) {
+        UriResourceNavigation navResource = (UriResourceNavigation) resourcePart;
+        if (navResource.getProperty().containsTarget()) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b86aa5d9/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java b/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
index fba514a..1cf75c1 100755
--- a/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
+++ b/samples/tutorials/p4_navigation/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
@@ -109,8 +109,13 @@ public class DemoEntityProcessor implements EntityProcessor {
         UriResourceNavigation uriResourceNavigation = (UriResourceNavigation) navSegment;
         EdmNavigationProperty edmNavigationProperty = uriResourceNavigation.getProperty();
         responseEdmEntityType = edmNavigationProperty.getType();
-        // contextURL displays the last segment
-        responseEdmEntitySet = Util.getNavigationTargetEntitySet(startEdmEntitySet, edmNavigationProperty);
+        if (!edmNavigationProperty.containsTarget()) {
+       // contextURL displays the last segment
+          responseEdmEntitySet = Util.getNavigationTargetEntitySet(startEdmEntitySet, edmNavigationProperty);
+        } else {
+          responseEdmEntitySet = startEdmEntitySet;
+        }
+        
 
         // 2nd: fetch the data from backend.
         // e.g. for the URI: Products(1)/Category we have to find the correct Category entity
@@ -141,7 +146,14 @@ public class DemoEntityProcessor implements EntityProcessor {
     }
 
     // 3. serialize
-    ContextURL contextUrl = ContextURL.with().entitySet(responseEdmEntitySet).suffix(Suffix.ENTITY).build();
+    ContextURL contextUrl = null;
+    if (isContNav(uriInfo)) {
+      contextUrl = ContextURL.with().entitySetOrSingletonOrType(request.getRawODataPath()).
+          suffix(Suffix.ENTITY).build();
+    } else {
+      contextUrl = ContextURL.with().entitySet(responseEdmEntitySet).suffix(Suffix.ENTITY).build();
+    }
+    
     EntitySerializerOptions opts = EntitySerializerOptions.with().contextURL(contextUrl).build();
 
     ODataSerializer serializer = this.odata.createSerializer(responseFormat);
@@ -153,6 +165,19 @@ public class DemoEntityProcessor implements EntityProcessor {
     response.setStatusCode(HttpStatusCode.OK.getStatusCode());
     response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
   }
+  
+  private boolean isContNav(UriInfo uriInfo) {
+    List<UriResource> resourceParts = uriInfo.getUriResourceParts();
+    for (UriResource resourcePart : resourceParts) {
+      if (resourcePart instanceof UriResourceNavigation) {
+        UriResourceNavigation navResource = (UriResourceNavigation) resourcePart;
+        if (navResource.getProperty().containsTarget()) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
 
   /*
    * These processor methods are not handled in this tutorial