You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2014/09/02 13:50:01 UTC

[41/50] [abbrv] git commit: [OLINGO-354] Deserialization of all types of FunctionImports

[OLINGO-354] Deserialization of all types of FunctionImports


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

Branch: refs/heads/Olingo-129_PocJpaDataStore
Commit: 6fd6f064d5d8ed97cd914b1378e988655270533a
Parents: f414699
Author: Michael Bolz <mi...@apache.org>
Authored: Tue Aug 5 15:14:09 2014 +0200
Committer: Michael Bolz <mi...@apache.org>
Committed: Tue Aug 5 19:41:00 2014 +0200

----------------------------------------------------------------------
 .../olingo/odata2/api/ep/EntityProvider.java    |  34 +++++
 .../odata2/core/ep/AtomEntityProvider.java      |  18 +++
 .../core/ep/ContentTypeBasedEntityProvider.java |   3 +
 .../odata2/core/ep/JsonEntityProvider.java      |  18 +++
 .../odata2/core/ep/ProviderFacadeImpl.java      |   6 +
 .../core/ep/consumer/JsonEntityConsumer.java    |  39 ++++-
 .../core/ep/consumer/JsonPropertyConsumer.java  | 126 +++++++++++----
 .../core/ep/consumer/XmlEntityConsumer.java     |  39 ++++-
 .../core/ep/consumer/XmlEntryConsumer.java      |   2 +-
 .../core/ep/consumer/XmlPropertyConsumer.java   |  63 ++++++--
 .../odata2/core/ep/ProviderFacadeImplTest.java  |  10 ++
 .../ep/consumer/JsonPropertyConsumerTest.java   | 120 ++++++++++++++-
 .../ep/consumer/XmlPropertyConsumerTest.java    | 153 ++++++++++++++-----
 .../odata2/core/uri/expression/TestParser.java  |   1 -
 .../odata2/fit/ref/FunctionImportJsonTest.java  | 106 +++++++++++--
 .../odata2/fit/ref/FunctionImportXmlTest.java   |  34 ++++-
 16 files changed, 664 insertions(+), 108 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProvider.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProvider.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProvider.java
