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/05/09 12:41:45 UTC

olingo-odata4 git commit: [OLINGO-1073] Collections with derived complex types

Repository: olingo-odata4
Updated Branches:
  refs/heads/master 4a51d1642 -> 32ff14fe7


[OLINGO-1073] Collections with derived complex types

wrong odata.type

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


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

Branch: refs/heads/master
Commit: 32ff14fe788b5dbd80ffd61c1e83e460427bae9e
Parents: 4a51d16
Author: i050510 <ra...@sap.com>
Authored: Fri May 5 10:20:56 2017 +0530
Committer: Christian Amend <ch...@sap.com>
Committed: Tue May 9 14:37:42 2017 +0200

----------------------------------------------------------------------
 .../olingo/fit/tecsvc/client/BasicITCase.java   |   4 +-
 .../OdataTypesInBaseAndDerivedTypes.json        |   4 +-
 .../core/serialization/AtomDeserializer.java    |  18 +-
 .../core/serialization/AtomSerializer.java      |   8 +-
 .../core/serialization/JsonDeserializer.java    |  13 +
 .../core/serialization/JsonSerializer.java      |   4 +-
 .../core/serialization/ODataBinderImpl.java     |  14 +-
 .../org/apache/olingo/client/core/AtomTest.java | 209 +++++++++++++++++
 .../org/apache/olingo/client/core/JSONTest.java | 235 +++++++++++++++++++
 .../apache/olingo/client/core/olingo1073.json   |  17 ++
 .../apache/olingo/client/core/olingo1073_1.json |  66 ++++++
 .../apache/olingo/client/core/olingo1073_1.xml  |  65 +++++
 .../apache/olingo/client/core/olingo1073_2.json |  87 +++++++
 .../apache/olingo/client/core/olingo1073_2.xml  |  78 ++++++
 .../olingo/commons/api/data/ComplexValue.java   |  18 ++
 15 files changed, 828 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
index 1e5cce3..3d33ee9 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
@@ -1598,9 +1598,9 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
         getProperties().size());
     assertEquals(1, entity.getNavigationLinks().get(0).asInlineEntitySet().getEntitySet().getEntities().get(1).
         getProperties().size());