index f989d4a..361a94e 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProvider.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProvider.java
@@ -313,6 +313,22 @@ public final class EntityProvider {
         throws EntityProviderException;
 
     /**
+     * Reads (de-serializes) function-import data from <code>content</code> (as {@link InputStream}) in specified format
+     * (given as <code>contentType</code>) based on <code>entity data model</code> (given as {@link EdmFunctionImport})
+     * and provide this data as {@link Object}.
+     * 
+     * @param contentType format of content in the given input stream.
+     * @param functionImport entity data model for Function Import to be read
+     * @param content data in form of an {@link InputStream} which contains the data in specified format
+     * @param properties additional properties necessary for reading content from {@link InputStream} into {@link Map}.
+     * Must not be null.
+     * @return data as {@link Object}
+     * @throws EntityProviderException if reading of data (de-serialization) fails
+     */
+    Object readFunctionImport(final String contentType, final EdmFunctionImport functionImport,
+        final InputStream content, final EntityProviderReadProperties properties) throws EntityProviderException;
+
+    /**
      * Read (de-serialize) a link from <code>content</code> (as {@link InputStream}) in specified format (given as
      * <code>contentType</code>)
      * based on <code>entity data model</code> (given as {@link EdmEntitySet}) and provide the link as {@link String}.
@@ -754,6 +770,24 @@ public final class EntityProvider {
   }
 
   /**
+   * Reads (de-serializes) function-import data from <code>content</code> (as {@link InputStream}) in specified format
+   * (given as <code>contentType</code>) based on <code>entity data model</code> (given as {@link EdmFunctionImport})
+   * and provide this data as {@link Object}.
+   * 
+   * @param contentType format of content in the given input stream.
+   * @param functionImport entity data model for Function Import to be read
+   * @param content data in form of an {@link InputStream} which contains the data in specified format
+   * @param properties additional properties necessary for reading content from {@link InputStream} into {@link Map}.
+   * Must not be null.
+   * @return data as {@link Object}
+   * @throws EntityProviderException if reading of data (de-serialization) fails
+   */
+  public static Object readFunctionImport(final String contentType, final EdmFunctionImport functionImport,
+      final InputStream content, final EntityProviderReadProperties properties) throws EntityProviderException {
+    return createEntityProvider().readFunctionImport(contentType, functionImport, content, properties);
+  }
+
+  /**
    * Read (de-serialize) a link from <code>content</code> (as {@link InputStream}) in specified format (given as
    * <code>contentType</code>)
    * based on <code>entity data model</code> (given as {@link EdmEntitySet}) and provide the link as {@link String}.

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java
index 441dace..e788403 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java
@@ -409,4 +409,22 @@ public class AtomEntityProvider implements ContentTypeBasedEntityProvider {
     XmlErrorDocumentConsumer xmlErrorDocumentConsumer = new XmlErrorDocumentConsumer();
     return xmlErrorDocumentConsumer.readError(errorDocument);
   }
+
+  @Override
+  public Object readFunctionImport(final EdmFunctionImport functionImport, InputStream content,
+      final EntityProviderReadProperties properties) throws EntityProviderException {
+    try {
+      if (functionImport.getReturnType().getType().getKind() == EdmTypeKind.ENTITY) {
+        return new XmlEntityConsumer().readEntry(functionImport.getEntitySet(), content, properties);
+      } else {
+        final EntityPropertyInfo info = EntityInfoAggregator.create(functionImport);
+        return functionImport.getReturnType().getMultiplicity() == EdmMultiplicity.MANY ?
+          new XmlEntityConsumer().readCollection(info, content, properties) :
+          new XmlEntityConsumer().readProperty(info, content, properties).get(info.getName());
+      }
+    } catch (final EdmException e) {
+      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+          .addContent(e.getClass().getSimpleName()), e);
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ContentTypeBasedEntityProvider.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ContentTypeBasedEntityProvider.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ContentTypeBasedEntityProvider.java
index b988039..249931d 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ContentTypeBasedEntityProvider.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ContentTypeBasedEntityProvider.java
@@ -87,4 +87,7 @@ public interface ContentTypeBasedEntityProvider {
       throws EntityProviderException;
 
   ODataErrorContext readErrorDocument(InputStream errorDocument) throws EntityProviderException;
+
+  Object readFunctionImport(EdmFunctionImport functionImport, InputStream content,
+      EntityProviderReadProperties properties) throws EntityProviderException;
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java
index def8c6a..bbece4f 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java
@@ -322,6 +322,24 @@ public class JsonEntityProvider implements ContentTypeBasedEntityProvider {
   }
 
   @Override
+  public Object readFunctionImport(final EdmFunctionImport functionImport, final InputStream content,
+      final EntityProviderReadProperties properties) throws EntityProviderException {
+    try {
+      if (functionImport.getReturnType().getType().getKind() == EdmTypeKind.ENTITY) {
+        return new JsonEntityConsumer().readEntry(functionImport.getEntitySet(), content, properties);
+      } else {
+        final EntityPropertyInfo info = EntityInfoAggregator.create(functionImport);
+        return functionImport.getReturnType().getMultiplicity() == EdmMultiplicity.MANY ?
+          new JsonEntityConsumer().readCollection(info, content, properties) :
+          new JsonEntityConsumer().readProperty(info, content, properties).get(info.getName());
+      }
+    } catch (final EdmException e) {
+      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+          .addContent(e.getClass().getSimpleName()), e);
+    }
+  }
+
+  @Override
   public String readLink(final EdmEntitySet entitySet, final InputStream content) throws EntityProviderException {
     return new JsonEntityConsumer().readLink(entitySet, content);
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
index 803c97c..c76109b 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
@@ -192,6 +192,12 @@ public class ProviderFacadeImpl implements EntityProviderInterface {
   }
 
   @Override
+  public Object readFunctionImport(final String contentType, final EdmFunctionImport functionImport,
+      final InputStream content, final EntityProviderReadProperties properties) throws EntityProviderException {
+    return create(contentType).readFunctionImport(functionImport, content, properties);
+  }
+
+  @Override
   public List<String> readLinks(final String contentType, final EdmEntitySet entitySet, final InputStream content)
       throws EntityProviderException {
     return create(contentType).readLinks(entitySet, content);

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntityConsumer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntityConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntityConsumer.java
index efbcbb9..2faa530 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntityConsumer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntityConsumer.java
@@ -33,6 +33,7 @@ import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
 import org.apache.olingo.odata2.api.ep.feed.ODataDeltaFeed;
 import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
 
 import com.google.gson.stream.JsonReader;
 
@@ -115,14 +116,20 @@ public class JsonEntityConsumer {
     }
   }
 
-  public Map<String, Object> readProperty(final EdmProperty property, final InputStream content,
+
+  public Map<String, Object> readProperty(final EdmProperty edmProperty, InputStream content,
+      final EntityProviderReadProperties properties) throws EntityProviderException {
+    return readProperty(EntityInfoAggregator.create(edmProperty), content, properties);
+  }
+
+  public Map<String, Object> readProperty(final EntityPropertyInfo propertyInfo, final InputStream content,
       final EntityProviderReadProperties readProperties) throws EntityProviderException {
     JsonReader reader = null;
     EntityProviderException cachedException = null;
 
     try {
       reader = createJsonReader(content);
-      return new JsonPropertyConsumer().readPropertyStandalone(reader, property, readProperties);
+      return new JsonPropertyConsumer().readPropertyStandalone(reader, propertyInfo, readProperties);
     } catch (final UnsupportedEncodingException e) {
       cachedException =
           new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
@@ -144,6 +151,34 @@ public class JsonEntityConsumer {
     }
   }
 
+  public List<?> readCollection(final EntityPropertyInfo info, InputStream content,
+      final EntityProviderReadProperties properties) throws EntityProviderException {
+    JsonReader reader = null;
+    EntityProviderException cachedException = null;
+
+    try {
+      reader = createJsonReader(content);
+      return new JsonPropertyConsumer().readCollection(reader, info, properties);
+    } catch (final UnsupportedEncodingException e) {
+      cachedException = new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+          .addContent(e.getClass().getSimpleName()), e);
+      throw cachedException;
+    } finally {// NOPMD (suppress DoNotThrowExceptionInFinally)
+      if (reader != null) {
+        try {
+          reader.close();
+        } catch (final IOException e) {
+          if (cachedException != null) {
+            throw cachedException;
+          } else {
+            throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+                .addContent(e.getClass().getSimpleName()), e);
+          }
+        }
+      }
+    }
+  }
+
   public String readLink(final EdmEntitySet entitySet, final Object content) throws EntityProviderException {
     JsonReader reader = null;
     EntityProviderException cachedException = null;

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumer.java
index 1d0cd96..7589aa5 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumer.java
@@ -19,7 +19,9 @@
 package org.apache.olingo.odata2.core.ep.consumer;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.olingo.odata2.api.edm.Edm;
@@ -44,22 +46,26 @@ import com.google.gson.stream.JsonToken;
  */
 public class JsonPropertyConsumer {
 
-  public Map<String, Object> readPropertyStandalone(final JsonReader reader, final EdmProperty property,
+  public Map<String, Object> readPropertyStandalone(JsonReader reader, final EdmProperty edmProperty,
       final EntityProviderReadProperties readProperties) throws EntityProviderException {
-    try {
-      EntityPropertyInfo entityPropertyInfo = EntityInfoAggregator.create(property);
-      Map<String, Object> typeMappings = readProperties == null ? null : readProperties.getTypeMappings();
-      Map<String, Object> result = new HashMap<String, Object>();
+    return readPropertyStandalone(reader, EntityInfoAggregator.create(edmProperty), readProperties);
+  }
 
+  public Map<String, Object> readPropertyStandalone(final JsonReader reader, final EntityPropertyInfo propertyInfo,
+      final EntityProviderReadProperties readProperties) throws EntityProviderException {
+    Map<String, Object> typeMappings = readProperties == null ? null : readProperties.getTypeMappings();
+    Map<String, Object> result = new HashMap<String, Object>();
+
+    try {
       reader.beginObject();
       String nextName = reader.nextName();
       if (FormatJson.D.equals(nextName)) {
         reader.beginObject();
         nextName = reader.nextName();
-        handleName(reader, typeMappings, entityPropertyInfo, readProperties, result, nextName);
+        handleName(reader, typeMappings, propertyInfo, readProperties, result, nextName);
         reader.endObject();
       } else {
-        handleName(reader, typeMappings, entityPropertyInfo, readProperties, result, nextName);
+        handleName(reader, typeMappings, propertyInfo, readProperties, result, nextName);
       }
       reader.endObject();
 
@@ -78,17 +84,80 @@ public class JsonPropertyConsumer {
     }
   }
 
+  public List<?> readCollection(JsonReader reader, final EntityPropertyInfo propertyInfo,
+        final EntityProviderReadProperties readProperties) throws EntityProviderException {
+    final Object typeMapping = readProperties == null ? null :
+      readProperties.getTypeMappings().get(propertyInfo.getName());
+    List<Object> result = new ArrayList<Object>();
+    String name = null;
+    boolean wrapped = false;
+    boolean version2 = false;
+
+    try {
+      if (reader.peek() == JsonToken.BEGIN_OBJECT) {
+        reader.beginObject();
+        name = reader.nextName();
+        if (FormatJson.D.equals(name)) {
+          wrapped = true;
+          if (reader.peek() == JsonToken.BEGIN_OBJECT) {
+            reader.beginObject();
+            name = reader.nextName();
+          } else {
+            name = null;
+          }
+        }
+      }
+      if (name != null) {
+        version2 = true;
+        if (FormatJson.METADATA.equals(name)) {
+          readAndCheckTypeInfo(reader,
+              "Collection(" + propertyInfo.getType().getNamespace() + Edm.DELIMITER
+              + propertyInfo.getType().getName() + ")");
+          name = reader.nextName();
+        }
+        if (!FormatJson.RESULTS.equals(name)) {
+          throw new EntityProviderException(EntityProviderException.INVALID_PARENT_TAG
+              .addContent(FormatJson.RESULTS, name));
+        }
+      }
+      reader.beginArray();
+      while (reader.hasNext()) {
+        result.add(readPropertyValue(reader, propertyInfo, typeMapping, readProperties));
+      }
+      reader.endArray();
+      if (version2) {
+        reader.endObject();
+      }
+      if (wrapped) {
+        reader.endObject();
+      }
+
+      if (reader.peek() != JsonToken.END_DOCUMENT) {
+        throw new EntityProviderException(EntityProviderException.END_DOCUMENT_EXPECTED
+            .addContent(reader.peek().toString()));
+      }
+
+      return result;
+    } catch (final EdmException e) {
+      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+          .addContent(e.getClass().getSimpleName()), e);
+    } catch (final IOException e) {
+      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+          .addContent(e.getClass().getSimpleName()), e);
+    } catch (final IllegalStateException e) {
+      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+          .addContent(e.getClass().getSimpleName()), e);
+    }
+  }
+
   private void handleName(final JsonReader reader, final Map<String, Object> typeMappings,
       final EntityPropertyInfo entityPropertyInfo, final EntityProviderReadProperties readProperties,
       final Map<String, Object> result, final String nextName) throws EntityProviderException {
     if (!entityPropertyInfo.getName().equals(nextName)) {
       throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent(nextName));
     }
-    Object mapping = null;
-    if (typeMappings != null) {
-      mapping = typeMappings.get(nextName);
-    }
-    Object propertyValue = readPropertyValue(reader, entityPropertyInfo, mapping, readProperties);
+    final Object mapping = typeMappings == null ? null : typeMappings.get(nextName);
+    final Object propertyValue = readPropertyValue(reader, entityPropertyInfo, mapping, readProperties);
     result.put(nextName, propertyValue);
   }
 
@@ -196,22 +265,10 @@ public class JsonPropertyConsumer {
     }
 
     while (reader.hasNext()) {
-      String childName = reader.nextName();
+      final String childName = reader.nextName();
       if (FormatJson.METADATA.equals(childName)) {
-        reader.beginObject();
-        childName = reader.nextName();
-        if (!FormatJson.TYPE.equals(childName)) {
-          throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent(FormatJson.TYPE)
-              .addContent(FormatJson.METADATA));
-        }
-        String actualTypeName = reader.nextString();
-        String expectedTypeName =
-            complexPropertyInfo.getType().getNamespace() + Edm.DELIMITER + complexPropertyInfo.getType().getName();
-        if (!expectedTypeName.equals(actualTypeName)) {
-          throw new EntityProviderException(EntityProviderException.INVALID_ENTITYTYPE.addContent(expectedTypeName)
-              .addContent(actualTypeName));
-        }
-        reader.endObject();
+        readAndCheckTypeInfo(reader,
+            complexPropertyInfo.getType().getNamespace() + Edm.DELIMITER + complexPropertyInfo.getType().getName());
       } else {
         EntityPropertyInfo childPropertyInfo = complexPropertyInfo.getPropertyInfo(childName);
         if (childPropertyInfo == null) {
@@ -227,4 +284,19 @@ public class JsonPropertyConsumer {
     reader.endObject();
     return data;
   }
+
+  protected void readAndCheckTypeInfo(final JsonReader reader, String expectedTypeName)
+          throws IOException, EntityProviderException {
+    reader.beginObject();
+    if (!FormatJson.TYPE.equals(reader.nextName())) {
+      throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent(FormatJson.TYPE)
+          .addContent(FormatJson.METADATA));
+    }
+    final String actualTypeName = reader.nextString();
+    if (!expectedTypeName.equals(actualTypeName)) {
+      throw new EntityProviderException(EntityProviderException.INVALID_ENTITYTYPE.addContent(expectedTypeName)
+          .addContent(actualTypeName));
+    }
+    reader.endObject();
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumer.java
index acbc77f..378cf98 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumer.java
@@ -36,6 +36,7 @@ import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
 import org.apache.olingo.odata2.api.ep.feed.ODataDeltaFeed;
 import org.apache.olingo.odata2.core.commons.XmlHelper;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
 
 /**
  * Xml entity (content type dependent) consumer for reading input (from <code>content</code>).
@@ -109,14 +110,16 @@ public class XmlEntityConsumer {
 
   public Map<String, Object> readProperty(final EdmProperty edmProperty, final InputStream content,
       final EntityProviderReadProperties properties) throws EntityProviderException {
+    return readProperty(EntityInfoAggregator.create(edmProperty), content, properties);
+  }
+
+  public Map<String, Object> readProperty(final EntityPropertyInfo propertyInfo, final InputStream content,
+      final EntityProviderReadProperties readProperties) throws EntityProviderException {
     XMLStreamReader reader = null;
     EntityProviderException cachedException = null;
-    XmlPropertyConsumer xec = new XmlPropertyConsumer();
-
     try {
       reader = XmlHelper.createStreamReader(content);
-      return xec.readProperty(reader, edmProperty, properties.getMergeSemantic(), properties.getTypeMappings(),
-          properties);
+      return new XmlPropertyConsumer().readProperty(reader, propertyInfo, readProperties);
     } catch (EntityProviderException e) {
       cachedException = e;
       throw cachedException;
@@ -160,6 +163,33 @@ public class XmlEntityConsumer {
     }
   }
 
+
+  public Object readCollection(final EntityPropertyInfo info, InputStream content,
+      final EntityProviderReadProperties properties) throws EntityProviderException {
+    XMLStreamReader reader = null;
+    EntityProviderException cachedException = null;
+    try {
+      reader = XmlHelper.createStreamReader(content);
+      return new XmlPropertyConsumer().readCollection(reader, info, properties);
+    } catch (final EntityProviderException e) {
+      cachedException = e;
+      throw cachedException;
+    } finally {// NOPMD (suppress DoNotThrowExceptionInFinally)
+      if (reader != null) {
+        try {
+          reader.close();
+        } catch (final XMLStreamException e) {
+          if (cachedException != null) {
+            throw cachedException;
+          } else {
+            throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+                .addContent(e.getClass().getSimpleName()), e);
+          }
+        }
+      }
+    }
+  }
+
   public String readLink(final EdmEntitySet entitySet, final Object content) throws EntityProviderException {
     XMLStreamReader reader = null;
     EntityProviderException cachedException = null;
@@ -213,5 +243,4 @@ public class XmlEntityConsumer {
       }
     }
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java
index 4bc9173..a9d8ae1 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java
@@ -588,7 +588,7 @@ public class XmlEntryConsumer {
             throw new EntityProviderException(EntityProviderException.DOUBLE_PROPERTY.addContent(closeTag));
           }
           property = getValidatedPropertyInfo(entitySet, closeTag);
-          final Object value = xpc.readStartedElement(reader, property, typeMappings, readProperties);
+          final Object value = xpc.readStartedElement(reader, closeTag, property, typeMappings, readProperties);
           properties.put(closeTag, value);
           closeTag = null;
         }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumer.java
index 3887333..8a052cb 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumer.java
@@ -18,7 +18,10 @@
  ******************************************************************************/
 package org.apache.olingo.odata2.core.ep.consumer;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import javax.xml.stream.XMLStreamConstants;
@@ -49,26 +52,27 @@ public class XmlPropertyConsumer {
   protected static final String FALSE = "false";
 
   public Map<String, Object> readProperty(final XMLStreamReader reader, final EdmProperty property,
-      final boolean merge, final EntityProviderReadProperties readProperties) throws EntityProviderException {
-    return readProperty(reader, property, merge, null, readProperties);
+      final EntityProviderReadProperties readProperties) throws EntityProviderException {
+    return readProperty(reader, EntityInfoAggregator.create(property), readProperties);
   }
 
-  public Map<String, Object> readProperty(final XMLStreamReader reader, final EdmProperty property,
-      final boolean merge, final Map<String, Object> typeMappings, final EntityProviderReadProperties readProperties)
-      throws EntityProviderException {
-    EntityPropertyInfo eia = EntityInfoAggregator.create(property);
-
+  public Map<String, Object> readProperty(final XMLStreamReader reader, final EntityPropertyInfo propertyInfo,
+      final EntityProviderReadProperties readProperties) throws EntityProviderException {
+    final EntityTypeMapping typeMappings =
+        EntityTypeMapping.create(readProperties == null ? Collections.<String, Object> emptyMap() :
+          readProperties.getTypeMappings());
+    final boolean merge = readProperties != null && readProperties.getMergeSemantic();
     try {
       reader.next();
 
-      Object value = readStartedElement(reader, eia, EntityTypeMapping.create(typeMappings), readProperties);
+      Object value = readStartedElement(reader, propertyInfo.getName(), propertyInfo, typeMappings, readProperties);
 
-      if (eia.isComplex() && merge) {
-        mergeWithDefaultValues(value, eia);
+      if (propertyInfo.isComplex() && merge) {
+        mergeWithDefaultValues(value, propertyInfo);
       }
 
       Map<String, Object> result = new HashMap<String, Object>();
-      result.put(eia.getName(), value);
+      result.put(propertyInfo.getName(), value);
       return result;
     } catch (XMLStreamException e) {
       throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
@@ -110,10 +114,39 @@ public class XmlPropertyConsumer {
     }
   }
 
-  protected Object readStartedElement(final XMLStreamReader reader, final EntityPropertyInfo propertyInfo,
+  public List<?> readCollection(XMLStreamReader reader, final EntityPropertyInfo info,
+      final EntityProviderReadProperties properties) throws EntityProviderException {
+    final String collectionName = info.getName();
+    final EntityTypeMapping typeMappings = EntityTypeMapping.create(
+        properties == null || !properties.getTypeMappings().containsKey(collectionName) ?
+            Collections.<String, Object> emptyMap() :
+            Collections.<String, Object> singletonMap(FormatXml.D_ELEMENT,
+                properties.getTypeMappings().get(collectionName)));
+    List<Object> result = new ArrayList<Object>();
+    try {
+      reader.nextTag();
+      reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_D_2007_08, collectionName);
+      reader.nextTag();
+      while (reader.isStartElement()) {
+        result.add(readStartedElement(reader, FormatXml.D_ELEMENT, info, typeMappings, properties));
+        reader.nextTag();
+      }
+      reader.require(XMLStreamConstants.END_ELEMENT, Edm.NAMESPACE_D_2007_08, collectionName);
+      reader.next();
+      reader.require(XMLStreamConstants.END_DOCUMENT, null, null);
+      return result;
+    } catch (final XMLStreamException e) {
+      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+          .addContent(e.getClass().getSimpleName()), e);
+    } catch (final EdmException e) {
+      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+          .addContent(e.getClass().getSimpleName()), e);
+    }
+  }
+
+  protected Object readStartedElement(XMLStreamReader reader, final String name, final EntityPropertyInfo propertyInfo,
       final EntityTypeMapping typeMappings, final EntityProviderReadProperties readProperties)
       throws EntityProviderException, EdmException {
-    final String name = propertyInfo.getName();
     Object result = null;
 
     try {
@@ -149,8 +182,8 @@ public class XmlPropertyConsumer {
           if (childProperty == null) {
             throw new EntityProviderException(EntityProviderException.INVALID_PROPERTY.addContent(childName));
           }
-          final Object value = readStartedElement(reader, childProperty, typeMappings.getEntityTypeMapping(name),
-              readProperties);
+          final Object value = readStartedElement(reader, childName, childProperty,
+              typeMappings.getEntityTypeMapping(name), readProperties);
           name2Value.put(childName, value);
           reader.nextTag();
         }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImplTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImplTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImplTest.java
index e5236d4..40e5e0b 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImplTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImplTest.java
@@ -217,6 +217,16 @@ public class ProviderFacadeImplTest extends AbstractConsumerTest {
   }
 
   @Test
+  public void readFunctionImport() throws Exception {
+    final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer()
+        .getFunctionImport("MaximalAge");
+    InputStream content = new ByteArrayInputStream("{\"d\":{\"MaximalAge\":42}}".getBytes("UTF-8"));
+    final Object result = new ProviderFacadeImpl().readFunctionImport(HttpContentType.APPLICATION_JSON,
+        functionImport, content, EntityProviderReadProperties.init().build());
+    assertEquals((short) 42, result);
+  }
+
+  @Test
   public void readLink() throws Exception {
     final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
     InputStream content = new ByteArrayInputStream("{\"d\":{\"uri\":\"http://somelink\"}}".getBytes("UTF-8"));

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumerTest.java
index cc5ec25..36b1cca 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumerTest.java
@@ -32,7 +32,9 @@ import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
 import java.util.Arrays;
 import java.util.Calendar;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
@@ -665,10 +667,6 @@ public class JsonPropertyConsumerTest extends BaseTest {
     return resultMap;
   }
 
-  private InputStream createContentAsStream(final String json) throws UnsupportedEncodingException {
-    return new ByteArrayInputStream(json.getBytes("UTF-8"));
-  }
-
   @Test(expected = EntityProviderException.class)
   public void invalidDoubleClosingBrackets() throws Exception {
     String simplePropertyJson = "{\"d\":{\"Name\":\"Team 1\"}}}";
@@ -691,4 +689,118 @@ public class JsonPropertyConsumerTest extends BaseTest {
     new JsonPropertyConsumer().readPropertyStandalone(reader, edmProperty, null);
   }
 
+  @Test
+  public void collectionEmpty() throws Exception {
+    final EntityPropertyInfo info = EntityInfoAggregator.create(
+        MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds"));
+    List<?> collection = new JsonPropertyConsumer().readCollection(prepareReader("[]"), info, null);
+    assertNotNull(collection);
+    assertTrue(collection.isEmpty());
+
+    collection = new JsonPropertyConsumer().readCollection(prepareReader("{\"d\":[]}"), info, null);
+    assertNotNull(collection);
+    assertTrue(collection.isEmpty());
+
+    collection = new JsonPropertyConsumer().readCollection(prepareReader("{\"results\":[]}"), info, null);
+    assertNotNull(collection);
+    assertTrue(collection.isEmpty());
+
+    collection = new JsonPropertyConsumer().readCollection(prepareReader("{\"d\":{\"results\":[]}}"), info, null);
+    assertNotNull(collection);
+    assertTrue(collection.isEmpty());
+  }
+
+  @Test
+  public void collectionSimple() throws Exception {
+    final EntityPropertyInfo info = EntityInfoAggregator.create(
+        MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds"));
+    List<?> collection = new JsonPropertyConsumer().readCollection(prepareReader("[\"1\",\"42\"]"), info, null);
+    assertNotNull(collection);
+    assertEquals(Arrays.asList("1", "42"), collection);
+  }
+
+  @Test
+  public void collectionSimpleWithMetadata() throws Exception {
+    final EntityPropertyInfo info = EntityInfoAggregator.create(
+        MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds"));
+    List<?> collection = new JsonPropertyConsumer().readCollection(prepareReader(
+        "{\"__metadata\":{\"type\":\"Collection(Edm.String)\"},\"results\":[\"1\",\"42\"]}"),
+        info, null);
+    assertNotNull(collection);
+    assertEquals(Arrays.asList("1", "42"), collection);
+  }
+
+  @Test
+  public void collectionSimpleWithMapping() throws Exception {
+    final EntityPropertyInfo info = EntityInfoAggregator.create(
+        MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds"));
+    EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class);
+    when(readProperties.getTypeMappings()).thenReturn(
+        Collections.<String, Object> singletonMap("AllUsedRoomIds", String.class));
+    List<?> collection = new JsonPropertyConsumer().readCollection(prepareReader("[\"1\",\"42\"]"), info,
+        readProperties);
+    assertNotNull(collection);
+    assertEquals(Arrays.asList("1", "42"), collection);
+  }
+
+  @Test
+  public void collectionComplex() throws Exception {
+    final EntityPropertyInfo info = EntityInfoAggregator.create(
+        MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllLocations"));
+    EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class);
+    final Map<String, Object> mappings = Collections.<String, Object> singletonMap("Location",
+        Collections.<String, Object> singletonMap("City",
+            Collections.<String, Object> singletonMap("PostalCode", String.class)));
+    when(readProperties.getTypeMappings()).thenReturn(mappings);
+    List<?> collection = new JsonPropertyConsumer().readCollection(prepareReader(
+        "{\"__metadata\":{\"type\":\"Collection(RefScenario.c_Location)\"},"
+            + "\"results\":["
+            + "{\"City\":{\"PostalCode\":\"69124\",\"CityName\":\"Heidelberg\"},\"Country\":\"Germany\"},"
+            + "{\"City\":{\"PostalCode\":\"69190\",\"CityName\":\"Walldorf\"},\"Country\":\"Germany\"}]}"),
+        info, readProperties);
+    assertNotNull(collection);
+    assertEquals(2, collection.size());
+    @SuppressWarnings("unchecked")
+    final Map<String, Object> secondLocation = (Map<String, Object>) collection.get(1);
+    assertEquals("Germany", secondLocation.get("Country"));
+  }
+
+  @Test(expected = EntityProviderException.class)
+  public void collectionUnfinished() throws Exception {
+    final EntityPropertyInfo info = EntityInfoAggregator.create(
+        MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds"));
+    new JsonPropertyConsumer().readCollection(prepareReader("[\"1\""), info, null);
+  }
+
+  @Test(expected = EntityProviderException.class)
+  public void collectionWithoutClosing() throws Exception {
+    final EntityPropertyInfo info = EntityInfoAggregator.create(
+        MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds"));
+    new JsonPropertyConsumer().readCollection(prepareReader("{\"results\":[]"), info, null);
+  }
+
+  @Test(expected = EntityProviderException.class)
+  public void collectionWithWrongTag() throws Exception {
+    final EntityPropertyInfo info = EntityInfoAggregator.create(
+        MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds"));
+    new JsonPropertyConsumer().readCollection(prepareReader("{\"something\":[]}"), info, null);
+  }
+
+  @Test(expected = EntityProviderException.class)
+  public void collectionWithWrongInnerTag() throws Exception {
+    final EntityPropertyInfo info = EntityInfoAggregator.create(
+        MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds"));
+    new JsonPropertyConsumer().readCollection(prepareReader("{\"d\":{\"something\":[]}}"), info, null);
+  }
+
+  @Test(expected = EntityProviderException.class)
+  public void collectionWithTrailing() throws Exception {
+    final EntityPropertyInfo info = EntityInfoAggregator.create(
+        MockFacade.getMockEdm().getDefaultEntityContainer().getFunctionImport("AllUsedRoomIds"));
+    new JsonPropertyConsumer().readCollection(prepareReader("{\"results\":[],\"a\":0}"), info, null);
+  }
+
+  private InputStream createContentAsStream(final String json) throws UnsupportedEncodingException {
+    return new ByteArrayInputStream(json.getBytes("UTF-8"));
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumerTest.java
index c33b4ea..1b3bc8c 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumerTest.java
@@ -26,8 +26,11 @@ import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import java.util.Arrays;
 import java.util.Calendar;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import javax.xml.stream.XMLStreamReader;
@@ -40,6 +43,7 @@ import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
 import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
 import org.apache.olingo.odata2.testutil.mock.MockFacade;
 import org.junit.Test;
 
@@ -59,7 +63,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age");
 
-    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null);
 
     assertEquals(Integer.valueOf(67), resultMap.get("Age"));
   }
@@ -71,9 +75,9 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age");
 
-    Map<String, Object> typeMappings = createTypeMappings("Age", Long.class);
-    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, typeMappings,
-        null);
+    EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class);
+    when(readProperties.getTypeMappings()).thenReturn(createTypeMappings("Age", Long.class));
+    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, readProperties);
 
     assertEquals(Long.valueOf(67), resultMap.get("Age"));
   }
@@ -85,9 +89,9 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age");
 
-    Map<String, Object> typeMappings = null;
-    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, typeMappings,
-        null);
+    EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class);
+    when(readProperties.getTypeMappings()).thenReturn(null);
+    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, readProperties);
 
     assertEquals(Integer.valueOf(67), resultMap.get("Age"));
   }
@@ -99,9 +103,9 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age");
 
-    Map<String, Object> typeMappings = new HashMap<String, Object>();
-    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, typeMappings,
-        null);
+    EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class);
+    when(readProperties.getTypeMappings()).thenReturn(new HashMap<String, Object>());
+    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, readProperties);
 
     assertEquals(Integer.valueOf(67), resultMap.get("Age"));
   }
@@ -113,7 +117,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("EmployeeName");
 
-    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null);
 
     assertEquals("Max Mustermann", resultMap.get("EmployeeName"));
   }
@@ -125,7 +129,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("EmployeeName");
 
-    final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null);
 
     assertTrue(resultMap.containsKey("EmployeeName"));
     assertEquals("", resultMap.get("EmployeeName"));
@@ -139,7 +143,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("EntryDate");
 
-    final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null);
 
     assertTrue(resultMap.containsKey("EntryDate"));
     assertNull(resultMap.get("EntryDate"));
@@ -153,7 +157,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("EntryDate");
 
-    final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null);
 
     assertEquals(86400000L, ((Calendar) resultMap.get("EntryDate")).getTimeInMillis());
   }
@@ -165,7 +169,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age");
 
-    new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    new XmlPropertyConsumer().readProperty(reader, property, null);
   }
 
   @Test(expected = EntityProviderException.class)
@@ -176,7 +180,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age");
 
-    new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    new XmlPropertyConsumer().readProperty(reader, property, null);
   }
 
   @Test(expected = EntityProviderException.class)
@@ -190,7 +194,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     when(facets.isNullable()).thenReturn(false);
     when(property.getFacets()).thenReturn(facets);
 
-    new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    new XmlPropertyConsumer().readProperty(reader, property, null);
   }
 
   @Test(expected = EntityProviderException.class)
@@ -202,7 +206,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     when(facets.getMaxLength()).thenReturn(10);
     when(property.getFacets()).thenReturn(facets);
 
-    new XmlPropertyConsumer().readProperty(createReaderForTest(xml, true), property, false, null);
+    new XmlPropertyConsumer().readProperty(createReaderForTest(xml, true), property, null);
   }
 
   @Test