-    assertEquals("olingo.odata.test1.ETBase", entity.getNavigationLinks().get(0).asInlineEntitySet().getEntitySet().
+    assertEquals("#olingo.odata.test1.ETBase", entity.getNavigationLinks().get(0).asInlineEntitySet().getEntitySet().
         getEntities().get(0).getTypeName().toString());
-    assertEquals("olingo.odata.test1.ETBase", entity.getNavigationLinks().get(0).asInlineEntitySet().getEntitySet().
+    assertEquals("#olingo.odata.test1.ETBase", entity.getNavigationLinks().get(0).asInlineEntitySet().getEntitySet().
         getEntities().get(1).getTypeName().toString());
     assertEquals("olingo.odata.test1.ETAllPrim", entity.getTypeName().toString());
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/fit/src/test/resources/OdataTypesInBaseAndDerivedTypes.json
----------------------------------------------------------------------
diff --git a/fit/src/test/resources/OdataTypesInBaseAndDerivedTypes.json b/fit/src/test/resources/OdataTypesInBaseAndDerivedTypes.json
index 88ae6b5..d64d26c 100644
--- a/fit/src/test/resources/OdataTypesInBaseAndDerivedTypes.json
+++ b/fit/src/test/resources/OdataTypesInBaseAndDerivedTypes.json
@@ -20,13 +20,13 @@
   "NavPropertyETTwoPrimMany@odata.type": "#Collection(olingo.odata.test1.ETTwoPrim)",
   "NavPropertyETTwoPrimMany": [
     {
-      "@odata.type": "olingo.odata.test1.ETBase",
+      "@odata.type": "#olingo.odata.test1.ETBase",
       "PropertyInt16": -365,
       "PropertyString": "Test String2",
       "AdditionalPropertyString_5": "ABC"
     },
     {
-      "@odata.type": "olingo.odata.test1.ETBase",
+      "@odata.type": "#olingo.odata.test1.ETBase",
       "AdditionalPropertyString_5": "ABC"
     }
   ]

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomDeserializer.java
index 0fa1736..6930f87 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomDeserializer.java
@@ -94,7 +94,7 @@ public class AtomDeserializer implements ODataDeserializer {
   protected static final XMLInputFactory FACTORY = new InputFactoryImpl();
 
   private final AtomGeoValueDeserializer geoDeserializer;
-
+  
   protected XMLEventReader getReader(final InputStream input) throws XMLStreamException {
     FACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", false);
     FACTORY.setProperty("javax.xml.stream.isReplacingEntityReferences", false);
@@ -219,6 +219,13 @@ public class AtomDeserializer implements ODataDeserializer {
         case COMPLEX:
           final Object complexValue = fromComplexOrEnum(reader, event.asStartElement());
           valueType = ValueType.COLLECTION_COMPLEX;
+          final Attribute typeAttr = event.asStartElement().getAttributeByName(typeQName);
+          final String typeAttrValue = typeAttr == null ? null : typeAttr.getValue();
+          final EdmTypeInfo typeInfoEle = StringUtils.isBlank(typeAttrValue) ? null :
+            new EdmTypeInfo.Builder().setTypeExpression(typeAttrValue).build();
+          if (typeInfoEle != null) {
+            ((ComplexValue)complexValue).setTypeName(typeInfoEle.external());
+          }
           values.add(complexValue);
           break;
 
@@ -287,7 +294,7 @@ public class AtomDeserializer implements ODataDeserializer {
       throws XMLStreamException, EdmPrimitiveTypeException {
 
     final Property property = new Property();
-
+    
     if (propertyValueQName.equals(start.getName())) {
       // retrieve name from context
       final Attribute context = start.getAttributeByName(contextQName);
@@ -297,9 +304,8 @@ public class AtomDeserializer implements ODataDeserializer {
     } else {
       property.setName(start.getName().getLocalPart());
     }
-
     valuable(property, reader, start);
-
+    
     return property;
   }
 
@@ -330,6 +336,10 @@ public class AtomDeserializer implements ODataDeserializer {
 
       case COMPLEX:
         final Object complexValue = fromComplexOrEnum(reader, start);
+        if (typeInfo != null && complexValue instanceof ComplexValue && 
+            start.getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_TERM)) == null) {
+          ((ComplexValue)complexValue).setTypeName(typeInfo.external());
+        }
         valuable.setValue(complexValue instanceof ComplexValue ? ValueType.COMPLEX : ValueType.ENUM,
             complexValue);
         break;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomSerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomSerializer.java
index ad4a14e..0b8dce7 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomSerializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomSerializer.java
@@ -127,6 +127,12 @@ public class AtomSerializer implements ODataSerializer {
       collection(writer, valueType.getBaseType(), kind, (List<?>) value);
       break;
     case COMPLEX:
+      if (((ComplexValue) value).getTypeName() != null) {
+        EdmTypeInfo typeInfo = new EdmTypeInfo.Builder().
+            setTypeExpression(((ComplexValue) value).getTypeName()).build();
+        writer.writeAttribute(Constants.PREFIX_METADATA, Constants.NS_METADATA,
+            Constants.ATTR_TYPE, typeInfo.external());
+      }
       for (Property property : ((ComplexValue) value).getValue()) {
         property(writer, property, false);
       }
@@ -148,7 +154,7 @@ public class AtomSerializer implements ODataSerializer {
     }
 
     EdmTypeInfo typeInfo = null;
-    if (property.getType() != null) {
+    if (property.getType() != null && !property.getValueType().name().equalsIgnoreCase("COMPLEX")) {
       typeInfo = new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build();
       if (!EdmPrimitiveTypeKind.String.getFullQualifiedName().toString().equals(typeInfo.internal())) {
         writer.writeAttribute(Constants.PREFIX_METADATA, Constants.NS_METADATA,

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java
index 3e06443..ec896bb 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java
@@ -333,7 +333,17 @@ public class JsonDeserializer implements ODataDeserializer {
           values.add(child.asText());
         }
       } else if (child.isContainerNode()) {
+        EdmTypeInfo childType = null;
+        if (child.has(Constants.JSON_TYPE)) {
+          String typeName = child.get(Constants.JSON_TYPE).asText();
+          childType = typeName == null ? null
+              : new EdmTypeInfo.Builder().setTypeExpression(typeName).build();
+          ((ObjectNode) child).remove(Constants.JSON_TYPE);
+        }
         final Object value = fromComplex((ObjectNode) child, codec);
+        if (childType != null) {
+          ((ComplexValue)value).setTypeName(childType.external());
+        }
         valueType = ValueType.COLLECTION_COMPLEX;
         values.add(value);
       }
@@ -368,6 +378,9 @@ public class JsonDeserializer implements ODataDeserializer {
         ((ObjectNode) node).remove(Constants.JSON_TYPE);
       }
       final Object value = fromComplex((ObjectNode) node, codec);
+      if (value instanceof ComplexValue) {
+        ((ComplexValue)value).setTypeName(valuable.getType());
+      }
       valuable.setValue(ValueType.COMPLEX, value);
       break;
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java
index 44a51d9..90aba4f 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java
@@ -241,7 +241,7 @@ public class JsonSerializer implements ODataSerializer {
       final ValueType valueType, final List<?> value)
           throws IOException, EdmPrimitiveTypeException {
 
-    final EdmTypeInfo itemTypeInfo = typeInfo == null ?
+    EdmTypeInfo itemTypeInfo = typeInfo == null ?
         null :
         new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
 
@@ -265,6 +265,8 @@ public class JsonSerializer implements ODataSerializer {
 
       case COLLECTION_COMPLEX:
         final ComplexValue complexItem2 = (ComplexValue) item;
+        itemTypeInfo = complexItem2.getTypeName() == null ? 
+            itemTypeInfo : new EdmTypeInfo.Builder().setTypeExpression(complexItem2.getTypeName()).build();
         complexValue(jgen, itemTypeInfo, complexItem2.getValue(), complexItem2);
         break;
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java
index 77764a5..deb58fa 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java
@@ -350,6 +350,7 @@ public class ODataBinderImpl implements ODataBinder {
       lcValueResource.getValue().addAll(complexProperties);
       annotations(value.asComplex(), lcValueResource);
       links(value.asComplex(), lcValueResource);
+      lcValueResource.setTypeName(value.asComplex().getTypeName());
       valueResource = lcValueResource;
 
     } else if (value.isCollection()) {
@@ -581,7 +582,11 @@ public class ODataBinderImpl implements ODataBinder {
       EntityCollection inlineEntitySet = new EntityCollection();
       for (final Object inlined : property.asCollection()) {
         Entity inlineEntity = new Entity();
-        inlineEntity.setType(propertyTypeName);
+        if (inlined instanceof ComplexValue && ((ComplexValue) inlined).getTypeName() != null) {
+          inlineEntity.setType(((ComplexValue) inlined).getTypeName());
+        } else {
+          inlineEntity.setType(propertyTypeName);
+        }
         inlineEntity.getProperties().addAll(((ComplexValue) inlined).getValue());
         copyAnnotations(inlineEntity, (ComplexValue) inlined);
         inlineEntitySet.getEntities().add(inlineEntity);
@@ -815,7 +820,7 @@ public class ODataBinderImpl implements ODataBinder {
     return property;
   }
 
-  protected ClientValue getODataValue(final FullQualifiedName type,
+  protected ClientValue getODataValue(FullQualifiedName type,
       final Valuable valuable, final URI contextURL, final String metadataETag) {
 
     // fixes enum values treated as primitive when no type information is available
@@ -834,6 +839,11 @@ public class ODataBinderImpl implements ODataBinder {
       for (Object _value : valuable.asCollection()) {
         final Property fake = new Property();
         fake.setValue(valuable.getValueType().getBaseType(), _value);
+        String typeName = null;
+        if (_value instanceof ComplexValue) {
+          typeName = ((ComplexValue) _value).getTypeName();
+          type = typeName == null? type : new FullQualifiedName(typeName);
+        }
         value.asCollection().add(getODataValue(type, fake, contextURL, metadataETag));
       }
     } else if (valuable.isEnum()) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java
index ba20144..8f70768 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java
@@ -18,10 +18,14 @@
  */
 package org.apache.olingo.client.core;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.ByteArrayInputStream;
+import java.io.InputStream;
 import java.io.StringWriter;
+import java.net.URI;
 
 import javax.xml.transform.Source;
 import javax.xml.transform.Transformer;
@@ -30,8 +34,18 @@ import javax.xml.transform.stream.StreamResult;
 import javax.xml.transform.stream.StreamSource;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.olingo.client.api.data.ResWrap;
+import org.apache.olingo.client.api.domain.ClientCollectionValue;
+import org.apache.olingo.client.api.domain.ClientComplexValue;
+import org.apache.olingo.client.api.domain.ClientEntity;
+import org.apache.olingo.client.api.domain.ClientValue;
+import org.apache.olingo.client.core.serialization.AtomDeserializer;
+import org.apache.olingo.commons.api.data.ComplexValue;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.custommonkey.xmlunit.Diff;
+import org.junit.Test;
 
 public class AtomTest extends JSONTest {
 
@@ -72,4 +86,199 @@ public class AtomTest extends JSONTest {
     // no test
   }
 
+  @Test
+  public void issue1OLINGO1073() throws Exception {
+    final ClientEntity message = client.getObjectFactory().
+        newEntity(new FullQualifiedName("Microsoft.OData.SampleService.Models.TripPin.Person"));
+    
+    final ClientComplexValue cityComplexType = getCityComplexType();
+    
+    final ClientComplexValue locationComplexType = client.getObjectFactory().
+        newComplexValue("Microsoft.OData.SampleService.Models.TripPin.Location");
+    locationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln.")));
+    locationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType));
+
+    final ClientComplexValue eventLocationComplexType = client.getObjectFactory().
+        newComplexValue("Microsoft.OData.SampleService.Models.TripPin.EventLocation");
+    eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("BuildingInfo",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12.")));
+    eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12.")));
+    eventLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType));
+    
+    final ClientComplexValue airportLocationComplexType = client.getObjectFactory().
+        newComplexValue("Microsoft.OData.SampleService.Models.TripPin.AirportLocation");
+    airportLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln123.")));
+    airportLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType));
+    
+    final ClientCollectionValue<ClientValue> collectionAddressInfo = client.getObjectFactory().
+        newCollectionValue("Microsoft.OData.SampleService.Models.TripPin.Location");
+    collectionAddressInfo.add(locationComplexType);
+    collectionAddressInfo.add(eventLocationComplexType);
+    collectionAddressInfo.add(airportLocationComplexType);
+    
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("UserName", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("russellwhyte")));
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("FirstName", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell")));
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("LastName", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("Whyte")));
+    
+    final ClientCollectionValue<ClientValue> emailCollectionValue = client.getObjectFactory().
+        newCollectionValue("String");
+    emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell@example.com"));
+    emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell@contoso.com"));
+    message.getProperties().add(client.getObjectFactory().newCollectionProperty("Emails", emailCollectionValue));
+    
+    message.getProperties().add(client.getObjectFactory().newCollectionProperty("AddressInfo", collectionAddressInfo));
+    message.getProperties().add(client.getObjectFactory().newEnumProperty("Gender", 
+        client.getObjectFactory().newEnumValue(
+            "Microsoft.OData.SampleService.Models.TripPin.PersonGender", "Male")));
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("Concurrency", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildInt64(Long.valueOf("636293755917400747"))));
+    message.setId(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/"
+        + "TripPinServiceRW/People('russellwhyte')"));
+    message.setETag("W/\"08D491CCBE417AAB\"");
+    message.setEditLink(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/"
+        + "TripPinServiceRW/People('russellwhyte')"));
+
+    String actual = IOUtils.toString(client.getWriter().writeEntity(message, ContentType.APPLICATION_ATOM_XML));
+    actual = actual.substring(actual.indexOf("<entry"));
+    assertNotNull(actual);
+    String expected = IOUtils.toString(getClass().getResourceAsStream("olingo1073_1.xml"));
+    expected = expected.substring(expected.indexOf("<entry"));
+    expected = expected.trim().replace("\n", "").replace("\r", "").replace("\t", "");
+    assertEquals(expected, actual);
+  }
+  
+
+  /**
+   * @return ClientComplexValue
+   */
+  private ClientComplexValue getCityComplexType() {
+    final ClientComplexValue cityComplexType = client.getObjectFactory().
+        newComplexValue("Microsoft.OData.SampleService.Models.TripPin.City");
+    cityComplexType.add(client.getObjectFactory().newPrimitiveProperty("CountryRegion",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("United States")));
+    cityComplexType.add(client.getObjectFactory().newPrimitiveProperty("Name",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("Boise")));
+    cityComplexType.add(client.getObjectFactory().newPrimitiveProperty("Region",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("ID")));
+    return cityComplexType;
+  }
+  
+  @Test
+  public void issue2OLINGO1073() throws Exception {
+    final ClientEntity message = client.getObjectFactory().
+        newEntity(new FullQualifiedName("Microsoft.OData.SampleService.Models.TripPin.Person"));
+    
+    final ClientComplexValue cityComplexType = getCityComplexType();
+    
+    final ClientComplexValue locationComplexType = client.getObjectFactory().
+        newComplexValue("Microsoft.OData.SampleService.Models.TripPin.Location");
+    locationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln.")));
+    locationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType));
+
+    final ClientComplexValue eventLocationComplexType = client.getObjectFactory().
+        newComplexValue("Microsoft.OData.SampleService.Models.TripPin.EventLocation");
+    eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("BuildingInfo",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12.")));
+    eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12.")));
+    eventLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType));
+    
+    final ClientComplexValue airportLocationComplexType = client.getObjectFactory().
+        newComplexValue("Microsoft.OData.SampleService.Models.TripPin.AirportLocation");
+    airportLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln123.")));
+    airportLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType));
+    
+    final ClientCollectionValue<ClientValue> collectionAddressInfo = client.getObjectFactory().
+        newCollectionValue("Microsoft.OData.SampleService.Models.TripPin.Location");
+    collectionAddressInfo.add(locationComplexType);
+    collectionAddressInfo.add(eventLocationComplexType);
+    collectionAddressInfo.add(airportLocationComplexType);
+    
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("UserName", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("russellwhyte")));
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("FirstName", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell")));
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("LastName", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("Whyte")));
+    
+    final ClientCollectionValue<ClientValue> emailCollectionValue = client.getObjectFactory().
+        newCollectionValue("String");
+    emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell@example.com"));
+    emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell@contoso.com"));
+    message.getProperties().add(client.getObjectFactory().newCollectionProperty("Emails", emailCollectionValue));
+    
+    message.getProperties().add(client.getObjectFactory().newCollectionProperty("AddressInfo", collectionAddressInfo));
+    message.getProperties().add(client.getObjectFactory().newEnumProperty("Gender", 
+        client.getObjectFactory().newEnumValue(
+            "Microsoft.OData.SampleService.Models.TripPin.PersonGender", "Male")));
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("Concurrency", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildInt64(Long.valueOf("636293755917400747"))));
+    message.setId(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/"
+        + "TripPinServiceRW/People('russellwhyte')"));
+    message.setETag("W/\"08D491CCBE417AAB\"");
+    message.setEditLink(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/"
+        + "TripPinServiceRW/People('russellwhyte')"));
+
+    InputStream inputStream = client.getWriter().writeEntity(message, ContentType.APPLICATION_ATOM_XML);
+    ResWrap<Entity> entity = new AtomDeserializer().toEntity(inputStream);
+    assertNotNull(entity);
+    assertEquals(7, entity.getPayload().getProperties().size());
+    assertEquals(3, entity.getPayload().getProperty("AddressInfo").asCollection().size());
+    assertEquals("#Microsoft.OData.SampleService.Models.TripPin.Location", 
+        ((ComplexValue)entity.getPayload().getProperty("AddressInfo").asCollection().get(0)).getTypeName());
+    assertEquals("#Microsoft.OData.SampleService.Models.TripPin.EventLocation", 
+        ((ComplexValue)entity.getPayload().getProperty("AddressInfo").asCollection().get(1)).getTypeName());
+    assertEquals("#Microsoft.OData.SampleService.Models.TripPin.AirportLocation", 
+        ((ComplexValue)entity.getPayload().getProperty("AddressInfo").asCollection().get(2)).getTypeName());
+    assertEquals("Collection(Microsoft.OData.SampleService.Models.TripPin.Location)", 
+        entity.getPayload().getProperty("AddressInfo").getType());
+  }
+  
+  @Test
+  public void issue3OLINGO1073_WithAnnotations() throws Exception {
+    InputStream inputStream = getClass().getResourceAsStream(
+        "olingo1073_2" + "." + getSuffix(ContentType.APPLICATION_ATOM_XML));
+    ClientEntity entity = client.getReader().readEntity(inputStream, ContentType.APPLICATION_ATOM_XML);
+    assertNotNull(entity);
+    assertEquals(7, entity.getProperties().size());
+    assertEquals(1, entity.getAnnotations().size());
+    assertEquals("com.contoso.PersonalInfo.PhoneNumbers", entity.getAnnotations().get(0).getTerm());
+    assertEquals(2, entity.getAnnotations().get(0).getCollectionValue().size());
+    
+    assertEquals("com.contoso.display.style", entity.getProperty("LastName").
+        getAnnotations().get(0).getTerm());
+    assertEquals(2, entity.getProperty("LastName").
+        getAnnotations().get(0).getComplexValue().asComplex().asJavaMap().size());
+    
+    assertEquals(3, entity.getProperty("AddressInfo").getCollectionValue().asCollection().size());
+    assertEquals("Collection(Microsoft.OData.SampleService.Models.TripPin.Location)", 
+        entity.getProperty("AddressInfo").getCollectionValue().asCollection().getTypeName());
+    assertEquals(true, entity.getProperty("AddressInfo").getCollectionValue().isCollection());
+    ClientCollectionValue<ClientValue> collectionValue = entity.getProperty("AddressInfo").
+        getCollectionValue().asCollection();
+    int i = 0;
+    for (ClientValue _value : collectionValue) {
+      if (i == 0) {
+        assertEquals("#Microsoft.OData.SampleService.Models.TripPin.Location", _value.getTypeName());
+        assertEquals(2, _value.asComplex().asJavaMap().size());
+        assertEquals("Microsoft.OData.SampleService.Models.TripPin.City", 
+            _value.asComplex().get("City").getComplexValue().getTypeName());
+      } else if (i == 1) {
+        assertEquals("#Microsoft.OData.SampleService.Models.TripPin.EventLocation", _value.getTypeName());
+        assertEquals(3, _value.asComplex().asJavaMap().size());
+      } else if (i == 2) {
+        assertEquals("#Microsoft.OData.SampleService.Models.TripPin.AirportLocation", _value.getTypeName());
+        assertEquals(3, _value.asComplex().asJavaMap().size());
+      }
+      i++;
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java
index a276c4f..caef339 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java
@@ -23,19 +23,25 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.ByteArrayInputStream;
+import java.io.InputStream;
 import java.io.StringWriter;
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.olingo.client.api.data.ResWrap;
 import org.apache.olingo.client.api.domain.ClientCollectionValue;
 import org.apache.olingo.client.api.domain.ClientComplexValue;
 import org.apache.olingo.client.api.domain.ClientEntity;
 import org.apache.olingo.client.api.domain.ClientValue;
+import org.apache.olingo.client.core.serialization.JsonDeserializer;
 import org.apache.olingo.commons.api.Constants;
+import org.apache.olingo.commons.api.data.ComplexValue;
 import org.apache.olingo.commons.api.data.Delta;
+import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.format.ContentType;
@@ -247,4 +253,233 @@ public class JSONTest extends AbstractTest {
     final ObjectNode actualNode = (ObjectNode) OBJECT_MAPPER.readTree(new ByteArrayInputStream(actual.getBytes()));
     assertEquals(expected, actualNode);
   }
+  
+  @Test
+  public void issue1OLINGO1073() throws Exception {
+    final ClientEntity message = client.getObjectFactory().
+        newEntity(new FullQualifiedName("Microsoft.Exchange.Services.OData.Model.Entity"));
+    
+    final ClientComplexValue complType1 = client.getObjectFactory().
+        newComplexValue("Microsoft.Exchange.Services.OData.Model.ComplexType1");
+    complType1.add(client.getObjectFactory().newPrimitiveProperty("Name1",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("challen_olingo_client")));
+    complType1.add(client.getObjectFactory().newPrimitiveProperty("Address1",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("challenh@microsoft.com")));
+
+    final ClientComplexValue complType2 = client.getObjectFactory().
+        newComplexValue("Microsoft.Exchange.Services.OData.Model.ComplexType2");
+    complType2.add(client.getObjectFactory().newPrimitiveProperty("Name2",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("challen_olingo_client")));
+    complType2.add(client.getObjectFactory().newPrimitiveProperty("Address2",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("challenh@microsoft.com")));
+    final ClientCollectionValue<ClientValue> toRecipients = client.getObjectFactory().
+        newCollectionValue("Microsoft.Exchange.Services.OData.Model.Recipient");
+    toRecipients.add(complType1);
+    toRecipients.add(complType2);
+    message.getProperties().add(client.getObjectFactory().newCollectionProperty("ToRecipients", toRecipients));
+
+
+    final String actual = IOUtils.toString(client.getWriter().writeEntity(message, ContentType.JSON));
+    final JsonNode expected =
+        OBJECT_MAPPER.readTree(IOUtils.toString(getClass().getResourceAsStream("olingo1073.json")).
+            replace(Constants.JSON_NAVIGATION_LINK, Constants.JSON_BIND_LINK_SUFFIX));
+    final ObjectNode actualNode = (ObjectNode) OBJECT_MAPPER.readTree(new ByteArrayInputStream(actual.getBytes()));
+    assertEquals(expected, actualNode);
+  }
+  
+  @Test
+  public void issue2OLINGO1073() throws Exception {
+    final ClientEntity message = client.getObjectFactory().
+        newEntity(new FullQualifiedName("Microsoft.OData.SampleService.Models.TripPin.Person"));
+    
+    final ClientComplexValue cityComplexType = getCityComplexType();
+    
+    final ClientComplexValue locationComplexType = client.getObjectFactory().
+        newComplexValue("Microsoft.OData.SampleService.Models.TripPin.Location");
+    locationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln.")));
+    locationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType));
+
+    final ClientComplexValue eventLocationComplexType = client.getObjectFactory().
+        newComplexValue("Microsoft.OData.SampleService.Models.TripPin.EventLocation");
+    eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("BuildingInfo",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12.")));
+    eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12.")));
+    eventLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType));
+    
+    final ClientComplexValue airportLocationComplexType = client.getObjectFactory().
+        newComplexValue("Microsoft.OData.SampleService.Models.TripPin.AirportLocation");
+    airportLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln123.")));
+    airportLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType));
+    
+    final ClientCollectionValue<ClientValue> collectionAddressInfo = client.getObjectFactory().
+        newCollectionValue("Microsoft.OData.SampleService.Models.TripPin.Location");
+    collectionAddressInfo.add(locationComplexType);
+    collectionAddressInfo.add(eventLocationComplexType);
+    collectionAddressInfo.add(airportLocationComplexType);
+    
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("UserName", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("russellwhyte")));
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("FirstName", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell")));
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("LastName", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("Whyte")));
+    
+    final ClientCollectionValue<ClientValue> emailCollectionValue = client.getObjectFactory().
+        newCollectionValue("String");
+    emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell@example.com"));
+    emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell@contoso.com"));
+    message.getProperties().add(client.getObjectFactory().newCollectionProperty("Emails", emailCollectionValue));
+    
+    message.getProperties().add(client.getObjectFactory().newCollectionProperty("AddressInfo", collectionAddressInfo));
+    message.getProperties().add(client.getObjectFactory().newEnumProperty("Gender", 
+        client.getObjectFactory().newEnumValue("Microsoft.OData.SampleService.Models.TripPin.PersonGender", "Male")));
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("Concurrency", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildInt64(Long.valueOf("636293755917400747"))));
+    message.setId(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/"
+        + "TripPinServiceRW/People('russellwhyte')"));
+    message.setETag("W/\"08D491CCBE417AAB\"");
+    message.setEditLink(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/"
+        + "TripPinServiceRW/People('russellwhyte')"));
+
+    final String actual = IOUtils.toString(client.getWriter().writeEntity(message, ContentType.JSON));
+    final JsonNode expected =
+        OBJECT_MAPPER.readTree(IOUtils.toString(getClass().getResourceAsStream("olingo1073_1.json")).
+            replace(Constants.JSON_NAVIGATION_LINK, Constants.JSON_BIND_LINK_SUFFIX));
+    final ObjectNode actualNode = (ObjectNode) OBJECT_MAPPER.readTree(new ByteArrayInputStream(actual.getBytes()));
+    assertEquals(expected, actualNode);
+  }
+  
+
+  /**
+   * @return ClientComplexValue
+   */
+  private ClientComplexValue getCityComplexType() {
+    final ClientComplexValue cityComplexType = client.getObjectFactory().
+        newComplexValue("Microsoft.OData.SampleService.Models.TripPin.City");
+    cityComplexType.add(client.getObjectFactory().newPrimitiveProperty("CountryRegion",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("United States")));
+    cityComplexType.add(client.getObjectFactory().newPrimitiveProperty("Name",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("Boise")));
+    cityComplexType.add(client.getObjectFactory().newPrimitiveProperty("Region",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("ID")));
+    return cityComplexType;
+  }
+  
+  @Test
+  public void issue3OLINGO1073() throws Exception {
+    final ClientEntity message = client.getObjectFactory().
+        newEntity(new FullQualifiedName("Microsoft.OData.SampleService.Models.TripPin.Person"));
+    
+    final ClientComplexValue cityComplexType = getCityComplexType();
+    
+    final ClientComplexValue locationComplexType = client.getObjectFactory().
+        newComplexValue("Microsoft.OData.SampleService.Models.TripPin.Location");
+    locationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln.")));
+    locationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType));
+
+    final ClientComplexValue eventLocationComplexType = client.getObjectFactory().
+        newComplexValue("Microsoft.OData.SampleService.Models.TripPin.EventLocation");
+    eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("BuildingInfo",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12.")));
+    eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12.")));
+    eventLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType));
+    
+    final ClientComplexValue airportLocationComplexType = client.getObjectFactory().
+        newComplexValue("Microsoft.OData.SampleService.Models.TripPin.AirportLocation");
+    airportLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln123.")));
+    airportLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType));
+    
+    final ClientCollectionValue<ClientValue> collectionAddressInfo = client.getObjectFactory().
+        newCollectionValue("Microsoft.OData.SampleService.Models.TripPin.Location");
+    collectionAddressInfo.add(locationComplexType);
+    collectionAddressInfo.add(eventLocationComplexType);
+    collectionAddressInfo.add(airportLocationComplexType);
+    
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("UserName", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("russellwhyte")));
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("FirstName", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell")));
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("LastName", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("Whyte")));
+    
+    final ClientCollectionValue<ClientValue> emailCollectionValue = client.getObjectFactory().
+        newCollectionValue("String");
+    emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell@example.com"));
+    emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell@contoso.com"));
+    message.getProperties().add(client.getObjectFactory().newCollectionProperty("Emails", emailCollectionValue));
+    
+    message.getProperties().add(client.getObjectFactory().newCollectionProperty("AddressInfo", collectionAddressInfo));
+    message.getProperties().add(client.getObjectFactory().newEnumProperty("Gender", 
+        client.getObjectFactory().newEnumValue(
+            "Microsoft.OData.SampleService.Models.TripPin.PersonGender", "Male")));
+    message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("Concurrency", 
+        client.getObjectFactory().newPrimitiveValueBuilder().buildInt64(Long.valueOf("636293755917400747"))));
+    message.setId(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/"
+        + "TripPinServiceRW/People('russellwhyte')"));
+    message.setETag("W/\"08D491CCBE417AAB\"");
+    message.setEditLink(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/"
+        + "TripPinServiceRW/People('russellwhyte')"));
+
+    InputStream inputStream = client.getWriter().writeEntity(message, ContentType.APPLICATION_JSON);
+    ResWrap<Entity> entity = new JsonDeserializer(true).toEntity(inputStream);
+    assertNotNull(entity);
+    assertEquals(7, entity.getPayload().getProperties().size());
+    assertEquals(3, entity.getPayload().getProperty("AddressInfo").asCollection().size());
+    assertEquals("#Microsoft.OData.SampleService.Models.TripPin.Location", 
+        ((ComplexValue)entity.getPayload().getProperty("AddressInfo").asCollection().get(0)).getTypeName());
+    assertEquals("#Microsoft.OData.SampleService.Models.TripPin.EventLocation", 
+        ((ComplexValue)entity.getPayload().getProperty("AddressInfo").asCollection().get(1)).getTypeName());
+    assertEquals("#Microsoft.OData.SampleService.Models.TripPin.AirportLocation", 
+        ((ComplexValue)entity.getPayload().getProperty("AddressInfo").asCollection().get(2)).getTypeName());
+    assertEquals("Collection(Microsoft.OData.SampleService.Models.TripPin.Location)", 
+        entity.getPayload().getProperty("AddressInfo").getType());
+  }
+  
+  @Test
+  public void issue4OLINGO1073_WithAnnotations() throws Exception {
+    InputStream inputStream = getClass().getResourceAsStream(
+        "olingo1073_2" + "." + getSuffix(ContentType.APPLICATION_JSON));
+    ClientEntity entity = client.getReader().readEntity(inputStream, ContentType.APPLICATION_JSON);
+    assertNotNull(entity);
+    assertEquals(7, entity.getProperties().size());
+    assertEquals(1, entity.getAnnotations().size());
+    assertEquals("com.contoso.PersonalInfo.PhoneNumbers", entity.getAnnotations().get(0).getTerm());
+    assertEquals(2, entity.getAnnotations().get(0).getCollectionValue().size());
+    
+    assertEquals("com.contoso.display.style", entity.getProperty("LastName").
+        getAnnotations().get(0).getTerm());
+    assertEquals(2, entity.getProperty("LastName").
+        getAnnotations().get(0).getComplexValue().asComplex().asJavaMap().size());
+    
+    assertEquals(3, entity.getProperty("AddressInfo").getCollectionValue().asCollection().size());
+    assertEquals("Collection(Microsoft.OData.SampleService.Models.TripPin.Location)", 
+        entity.getProperty("AddressInfo").getCollectionValue().asCollection().getTypeName());
+    assertEquals(true, entity.getProperty("AddressInfo").getCollectionValue().isCollection());
+    ClientCollectionValue<ClientValue> collectionValue = entity.getProperty("AddressInfo").
+        getCollectionValue().asCollection();
+    int i = 0;
+    for (ClientValue _value : collectionValue) {
+      if (i == 0) {
+        assertEquals("#Microsoft.OData.SampleService.Models.TripPin.Location", _value.getTypeName());
+        assertEquals(2, _value.asComplex().asJavaMap().size());
+        assertEquals("Microsoft.OData.SampleService.Models.TripPin.City", 
+            _value.asComplex().get("City").getComplexValue().getTypeName());
+      } else if (i == 1) {
+        assertEquals("#Microsoft.OData.SampleService.Models.TripPin.EventLocation", _value.getTypeName());
+        assertEquals(3, _value.asComplex().asJavaMap().size());
+        assertEquals("com.contoso.display.style", _value.asComplex().get("Address").getAnnotations().get(0).getTerm());
+        assertEquals(2, _value.asComplex().get("Address").getAnnotations().get(0).getComplexValue().asJavaMap().size());
+      } else if (i == 2) {
+        assertEquals("#Microsoft.OData.SampleService.Models.TripPin.AirportLocation", _value.getTypeName());
+        assertEquals(3, _value.asComplex().asJavaMap().size());
+      }
+      i++;
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073.json
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073.json b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073.json
new file mode 100644
index 0000000..0a52548
--- /dev/null
+++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073.json
@@ -0,0 +1,17 @@
+{
+	"@odata.type": "#Microsoft.Exchange.Services.OData.Model.Entity",
+	"ToRecipients@odata.type": "#Collection(Microsoft.Exchange.Services.OData.Model.Recipient)",
+	"ToRecipients": [{
+		"@odata.type": "#Microsoft.Exchange.Services.OData.Model.ComplexType1",
+		"Name1@odata.type": "String",
+		"Name1": "challen_olingo_client",
+		"Address1@odata.type": "String",
+		"Address1": "challenh@microsoft.com"
+	}, {
+		"@odata.type": "#Microsoft.Exchange.Services.OData.Model.ComplexType2",
+		"Name2@odata.type": "String",
+		"Name2": "challen_olingo_client",
+		"Address2@odata.type": "String",
+		"Address2": "challenh@microsoft.com"
+	}]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.json
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.json b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.json
new file mode 100644
index 0000000..86cdab5
--- /dev/null
+++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.json
@@ -0,0 +1,66 @@
+{
+  "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.Person",
+  "@odata.id": "http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/TripPinServiceRW/People('russellwhyte')",
+  "UserName@odata.type": "String",
+  "UserName": "russellwhyte",
+  "FirstName@odata.type": "String",
+  "FirstName": "Russell",
+  "LastName@odata.type": "String",
+  "LastName": "Whyte",
+  "Emails@odata.type": "#Collection(String)",
+  "Emails": [
+    "Russell@example.com",
+    "Russell@contoso.com"
+  ],
+  "AddressInfo@odata.type": "#Collection(Microsoft.OData.SampleService.Models.TripPin.Location)",
+  "AddressInfo": [
+    {
+      "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.Location",
+      "Address@odata.type": "String",
+      "Address": "187 Suffolk Ln.",
+      "City": {
+        "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City",
+        "CountryRegion@odata.type": "String",
+        "CountryRegion": "United States",
+        "Name@odata.type": "String",
+        "Name": "Boise",
+        "Region@odata.type": "String",
+        "Region": "ID"
+      }
+    },
+    {
+      "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.EventLocation",
+      "BuildingInfo@odata.type": "String",
+      "BuildingInfo": "187 Suffolk Ln12.",
+      "Address@odata.type": "String",
+      "Address": "187 Suffolk Ln12.",
+      "City": {
+        "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City",
+        "CountryRegion@odata.type": "String",
+        "CountryRegion": "United States",
+        "Name@odata.type": "String",
+        "Name": "Boise",
+        "Region@odata.type": "String",
+        "Region": "ID"
+      }
+    },
+    {
+      "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.AirportLocation",
+	  "Address@odata.type": "String",
+      "Address": "187 Suffolk Ln123.",
+      "City": {
+        "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City",
+        "CountryRegion@odata.type": "String",
+        "CountryRegion": "United States",
+        "Name@odata.type": "String",
+        "Name": "Boise",
+        "Region@odata.type": "String",
+        "Region": "ID"
+      }
+    }
+  ],
+  "Gender@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.PersonGender",
+  "Gender": "Male",
+  "Concurrency@odata.type": "Int64",
+  "Concurrency": 636293755917400747
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.xml
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.xml b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.xml
new file mode 100644
index 0000000..c71b0de
--- /dev/null
+++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.xml
@@ -0,0 +1,65 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<entry xmlns="http://www.w3.org/2005/Atom" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:gml="http://www.opengis.net/gml" xmlns:georss="http://www.georss.org/georss">
+	<id>http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/TripPinServiceRW/People('russellwhyte')</id>
+	<category scheme="http://docs.oasis-open.org/odata/ns/scheme" term="#Microsoft.OData.SampleService.Models.TripPin.Person"/>
+	<content type="application/xml">
+		<m:properties>
+			<d:UserName>russellwhyte</d:UserName>
+			<d:FirstName>Russell</d:FirstName>
+			<d:LastName>Whyte</d:LastName>
+			<d:Emails m:type="#Collection(String)">
+				<m:element>Russell@example.com</m:element>
+				<m:element>Russell@contoso.com</m:element>
+			</d:Emails>
+			<d:AddressInfo m:type="#Collection(Microsoft.OData.SampleService.Models.TripPin.Location)">
+				<m:element m:type="#Microsoft.OData.SampleService.Models.TripPin.Location">
+					<d:Address>187 Suffolk Ln.</d:Address>
+					<d:City m:type="#Microsoft.OData.SampleService.Models.TripPin.City">
+						<d:CountryRegion>United States</d:CountryRegion>
+						<d:Name>Boise</d:Name>
+						<d:Region>ID</d:Region>
+					</d:City>
+				</m:element>
+				<m:element m:type="#Microsoft.OData.SampleService.Models.TripPin.EventLocation">
+					<d:BuildingInfo>187 Suffolk Ln12.</d:BuildingInfo>
+					<d:Address>187 Suffolk Ln12.</d:Address>
+					<d:City m:type="#Microsoft.OData.SampleService.Models.TripPin.City">
+						<d:CountryRegion>United States</d:CountryRegion>
+						<d:Name>Boise</d:Name>
+						<d:Region>ID</d:Region>
+					</d:City>
+				</m:element>
+				<m:element m:type="#Microsoft.OData.SampleService.Models.TripPin.AirportLocation">
+					<d:Address>187 Suffolk Ln123.</d:Address>
+					<d:City m:type="#Microsoft.OData.SampleService.Models.TripPin.City">
+						<d:CountryRegion>United States</d:CountryRegion>
+						<d:Name>Boise</d:Name>
+						<d:Region>ID</d:Region>
+					</d:City>
+				</m:element>
+			</d:AddressInfo>
+			<d:Gender m:type="#Microsoft.OData.SampleService.Models.TripPin.PersonGender">Male</d:Gender>
+			<d:Concurrency m:type="Int64">636293755917400747</d:Concurrency>
+		</m:properties>
+	</content>
+</entry>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.json
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.json b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.json
new file mode 100644
index 0000000..52c76e3
--- /dev/null
+++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.json
@@ -0,0 +1,87 @@
+{
+  "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.Person",
+  "@odata.id": "http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/TripPinServiceRW/People('russellwhyte')",
+  "@com.contoso.PersonalInfo.PhoneNumbers": ["(203)555-1718", "(203)555-1719"],
+  "UserName@odata.type": "String",
+  "UserName": "russellwhyte",
+  "FirstName@odata.type": "String",
+  "FirstName": "Russell",
+  "LastName@com.contoso.display.style": {
+    "@odata.type": "#com.contoso.display.styleType",
+    "title": true,
+    "order": 1
+  },
+  "LastName@odata.type": "String",
+  "LastName": "Whyte",
+  "Emails@odata.type": "#Collection(String)",
+  "Emails": [
+    "Russell@example.com",
+    "Russell@contoso.com"
+  ],
+  "AddressInfo@odata.type": "#Collection(Microsoft.OData.SampleService.Models.TripPin.Location)",
+  "AddressInfo": [
+    {
+      "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.Location",
+      "Address@odata.type": "String",
+      "Address": "187 Suffolk Ln.",
+      "City": {
+        "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City",
+        "CountryRegion@odata.type": "String",
+        "CountryRegion": "United States",
+        "Name@odata.type": "String",
+        "Name": "Boise",
+        "Region@odata.type": "String",
+        "Region": "ID"
+      }
+    },
+    {
+      "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.EventLocation",
+      "BuildingInfo@odata.type": "String",
+      "BuildingInfo": "187 Suffolk Ln12.",
+      "Address@com.contoso.display.style": {
+	    "@odata.type": "#com.contoso.display.styleType",
+	    "Addrtitle": true,
+	    "Addrorder": 1
+	  },
+      "Address": "187 Suffolk Ln12.",
+      "City": {
+        "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City",
+        "CountryRegion@odata.type": "String",
+        "CountryRegion": "United States",
+        "Name@odata.type": "String",
+        "Name": "Boise",
+        "Region@odata.type": "String",
+        "Region": "ID"
+      }
+    },
+    {
+      "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.AirportLocation",
+	  "Address@odata.type": "String",
+      "Address": "187 Suffolk Ln123.",
+      "City": {
+        "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City",
+        "CountryRegion@odata.type": "String",
+        "CountryRegion": "United States",
+        "Name@odata.type": "String",
+        "Name": "Boise",
+        "Region@odata.type": "String",
+        "Region": "ID"
+      },
+      "Home@odata.type": "#GeographyPoint",
+	  "Home": {
+	    "type": "Point",
+	    "coordinates": [23.1, 32.1],
+	    "crs": {
+	      "type": "name",
+	      "properties": {
+	        "name": "EPSG:4326"
+	      }
+	    }
+	  }
+    }
+  ],
+  "Gender@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.PersonGender",
+  "Gender": "Male",
+  "Concurrency@odata.type": "Int64",
+  "Concurrency": 636293755917400747
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.xml
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.xml b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.xml
new file mode 100644
index 0000000..b996ac8
--- /dev/null
+++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.xml
@@ -0,0 +1,78 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<entry xmlns="http://www.w3.org/2005/Atom" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:gml="http://www.opengis.net/gml" xmlns:georss="http://www.georss.org/georss">
+	<id>http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/TripPinServiceRW/People('russellwhyte')</id>
+	<category scheme="http://docs.oasis-open.org/odata/ns/scheme" term="#Microsoft.OData.SampleService.Models.TripPin.Person"/>
+	<content type="application/xml">
+		<m:properties>
+			<d:UserName>russellwhyte</d:UserName>
+			<d:FirstName>Russell</d:FirstName>
+			<d:LastName>Whyte</d:LastName>
+			<m:annotation term="com.contoso.display.style" target="LastName" m:type="#com.contoso.display.styleType">
+		        <d:title m:type="Boolean">true</d:title>
+		        <d:order m:type="Int32">1</d:order>
+		    </m:annotation>
+      		<d:Emails m:type="#Collection(String)">
+				<m:element>Russell@example.com</m:element>
+				<m:element>Russell@contoso.com</m:element>
+			</d:Emails>
+			<d:AddressInfo m:type="#Collection(Microsoft.OData.SampleService.Models.TripPin.Location)">
+				<m:element m:type="#Microsoft.OData.SampleService.Models.TripPin.Location">
+					<d:Address>187 Suffolk Ln.</d:Address>
+					<d:City m:type="#Microsoft.OData.SampleService.Models.TripPin.City">
+						<d:CountryRegion>United States</d:CountryRegion>
+						<d:Name>Boise</d:Name>
+						<d:Region>ID</d:Region>
+					</d:City>
+				</m:element>
+				<m:element m:type="#Microsoft.OData.SampleService.Models.TripPin.EventLocation">
+					<d:BuildingInfo>187 Suffolk Ln12.</d:BuildingInfo>
+					<d:Address>187 Suffolk Ln12.</d:Address>
+					<d:City m:type="#Microsoft.OData.SampleService.Models.TripPin.City">
+						<d:CountryRegion>United States</d:CountryRegion>
+						<d:Name>Boise</d:Name>
+						<d:Region>ID</d:Region>
+					</d:City>
+				</m:element>
+				<m:element m:type="#Microsoft.OData.SampleService.Models.TripPin.AirportLocation">
+					<d:Address>187 Suffolk Ln123.</d:Address>
+					<d:City m:type="#Microsoft.OData.SampleService.Models.TripPin.City">
+						<d:CountryRegion>United States</d:CountryRegion>
+						<d:Name>Boise</d:Name>
+						<d:Region>ID</d:Region>
+					</d:City>
+					<d:Home m:type="GeographyPoint">
+				        <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+				          <gml:pos>32.1 23.1</gml:pos>
+				        </gml:Point>
+				    </d:Home>
+				</m:element>
+			</d:AddressInfo>
+			<d:Gender m:type="#Microsoft.OData.SampleService.Models.TripPin.PersonGender">Male</d:Gender>
+			<d:Concurrency m:type="Int64">636293755917400747</d:Concurrency>
+		</m:properties>
+	</content>
+	<m:annotation term="com.contoso.PersonalInfo.PhoneNumbers" m:type="#Collection(String)">
+	    <m:element>(203)555-1718</m:element>
+	    <m:element>(203)555-1719</m:element>
+  </m:annotation> 
+</entry>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ComplexValue.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ComplexValue.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ComplexValue.java
index 0054777..523c938 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ComplexValue.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ComplexValue.java
@@ -27,6 +27,8 @@ import java.util.List;
 public class ComplexValue extends Linked {
 
   private final List<Property> value = new ArrayList<Property>();
+  
+  private String typeName;
 
   /**
    * Get list of all values for this ComplexValue.
@@ -53,4 +55,20 @@ public class ComplexValue extends Linked {
   public String toString() {
     return value.toString();
   }
+  
+  /**
+   * Get string representation of type (can be null if not set).
+   * @return string representation of type (can be null if not set)
+   */
+  public String getTypeName() {
+    return typeName;
+  }
+
+  /**
+   * Set string representation of type.
+   * @param type string representation of type
+   */
+  public void setTypeName(final String typeName) {
+    this.typeName = typeName;
+  }
 }