@@ -216,7 +220,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class);
 
     final Map<String, Object> resultMap = new XmlPropertyConsumer()
-        .readProperty(createReaderForTest(xml, true), property, false, readProperties);
+        .readProperty(createReaderForTest(xml, true), property, readProperties);
     assertTrue(resultMap.containsKey("Name"));
     assertEquals("TooLongName", resultMap.get("Name"));
   }
@@ -237,7 +241,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
 
-    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null);
 
     Map<String, Object> locationMap = (Map<String, Object>) resultMap.get("Location");
     assertEquals("Germany", locationMap.get("Country"));
@@ -265,7 +269,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
 
-    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null);
 
     Map<String, Object> locationMap = (Map<String, Object>) resultMap.get("Location");
     assertEquals("Germany", locationMap.get("Country"));
@@ -289,10 +293,13 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
 
+    EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class);
+    when(readProperties.getTypeMappings()).thenReturn(
+        createTypeMappings("Location",
+            createTypeMappings("City",
+                createTypeMappings("PostalCode", Integer.class))));
     try {
-      Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false,
-          createTypeMappings("Location", createTypeMappings("City", createTypeMappings("PostalCode", Integer.class))),
-          null);
+      Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, readProperties);
       assertNotNull(resultMap);
     } catch (EntityProviderException e) {
       assertTrue(e.getCause() instanceof EdmSimpleTypeException);
@@ -322,12 +329,13 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     when(postalCodeProperty.getType()).thenReturn(EdmSimpleTypeKind.Int32.getEdmSimpleTypeInstance());
 
     // Execute test
-    Map<String, Object> typeMappings =
+    EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class);
+    when(readProperties.getTypeMappings()).thenReturn(
         createTypeMappings("Location",
             createTypeMappings("City",
-                createTypeMappings("CityName", String.class, "PostalCode", Long.class)));
+                createTypeMappings("CityName", String.class, "PostalCode", Long.class))));
     Map<String, Object> resultMap =
-        new XmlPropertyConsumer().readProperty(reader, locationComplexProperty, false, typeMappings, null);
+        new XmlPropertyConsumer().readProperty(reader, locationComplexProperty, readProperties);
 
     // verify
     Map<String, Object> locationMap = (Map<String, Object>) resultMap.get("Location");
@@ -354,7 +362,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
 
-    Object prop = new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    Object prop = new XmlPropertyConsumer().readProperty(reader, property, null);
     Map<String, Object> resultMap = (Map<String, Object>) prop;
 
     Map<String, Object> locationMap = (Map<String, Object>) resultMap.get("Location");
@@ -379,7 +387,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
 
-    new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    new XmlPropertyConsumer().readProperty(reader, property, null);
   }
 
   @Test(expected = EntityProviderException.class)
@@ -397,7 +405,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
 
-    new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    new XmlPropertyConsumer().readProperty(reader, property, null);
   }
 
   @Test(expected = EntityProviderException.class)
@@ -415,7 +423,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
 
-    new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    new XmlPropertyConsumer().readProperty(reader, property, null);
   }
 
   @Test(expected = EntityProviderException.class)
@@ -433,7 +441,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
 
-    new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    new XmlPropertyConsumer().readProperty(reader, property, null);
   }
 
   @Test
@@ -452,7 +460,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
 
-    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null);
 
     Map<String, Object> locationMap = (Map<String, Object>) resultMap.get("Location");
     assertEquals("Germany", locationMap.get("Country"));
@@ -469,7 +477,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
 
-    final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null);
 
     assertTrue(resultMap.containsKey("Location"));
     assertNull(resultMap.get("Location"));
@@ -486,7 +494,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     when(facets.isNullable()).thenReturn(false);
     when(property.getFacets()).thenReturn(facets);
 
-    new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    new XmlPropertyConsumer().readProperty(reader, property, null);
   }
 
   @Test
@@ -501,7 +509,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EntityProviderReadProperties readProperties = mock(EntityProviderReadProperties.class);
 
     final Map<String, Object> resultMap = new XmlPropertyConsumer()
-        .readProperty(createReaderForTest(xml, true), property, false, readProperties);
+        .readProperty(createReaderForTest(xml, true), property, readProperties);
     assertFalse(resultMap.isEmpty());
     assertNull(resultMap.get("Location"));
   }
@@ -516,7 +524,7 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
 
-    new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    new XmlPropertyConsumer().readProperty(reader, property, null);
   }
 
   @Test
@@ -526,11 +534,80 @@ public class XmlPropertyConsumerTest extends AbstractXmlConsumerTest {
     final EdmProperty property =
         (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
 
-    final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, null);
+    final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, null);
 
     assertNotNull(resultMap.get("Location"));
     @SuppressWarnings("unchecked")
     final Map<String, Object> innerMap = (Map<String, Object>) resultMap.get("Location");
     assertTrue(innerMap.isEmpty());
   }
+
+  @Test
+  public void collectionSimpleType() throws Exception {
+    final String xml = "<AllUsedRoomIds xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\">"
+        + "<element>1</element>"
+        + "<element m:null=\"true\" xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" />"
+        + "<element></element>"
+        + "</AllUsedRoomIds>";
+    @SuppressWarnings("unchecked")
+    final List<String> result = (List<String>) new XmlPropertyConsumer().readCollection(createReaderForTest(xml, true),
+        EntityInfoAggregator.create(MockFacade.getMockEdm().getDefaultEntityContainer()
+            .getFunctionImport("AllUsedRoomIds")),
+        EntityProviderReadProperties.init().build());
+    assertNotNull(result);
+    assertEquals(Arrays.asList("1", null, ""), result);
+  }
+
+  @Test(expected = EntityProviderException.class)
+  public void collectionSimpleTypeWrong() throws Exception {
+    final String xml = "<AllUsedRoomIds xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\">"
+        + "<m:element xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" />"
+        + "</AllUsedRoomIds>";
+    new XmlPropertyConsumer().readCollection(createReaderForTest(xml, true),
+        EntityInfoAggregator.create(MockFacade.getMockEdm().getDefaultEntityContainer()
+            .getFunctionImport("AllUsedRoomIds")), null);
+  }
+
+  @Test(expected = EntityProviderException.class)
+  public void collectionSimpleTypeWrongMapping() throws Exception {
+    final String xml = "<AllUsedRoomIds xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\">"
+        + "<element>1</element></AllUsedRoomIds>";
+    new XmlPropertyConsumer().readCollection(createReaderForTest(xml, true),
+        EntityInfoAggregator.create(MockFacade.getMockEdm().getDefaultEntityContainer()
+            .getFunctionImport("AllUsedRoomIds")),
+        EntityProviderReadProperties.init().addTypeMappings(
+            Collections.<String, Object> singletonMap("AllUsedRoomIds", Integer.class)).build());
+  }
+
+  @Test(expected = EntityProviderException.class)
+  public void collectionSimpleTypeWrongXml() throws Exception {
+    final String xml = "<AllUsedRoomIds xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\"><element>1</element>";
+    new XmlPropertyConsumer().readCollection(createReaderForTest(xml, true),
+        EntityInfoAggregator.create(MockFacade.getMockEdm().getDefaultEntityContainer()
+            .getFunctionImport("AllUsedRoomIds")), null);
+  }
+
+  @Test
+  public void collectionComplexType() throws Exception {
+    final String xml = "<d:AllLocations xmlns:d=\"" + Edm.NAMESPACE_D_2007_08 + "\">"
+        + "<d:element><d:City><d:PostalCode>69124</d:PostalCode><d:CityName>Heidelberg</d:CityName></d:City>"
+        + "<d:Country>Germany</d:Country></d:element>"
+        + "<d:element m:type=\"RefScenario.c_Location\" xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\">"
+        + "<d:City m:type=\"RefScenario.c_City\"><d:PostalCode>69190</d:PostalCode><d:CityName>Walldorf</d:CityName>"
+        + "</d:City><d:Country>Germany</d:Country></d:element>"
+        + "</d:AllLocations>";
+    @SuppressWarnings("unchecked")
+    final List<?> result = (List<String>) new XmlPropertyConsumer().readCollection(createReaderForTest(xml, true),
+        EntityInfoAggregator.create(MockFacade.getMockEdm().getDefaultEntityContainer()
+            .getFunctionImport("AllLocations")),
+        EntityProviderReadProperties.init().build());
+    assertNotNull(result);
+    assertEquals(2, result.size());
+    @SuppressWarnings("unchecked")
+    final Map<String, Object> secondLocation = (Map<String, Object>) result.get(1);
+    assertEquals("Germany", secondLocation.get("Country"));
+    @SuppressWarnings("unchecked")
+    final Map<String, Object> secondCity = (Map<String, Object>) secondLocation.get("City");
+    assertEquals("Walldorf", secondCity.get("CityName"));
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestParser.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestParser.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestParser.java
index ef73dc8..229edeb 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestParser.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestParser.java
@@ -44,7 +44,6 @@ import org.apache.olingo.odata2.core.edm.EdmGuid;
 import org.apache.olingo.odata2.core.edm.EdmInt16;
 import org.apache.olingo.odata2.core.edm.EdmInt32;
 import org.apache.olingo.odata2.core.edm.EdmInt64;
-import org.apache.olingo.odata2.core.edm.EdmNull;
 import org.apache.olingo.odata2.core.edm.EdmSByte;
 import org.apache.olingo.odata2.core.edm.EdmSingle;
 import org.apache.olingo.odata2.core.edm.EdmString;

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportJsonTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportJsonTest.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportJsonTest.java
index 937f64f..b17663e 100644
--- a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportJsonTest.java
+++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportJsonTest.java
@@ -19,11 +19,22 @@
 package org.apache.olingo.odata2.fit.ref;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.http.HttpResponse;
 import org.apache.olingo.odata2.api.commons.HttpContentType;
 import org.apache.olingo.odata2.api.commons.HttpHeaders;
+import org.apache.olingo.odata2.api.edm.EdmEntityContainer;
+import org.apache.olingo.odata2.api.ep.EntityProvider;
+import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.testutil.helper.StringHelper;
 import org.apache.olingo.odata2.testutil.server.ServletType;
 import org.junit.Test;
 
@@ -37,15 +48,27 @@ public class FunctionImportJsonTest extends AbstractRefTest {
     super(servletType);
   }
 
+  private EdmEntityContainer getEntityContainer() throws Exception {
+    final HttpResponse response = callUri("$metadata"); 
+    final EdmEntityContainer entityContainer = EntityProvider.readMetadata(response.getEntity().getContent(), false)
+        .getDefaultEntityContainer();
+    getBody(response);
+    return entityContainer;
+  }
+
   @Test
-  public void functionImports() throws Exception {
-    HttpResponse response = callUri("EmployeeSearch?q='nat'&$format=json");
+  public void entityCollection() throws Exception {
+    final HttpResponse response = callUri("EmployeeSearch?q='nat'&$format=json");
     checkMediaType(response, HttpContentType.APPLICATION_JSON);
     final String body = getBody(response);
     assertEquals(getBody(callUri("Employees?$filter=substringof('nat',EmployeeName)&$format=json")), body);
+  }
 
-    response = callUri("AllLocations?$format=json");
+  @Test
+  public void complexTypeCollection() throws Exception {
+    final HttpResponse response = callUri("AllLocations?$format=json");
     checkMediaType(response, HttpContentType.APPLICATION_JSON);
+    final String body = getBody(response);
     assertEquals("{\"d\":{\"__metadata\":{\"type\":\"Collection(RefScenario.c_Location)\"},"
         + "\"results\":[{\"__metadata\":{\"type\":\"RefScenario.c_Location\"},"
         + "\"City\":{\"__metadata\":{\"type\":\"RefScenario.c_City\"},"
@@ -53,34 +76,91 @@ public class FunctionImportJsonTest extends AbstractRefTest {
         + "{\"__metadata\":{\"type\":\"RefScenario.c_Location\"},"
         + "\"City\":{\"__metadata\":{\"type\":\"RefScenario.c_City\"},"
         + "\"PostalCode\":\"69190\",\"CityName\":\"Walldorf\"},\"Country\":\"Germany\"}]}}",
-        getBody(response));
+        body);
+    final Object result = EntityProvider.readFunctionImport(HttpContentType.APPLICATION_JSON,
+        getEntityContainer().getFunctionImport("AllLocations"), StringHelper.encapsulate(body),
+        EntityProviderReadProperties.init().build());
+    assertNotNull(result);
+    final List<?> collection = (List<?>) result;
+    @SuppressWarnings("unchecked")
+    final Map<String, Object> secondLocation = (Map<String, Object>) collection.get(1);
+    @SuppressWarnings("unchecked")
+    final Map<String, Object> secondCity = (Map<String, Object>) secondLocation.get("City");
+    assertEquals(CITY_2_NAME, secondCity.get("CityName"));
+  }
 
-    response = callUri("AllUsedRoomIds?$format=json");
+  @Test
+  public void simpleTypeCollection() throws Exception {
+    final HttpResponse response = callUri("AllUsedRoomIds?$format=json");
     checkMediaType(response, HttpContentType.APPLICATION_JSON);
+    final String body = getBody(response);
     assertEquals("{\"d\":{\"__metadata\":{\"type\":\"Collection(Edm.String)\"},"
         + "\"results\":[\"1\",\"2\",\"3\"]}}",
-        getBody(response));
+        body);
+    final Object result = EntityProvider.readFunctionImport(HttpContentType.APPLICATION_JSON,
+        getEntityContainer().getFunctionImport("AllUsedRoomIds"), StringHelper.encapsulate(body),
+        EntityProviderReadProperties.init().build());
+    assertNotNull(result);
+    assertEquals(Arrays.asList("1", "2", "3"), result);
+  }
 
-    response = callUri("MaximalAge?$format=json");
+  @Test
+  public void simpleType() throws Exception {
+    final HttpResponse response = callUri("MaximalAge?$format=json");
     checkMediaType(response, HttpContentType.APPLICATION_JSON);
-    assertEquals("{\"d\":{\"MaximalAge\":56}}", getBody(response));
+    final String body = getBody(response);
+    assertEquals("{\"d\":{\"MaximalAge\":56}}", body);
+    final Object result = EntityProvider.readFunctionImport(HttpContentType.APPLICATION_JSON,
+        getEntityContainer().getFunctionImport("MaximalAge"), StringHelper.encapsulate(body),
+        EntityProviderReadProperties.init().build());
+    assertNotNull(result);
+    assertEquals(Short.valueOf(EMPLOYEE_3_AGE), result);
+  }
 
-    response = callUri("MostCommonLocation?$format=json");
+  @SuppressWarnings("unchecked")
+  @Test
+  public void complexType() throws Exception {
+    final HttpResponse response = callUri("MostCommonLocation?$format=json");
     checkMediaType(response, HttpContentType.APPLICATION_JSON);
+    final String body = getBody(response);
     assertEquals("{\"d\":{\"MostCommonLocation\":"
         + "{\"__metadata\":{\"type\":\"RefScenario.c_Location\"},"
         + "\"City\":{\"__metadata\":{\"type\":\"RefScenario.c_City\"},"
         + "\"PostalCode\":\"69190\",\"CityName\":\"" + CITY_2_NAME + "\"},"
         + "\"Country\":\"Germany\"}}}",
-        getBody(response));
+        body);
+    final Object result = EntityProvider.readFunctionImport(HttpContentType.APPLICATION_JSON,
+        getEntityContainer().getFunctionImport("MostCommonLocation"), StringHelper.encapsulate(body),
+        EntityProviderReadProperties.init().build());
+    assertNotNull(result);
+    Map<String, Object> resultMap = (Map<String, Object>) result;
+    assertNotNull(resultMap);
+    assertFalse(resultMap.isEmpty());
+    resultMap = (Map<String, Object>) resultMap.get("City");
+    assertNotNull(resultMap);
+    assertFalse(resultMap.isEmpty());
+    assertEquals(CITY_2_NAME, resultMap.get("CityName"));
+  }
 
-    response = callUri("ManagerPhoto?Id='1'&$format=json");
+  @Test
+  public void binary() throws Exception {
+    final HttpResponse response = callUri("ManagerPhoto?Id='1'&$format=json");
     checkMediaType(response, HttpContentType.APPLICATION_JSON);
     assertTrue(getBody(response).startsWith("{\"d\":{\"ManagerPhoto\":\"iVBORw0KGgoAAAAN"));
+  }
 
+  @Test
+  public void entity() throws Exception {
     final String expected = getBody(callUri("Employees('3')?$format=json"));
-    response = callUri("OldestEmployee", HttpHeaders.ACCEPT, HttpContentType.APPLICATION_JSON);
+    final HttpResponse response = callUri("OldestEmployee", HttpHeaders.ACCEPT, HttpContentType.APPLICATION_JSON);
     checkMediaType(response, HttpContentType.APPLICATION_JSON);
-    assertEquals(expected, getBody(response));
+    final String body = getBody(response);
+    assertEquals(expected, body);
+    final Object result = EntityProvider.readFunctionImport(HttpContentType.APPLICATION_JSON,
+        getEntityContainer().getFunctionImport("OldestEmployee"), StringHelper.encapsulate(body),
+        EntityProviderReadProperties.init().build());
+    assertNotNull(result);
+    final ODataEntry entry = (ODataEntry) result;
+    assertEquals("3", entry.getProperties().get("EmployeeId"));
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6fd6f064/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportXmlTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportXmlTest.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportXmlTest.java
index bdf62e5..fdf43e5 100644
--- a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportXmlTest.java
+++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/FunctionImportXmlTest.java
@@ -25,12 +25,21 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
 import junit.framework.Assert;
 
 import org.apache.http.HttpResponse;
 import org.apache.olingo.odata2.api.commons.HttpContentType;
 import org.apache.olingo.odata2.api.commons.HttpHeaders;
+import org.apache.olingo.odata2.api.edm.EdmEntityContainer;
+import org.apache.olingo.odata2.api.ep.EntityProvider;
+import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
 import org.apache.olingo.odata2.core.commons.ContentType;
+import org.apache.olingo.odata2.testutil.helper.StringHelper;
 import org.apache.olingo.odata2.testutil.server.ServletType;
 import org.junit.Test;
 
@@ -55,11 +64,32 @@ public class FunctionImportXmlTest extends AbstractRefXmlTest {
 
     response = callUri("AllLocations", HttpHeaders.ACCEPT, HttpContentType.APPLICATION_XML);
     checkMediaType(response, HttpContentType.APPLICATION_XML_UTF8);
-    assertXpathExists("/d:AllLocations/d:element/d:City[d:CityName=\"" + CITY_2_NAME + "\"]", getBody(response));
+    String body = getBody(response);
+    assertXpathExists("/d:AllLocations/d:element/d:City[d:CityName=\"" + CITY_2_NAME + "\"]", body);
+    final HttpResponse metadataResponse = callUri("$metadata"); 
+    final EdmEntityContainer entityContainer = EntityProvider.readMetadata(metadataResponse.getEntity().getContent(),
+        false).getDefaultEntityContainer();
+    getBody(metadataResponse);
+    Object result = EntityProvider.readFunctionImport(HttpContentType.APPLICATION_XML,
+        entityContainer.getFunctionImport("AllLocations"), StringHelper.encapsulate(body),
+        EntityProviderReadProperties.init().build());
+    assertNotNull(result);
+    final List<?> collection = (List<?>) result;
+    @SuppressWarnings("unchecked")
+    final Map<String, Object> secondLocation = (Map<String, Object>) collection.get(1);
+    @SuppressWarnings("unchecked")
+    final Map<String, Object> secondCity = (Map<String, Object>) secondLocation.get("City");
+    assertEquals(CITY_2_NAME, secondCity.get("CityName"));
 
     response = callUri("AllUsedRoomIds", HttpHeaders.ACCEPT, HttpContentType.APPLICATION_XML);
     checkMediaType(response, HttpContentType.APPLICATION_XML_UTF8);
-    assertXpathExists("/d:AllUsedRoomIds[d:element=\"3\"]", getBody(response));
+    body = getBody(response);
+    assertXpathExists("/d:AllUsedRoomIds[d:element=\"3\"]", body);
+    result = EntityProvider.readFunctionImport(HttpContentType.APPLICATION_XML,
+        entityContainer.getFunctionImport("AllUsedRoomIds"), StringHelper.encapsulate(body),
+        EntityProviderReadProperties.init().build());
+    assertNotNull(result);
+    assertEquals(Arrays.asList("1", "2", "3"), result);
 
     response = callUri("MaximalAge", HttpHeaders.ACCEPT, HttpContentType.APPLICATION_XML);
     checkMediaType(response, HttpContentType.APPLICATION_XML_UTF8);