[OLINGO-882] Merge branch 'master' into OLINGO-882_EnableContainerManagedPersistence
diff --git a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/exception/ODataJPARuntimeException.java b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/exception/ODataJPARuntimeException.java
index 0b9c3b2..dd70e8d 100644
--- a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/exception/ODataJPARuntimeException.java
+++ b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/exception/ODataJPARuntimeException.java
@@ -72,6 +72,8 @@
       "ERROR_JPA_CLOB_NULL");
   public static final MessageReference OPERATOR_EQ_NE_MISSING = createMessageReference(ODataJPARuntimeException.class,
       "OPERATOR_EQ_NE_MISSING");
+  public static final MessageReference FILTER_ON_NAVIGATION_NOT_SUPPORTED =
+      createMessageReference(ODataJPARuntimeException.class, "FILTER_ON_NAVIGATION_NOT_SUPPORTED");
 
   private ODataJPARuntimeException(final String localizedMessage, final Throwable e, final MessageReference msgRef) {
     super(localizedMessage, e, msgRef);
diff --git a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/model/JPAEdmMapping.java b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/model/JPAEdmMapping.java
index 44f0f29..27fb683 100644
--- a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/model/JPAEdmMapping.java
+++ b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/model/JPAEdmMapping.java
@@ -75,5 +75,9 @@
    * @return JPA EntityListener type
    */
   public Class<? extends ODataJPATombstoneEntityListener> getODataJPATombstoneEntityListener();
+  
+  public boolean isVirtualAccess();
+  
+  public void setVirtualAccess(boolean virtualAccess);
 
 }
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataEntityParser.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataEntityParser.java
index a6ec241..9977219 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataEntityParser.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataEntityParser.java
@@ -115,9 +115,9 @@
       final String serviceRoot = odataContext.getPathInfo().getServiceRoot().toString();
       final String path =
           uriString.startsWith(serviceRoot.toString()) ? uriString.substring(serviceRoot.length()) : uriString;
-      final PathSegment pathSegment = getPathSegment(path);
+      final List<PathSegment> pathSegment = getPathSegment(path);
       edm = getEdm();
-      uri = UriParser.parse(edm, Arrays.asList(pathSegment), Collections.<String, String> emptyMap());
+      uri = UriParser.parse(edm, pathSegment, Collections.<String, String> emptyMap());
     } catch (ODataException e) {
       throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e);
     }
@@ -128,8 +128,8 @@
       throws ODataJPARuntimeException {
     List<PathSegment> pathSegments = new ArrayList<PathSegment>();
     for (String link : linkSegments) {
-      PathSegment pathSegment = getPathSegment(link);
-      pathSegments.add(pathSegment);
+      List<PathSegment> pathSegment = getPathSegment(link);
+      pathSegments.addAll(pathSegment);
     }
     UriInfo uriInfo = null;
     try {
@@ -143,11 +143,11 @@
 
   public UriInfo parseBindingLink(final String link, final Map<String, String> options)
       throws ODataJPARuntimeException {
-    final PathSegment pathSegment = getPathSegment(link);
+    final List<PathSegment> pathSegment = getPathSegment(link);
     UriInfo uriInfo = null;
     try {
       edm = getEdm();
-      uriInfo = UriParser.parse(edm, Arrays.asList(pathSegment), options);
+      uriInfo = UriParser.parse(edm, pathSegment, options);
     } catch (ODataException e) {
       throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e);
     }
@@ -161,19 +161,26 @@
     return edm;
   }
 
-  private PathSegment getPathSegment(final String path) {
-    final PathSegment pathSegment = new PathSegment() {
+  private List<PathSegment> getPathSegment(final String path) {
+    String trimmedPath = path.replace(serviceRoot, "");
 
-      @Override
-      public String getPath() {
-        return path.replace(serviceRoot, "");
-      }
+    final String[] splittedPath = trimmedPath.split("/");
+    final List<PathSegment> pathSegments = new ArrayList<PathSegment>();
 
-      @Override
-      public Map<String, List<String>> getMatrixParameters() {
-        return null;
-      }
-    };
-    return pathSegment;
+    for (final String pathSegmentString : splittedPath) {
+      final PathSegment pathSegment = new PathSegment() {
+        @Override
+        public String getPath() {
+          return pathSegmentString;
+        }
+        @Override
+        public Map<String, List<String>> getMatrixParameters() {
+          return null;
+        }
+      };
+      pathSegments.add(pathSegment);
+    }
+
+    return pathSegments;
   }
 }
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataExpressionParser.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataExpressionParser.java
index e733337..79905ce 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataExpressionParser.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataExpressionParser.java
@@ -27,10 +27,12 @@
 import org.apache.olingo.odata2.api.edm.EdmLiteral;
 import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
 import org.apache.olingo.odata2.api.edm.EdmMapping;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
 import org.apache.olingo.odata2.api.edm.EdmProperty;
 import org.apache.olingo.odata2.api.edm.EdmSimpleType;
 import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
 import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.edm.EdmTyped;
 import org.apache.olingo.odata2.api.exception.ODataException;
 import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
 import org.apache.olingo.odata2.api.uri.KeyPredicate;
@@ -135,11 +137,14 @@
             + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT;
       case EQ:
         return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + JPQLStatement.DELIMITER.SPACE
-            + JPQLStatement.Operator.EQ + JPQLStatement.DELIMITER.SPACE + right
+            + (!"null".equals(right) ? JPQLStatement.Operator.EQ : "IS") + JPQLStatement.DELIMITER.SPACE + right
             + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT;
       case NE:
         return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + JPQLStatement.DELIMITER.SPACE
-            + JPQLStatement.Operator.NE + JPQLStatement.DELIMITER.SPACE + right
+            + (!"null".equals(right) ?
+                JPQLStatement.Operator.NE :
+                "IS" + JPQLStatement.DELIMITER.SPACE + JPQLStatement.Operator.NOT)
+            + JPQLStatement.DELIMITER.SPACE + right
             + JPQLStatement.DELIMITER.PARENTHESIS_RIGHT;
       case LT:
         return JPQLStatement.DELIMITER.PARENTHESIS_LEFT + left + JPQLStatement.DELIMITER.SPACE
@@ -210,10 +215,11 @@
       case SUBSTRINGOF:
         if (methodFlag.get() != null && methodFlag.get() == 1) {
           methodFlag.set(null);
-          return String.format("(CASE WHEN (%s LIKE CONCAT('%%',%s,'%%')) THEN TRUE ELSE FALSE END)", second, first);
+          return String.format("(CASE WHEN (%s LIKE CONCAT('%%',CONCAT(%s,'%%'))) THEN TRUE ELSE FALSE END)",
+              second, first);
         } else {
-          return String.format("(CASE WHEN (%s LIKE CONCAT('%%',%s,'%%')) THEN TRUE ELSE FALSE END) = true", second,
-              first);
+          return String.format("(CASE WHEN (%s LIKE CONCAT('%%',CONCAT(%s,'%%'))) THEN TRUE ELSE FALSE END) = true",
+              second, first);
         }
       case TOLOWER:
         return String.format("LOWER(%s)", first);
@@ -427,14 +433,20 @@
         throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.GENERAL.addContent(e.getMessage()), e);
       }
 
-    } else if (edmSimpleType.getDefaultType().equals(Long.class)) {
+    } else if (Long.class.equals(edmSimpleType.getDefaultType())) {
       uriLiteral = uriLiteral + JPQLStatement.DELIMITER.LONG; //$NON-NLS-1$
     }
     return uriLiteral;
   }
 
-  private static String getPropertyName(final CommonExpression whereExpression) throws EdmException {
-    EdmProperty property = ((EdmProperty) ((PropertyExpression) whereExpression).getEdmProperty());
+  private static String getPropertyName(final CommonExpression whereExpression) throws EdmException,
+      ODataJPARuntimeException {
+    EdmTyped edmProperty  = ((PropertyExpression) whereExpression).getEdmProperty();
+    if (edmProperty instanceof EdmNavigationProperty) {
+      throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.FILTER_ON_NAVIGATION_NOT_SUPPORTED, null);
+    }
+
+    EdmProperty property = ((EdmProperty) edmProperty);
     EdmMapping mapping = property.getMapping();
     String name = mapping != null ? mapping.getInternalName() : property.getName();
     return name;
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderDefault.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderDefault.java
index 3b43001..0517e48 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderDefault.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderDefault.java
@@ -622,12 +622,12 @@
       for (EdmProperty keyProperty : entity.getKeyProperties()) {
         flag = true;
         for (SelectItem selectedItem : selectItems) {
-          if (selectedItem.isStar() == false && selectedItem.getProperty().equals(keyProperty)) {
+          if (!selectedItem.isStar() && keyProperty.equals(selectedItem.getProperty())) {
             flag = false;
             break;
           }
         }
-        if (flag == true) {
+        if (flag) {
           selectPropertyList.add(keyProperty);
         }
       }
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java
index 07564d5..793e151 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntity.java
@@ -49,6 +49,7 @@
 import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
 import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
 import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
+import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmMappingImpl;
 
 public class JPAEntity {
 
@@ -204,87 +205,19 @@
     this.jpaEntity = jpaEntity;
   }
 
-  @SuppressWarnings("unchecked")
   protected void setComplexProperty(Method accessModifier, final Object jpaEntity,
       final EdmStructuralType edmComplexType, final HashMap<String, Object> propertyValue)
       throws EdmException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
       InstantiationException, ODataJPARuntimeException, NoSuchMethodException, SecurityException, SQLException {
 
-    JPAEdmMapping mapping = (JPAEdmMapping) edmComplexType.getMapping();
-    Object embeddableObject = mapping.getJPAType().newInstance();
-    accessModifier.invoke(jpaEntity, embeddableObject);
-
-    HashMap<String, Method> accessModifiers =
-        jpaEntityParser.getAccessModifiers(embeddableObject, edmComplexType, JPAEntityParser.ACCESS_MODIFIER_SET);
-
-    for (String edmPropertyName : edmComplexType.getPropertyNames()) {
-      EdmTyped edmTyped = (EdmTyped) edmComplexType.getProperty(edmPropertyName);
-      accessModifier = accessModifiers.get(edmPropertyName);
-      if (edmTyped.getType().getKind().toString().equals(EdmTypeKind.COMPLEX.toString())) {
-        EdmStructuralType structualType = (EdmStructuralType) edmTyped.getType();
-        setComplexProperty(accessModifier, embeddableObject, structualType, (HashMap<String, Object>) propertyValue
-            .get(edmPropertyName));
-      } else {
-        setProperty(accessModifier, embeddableObject, propertyValue.get(edmPropertyName), (EdmSimpleType) edmTyped
-            .getType());
-      }
-    }
+    setComplexProperty(accessModifier, jpaEntity, edmComplexType, propertyValue, null);
   }
 
-  @SuppressWarnings({ "unchecked", "rawtypes" })
   protected void setProperty(final Method method, final Object entity, final Object entityPropertyValue,
       final EdmSimpleType type) throws
       IllegalAccessException, IllegalArgumentException, InvocationTargetException, ODataJPARuntimeException {
-    if (entityPropertyValue != null) {
-      Class<?> parameterType = method.getParameterTypes()[0];
-      if (type != null && type.getDefaultType().equals(String.class)) {
-        if (parameterType.equals(String.class)) {
-          method.invoke(entity, entityPropertyValue);
-        } else if (parameterType.equals(char[].class)) {
-          char[] characters = ((String) entityPropertyValue).toCharArray();
-          method.invoke(entity, characters);
-        } else if (parameterType.equals(char.class)) {
-          char c = ((String) entityPropertyValue).charAt(0);
-          method.invoke(entity, c);
-        } else if (parameterType.equals(Character[].class)) {
-          Character[] characters = JPAEntityParser.toCharacterArray((String) entityPropertyValue);
-          method.invoke(entity, (Object) characters);
-        } else if (parameterType.equals(Character.class)) {
-          Character c = Character.valueOf(((String) entityPropertyValue).charAt(0));
-          method.invoke(entity, c);
-        } else if (parameterType.isEnum()) {
-          Enum e = Enum.valueOf((Class<Enum>) parameterType, (String) entityPropertyValue);
-          method.invoke(entity, e);
-        }
-      } else if (parameterType.equals(Blob.class)) {
-        if (onJPAWriteContent == null) {
-          throw ODataJPARuntimeException
-              .throwException(ODataJPARuntimeException.ERROR_JPA_BLOB_NULL, null);
-        } else {
-          method.invoke(entity, onJPAWriteContent.getJPABlob((byte[]) entityPropertyValue));
-        }
-      } else if (parameterType.equals(Clob.class)) {
-        if (onJPAWriteContent == null) {
-          throw ODataJPARuntimeException
-              .throwException(ODataJPARuntimeException.ERROR_JPA_CLOB_NULL, null);
-        } else {
-          method.invoke(entity, onJPAWriteContent.getJPAClob(((String) entityPropertyValue).toCharArray()));
-        }
-      } else if (parameterType.equals(Timestamp.class)) {
-        Timestamp ts = new Timestamp(((Calendar) entityPropertyValue).getTimeInMillis());
-        method.invoke(entity, ts);
-      } else if (parameterType.equals(java.util.Date.class)) {
-        method.invoke(entity, ((Calendar) entityPropertyValue).getTime());
-      } else if (parameterType.equals(java.sql.Date.class)) {
-        long timeInMs = ((Calendar) entityPropertyValue).getTimeInMillis();
-        method.invoke(entity, new java.sql.Date(timeInMs));
-      } else if (parameterType.equals(java.sql.Time.class)) {
-        long timeInMs = ((Calendar) entityPropertyValue).getTimeInMillis();
-        method.invoke(entity, new java.sql.Time(timeInMs));
-      } else {
-        method.invoke(entity, entityPropertyValue);
-      }
-    }
+
+    setProperty(method, entity, entityPropertyValue, type, null);
   }
 
   protected void setEmbeddableKeyProperty(final HashMap<String, String> embeddableKeys,
@@ -408,9 +341,14 @@
         propertyNames = oDataEntryProperties.keySet();
       }
 
+      boolean isVirtual = false;
       for (String propertyName : propertyNames) {
         EdmTyped edmTyped = (EdmTyped) oDataEntityType.getProperty(propertyName);
-
+        if (edmTyped instanceof EdmProperty) {
+          isVirtual = ((JPAEdmMappingImpl)((EdmProperty) edmTyped).getMapping()).isVirtualAccess();
+        } else {
+          isVirtual = false;
+        }
         Method accessModifier = null;
 
         switch (edmTyped.getType().getKind()) {
@@ -421,16 +359,26 @@
             }
           }
           accessModifier = accessModifiersWrite.get(propertyName);
-          setProperty(accessModifier, jpaEntity, oDataEntryProperties.get(propertyName), (EdmSimpleType) edmTyped
-              .getType());
-
+          if (isVirtual) {
+            setProperty(accessModifier, jpaEntity, oDataEntryProperties.get(propertyName), (EdmSimpleType) edmTyped
+                .getType(), propertyName);
+          } else {
+            setProperty(accessModifier, jpaEntity, oDataEntryProperties.get(propertyName), (EdmSimpleType) edmTyped
+                .getType());
+          }
           break;
         case COMPLEX:
           structuralType = (EdmStructuralType) edmTyped.getType();
           accessModifier = accessModifiersWrite.get(propertyName);
-          setComplexProperty(accessModifier, jpaEntity,
-              structuralType,
-              (HashMap<String, Object>) oDataEntryProperties.get(propertyName));
+          if (isVirtual) {
+            setComplexProperty(accessModifier, jpaEntity,
+                structuralType,
+                (HashMap<String, Object>) oDataEntryProperties.get(propertyName), propertyName);
+          } else {
+            setComplexProperty(accessModifier, jpaEntity,
+                structuralType,
+                (HashMap<String, Object>) oDataEntryProperties.get(propertyName));
+          }
           break;
         case NAVIGATION:
         case ENTITY:
@@ -475,4 +423,102 @@
               .addContent(e.getMessage()), e);
     }
   }
+
+  @SuppressWarnings("unchecked")
+  protected void setComplexProperty(Method accessModifier, final Object jpaEntity,
+      final EdmStructuralType edmComplexType, final HashMap<String, Object> propertyValue, String propertyName)
+      throws EdmException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
+      InstantiationException, ODataJPARuntimeException, NoSuchMethodException, SecurityException, SQLException {
+
+    JPAEdmMapping mapping = (JPAEdmMapping) edmComplexType.getMapping();
+    Object embeddableObject = mapping.getJPAType().newInstance();
+    accessModifier.invoke(jpaEntity, embeddableObject);
+
+    HashMap<String, Method> accessModifiers =
+        jpaEntityParser.getAccessModifiers(embeddableObject, edmComplexType,
+            JPAEntityParser.ACCESS_MODIFIER_SET);
+
+    for (String edmPropertyName : edmComplexType.getPropertyNames()) {
+      EdmTyped edmTyped = (EdmTyped) edmComplexType.getProperty(edmPropertyName);
+      accessModifier = accessModifiers.get(edmPropertyName);
+      if (edmTyped.getType().getKind().toString().equals(EdmTypeKind.COMPLEX.toString())) {
+        EdmStructuralType structualType = (EdmStructuralType) edmTyped.getType();
+        if (propertyName != null) {
+          setComplexProperty(accessModifier, embeddableObject, structualType,
+              (HashMap<String, Object>) propertyValue.get(edmPropertyName), propertyName);
+        } else {
+          setComplexProperty(accessModifier, embeddableObject, structualType,
+              (HashMap<String, Object>) propertyValue.get(edmPropertyName));
+        }
+      } else {
+        if (propertyName != null) {
+          setProperty(accessModifier, embeddableObject, propertyValue.get(edmPropertyName),
+              (EdmSimpleType) edmTyped.getType(), propertyName);
+        } else {
+          setProperty(accessModifier, embeddableObject, propertyValue.get(edmPropertyName),
+              (EdmSimpleType) edmTyped.getType());
+        }
+      }
+    }
+  }
+
+  @SuppressWarnings({ "unchecked", "rawtypes" })
+  protected void setProperty(final Method method, final Object entity, final Object entityPropertyValue,
+      final EdmSimpleType type, String propertyName) throws
+      IllegalAccessException, IllegalArgumentException, InvocationTargetException, ODataJPARuntimeException {
+    if (entityPropertyValue != null) {
+      if (propertyName != null) {
+        method.invoke(entity, propertyName, entityPropertyValue);
+        return;
+      }
+      Class<?> parameterType = method.getParameterTypes()[0];
+      if (type != null && type.getDefaultType().equals(String.class)) {
+        if (parameterType.equals(String.class)) {
+          method.invoke(entity, entityPropertyValue);
+        } else if (parameterType.equals(char[].class)) {
+          char[] characters = ((String) entityPropertyValue).toCharArray();
+          method.invoke(entity, characters);
+        } else if (parameterType.equals(char.class)) {
+          char c = ((String) entityPropertyValue).charAt(0);
+          method.invoke(entity, c);
+        } else if (parameterType.equals(Character[].class)) {
+          Character[] characters = JPAEntityParser.toCharacterArray((String) entityPropertyValue);
+          method.invoke(entity, (Object) characters);
+        } else if (parameterType.equals(Character.class)) {
+          Character c = Character.valueOf(((String) entityPropertyValue).charAt(0));
+          method.invoke(entity, c);
+        } else if (parameterType.isEnum()) {
+          Enum e = Enum.valueOf((Class<Enum>) parameterType, (String) entityPropertyValue);
+          method.invoke(entity, e);
+        }
+      } else if (parameterType.equals(Blob.class)) {
+        if (onJPAWriteContent == null) {
+          throw ODataJPARuntimeException
+              .throwException(ODataJPARuntimeException.ERROR_JPA_BLOB_NULL, null);
+        } else {
+          method.invoke(entity, onJPAWriteContent.getJPABlob((byte[]) entityPropertyValue));
+        }
+      } else if (parameterType.equals(Clob.class)) {
+        if (onJPAWriteContent == null) {
+          throw ODataJPARuntimeException
+              .throwException(ODataJPARuntimeException.ERROR_JPA_CLOB_NULL, null);
+        } else {
+          method.invoke(entity, onJPAWriteContent.getJPAClob(((String) entityPropertyValue).toCharArray()));
+        }
+      } else if (parameterType.equals(Timestamp.class)) {
+        Timestamp ts = new Timestamp(((Calendar) entityPropertyValue).getTimeInMillis());
+        method.invoke(entity, ts);
+      } else if (parameterType.equals(java.util.Date.class)) {
+        method.invoke(entity, ((Calendar) entityPropertyValue).getTime());
+      } else if (parameterType.equals(java.sql.Date.class)) {
+        long timeInMs = ((Calendar) entityPropertyValue).getTimeInMillis();
+        method.invoke(entity, new java.sql.Date(timeInMs));
+      } else if (parameterType.equals(java.sql.Time.class)) {
+        long timeInMs = ((Calendar) entityPropertyValue).getTimeInMillis();
+        method.invoke(entity, new java.sql.Time(timeInMs));
+      } else {
+        method.invoke(entity, entityPropertyValue);
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParser.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParser.java
index 03ef879..4c1d439 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParser.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParser.java
@@ -116,7 +116,7 @@
             propertyValue = getEmbeddablePropertyValue(methodName, propertyValue);
           }
         } else {
-          propertyValue = getPropertyValue(accessModifierMap.get(propertyName), propertyValue);
+          propertyValue = getPropertyValue(accessModifierMap.get(propertyName), propertyValue, propertyName);
         }
         if (property.getType().getKind()
             .equals(EdmTypeKind.COMPLEX)) {
@@ -169,17 +169,24 @@
     if (navigationPropertyList != null
         && navigationPropertyList.size() != 0) {
 
-      try {
-        for (EdmNavigationProperty navigationProperty : navigationPropertyList) {
-          methodName = getAccessModifierName(navigationProperty.getName(),
-              navigationProperty.getMapping(), ACCESS_MODIFIER_GET);
-          Method getterMethod = jpaEntity.getClass()
-              .getMethod(methodName, (Class<?>[]) null);
-          getterMethod.setAccessible(true);
-          result = getPropertyValue(getterMethod, jpaEntity);
-          navigationMap.put(navigationProperty.getName(), result);
-        }
-      } catch (IllegalArgumentException e) {
+    	try {
+    		for (EdmNavigationProperty navigationProperty : navigationPropertyList) {
+    			methodName = getAccessModifierName(navigationProperty.getName(),
+    					navigationProperty.getMapping(), ACCESS_MODIFIER_GET);
+    			Method getterMethod = null;
+    			if(((JPAEdmMapping)navigationProperty.getMapping()).isVirtualAccess()) {
+    				getterMethod = jpaEntity.getClass().getMethod(ACCESS_MODIFIER_GET, String.class);
+    			}else{
+    				getterMethod = jpaEntity.getClass()
+    						.getMethod(methodName, (Class<?>[]) null);
+    			}
+
+    			getterMethod.setAccessible(true);
+    			result = getPropertyValue(getterMethod, jpaEntity,
+    					navigationProperty.getMapping().getInternalName());
+    			navigationMap.put(navigationProperty.getName(), result);
+    		}
+    	} catch (IllegalArgumentException e) {
         throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
       } catch (EdmException e) {
         throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
@@ -215,7 +222,8 @@
     return getAccessModifiers(getEdmProperties(structuralType), jpaEntity.getClass(), accessModifier);
   }
 
-  public static Object getPropertyValue(final Method method, final Object entity) throws ODataJPARuntimeException {
+  public static Object getPropertyValue(final Method method, final Object entity, String propertyName) 
+		  throws ODataJPARuntimeException {
     Object propertyValue = null;
     if (method == null) {
       return null;
@@ -246,7 +254,11 @@
       } else if (returnType.equals(Clob.class)) {
         propertyValue = getString((Clob) method.invoke(entity));
       } else {
-        propertyValue = method.invoke(entity);
+    	  if(method.getParameterTypes().length>0) {
+    		  propertyValue = method.invoke(entity,propertyName);
+    	  } else {
+    		  propertyValue = method.invoke(entity);
+    	  }
       }
     } catch (IllegalAccessException e) {
       throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
@@ -393,7 +405,7 @@
         }
         method = propertyValue.getClass().getMethod(namePart, (Class<?>[]) null);
         method.setAccessible(true);
-        propertyValue = getPropertyValue(method, propertyValue);
+        propertyValue = getPropertyValue(method, propertyValue,namePart);
       }
     } catch (NoSuchMethodException e) {
       throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, e);
@@ -541,13 +553,23 @@
               continue;
             }
           } else {
-            if (accessModifier.equals(ACCESS_MODIFIER_SET)) {
-              JPAEdmMapping jpaEdmMapping = (JPAEdmMapping) property.getMapping();
-              accessModifierMap.put(propertyName, jpaEntityType.getMethod(methodName,
-                  new Class<?>[] { jpaEdmMapping.getJPAType() }));
-            } else {
-              method = jpaEntityType.getMethod(methodName, (Class<?>[]) null);
-            }
+        	  if (accessModifier.equals(ACCESS_MODIFIER_SET)) {
+        		  JPAEdmMapping jpaEdmMapping = (JPAEdmMapping) property.getMapping();
+        		  if(jpaEdmMapping.isVirtualAccess()) {
+        			  accessModifierMap.put(propertyName, jpaEntityType.getMethod(ACCESS_MODIFIER_SET,
+        					  new Class<?>[] { String.class,Object.class }));
+        		  }else {
+        			  accessModifierMap.put(propertyName, jpaEntityType.getMethod(methodName,
+        					  new Class<?>[] { jpaEdmMapping.getJPAType() }));
+        		  }
+        	  } else {
+        		  JPAEdmMapping jpaEdmMapping = (JPAEdmMapping) property.getMapping();
+        		  if(jpaEdmMapping.isVirtualAccess()) {
+        			  method = jpaEntityType.getMethod(ACCESS_MODIFIER_GET, String.class);
+        		  }else{
+        			  method = jpaEntityType.getMethod(methodName, (Class<?>[]) null);
+        		  }
+        	  }
           }
         } catch (EdmException exp) {
           throw ODataJPARuntimeException.throwException(ODataJPARuntimeException.INNER_EXCEPTION, exp);
diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmMappingImpl.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmMappingImpl.java
index 5944191..b07c7ca 100644
--- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmMappingImpl.java
+++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmMappingImpl.java
@@ -27,6 +27,7 @@
   private String columnName = null;
   private Class<?> type = null;
   private Class<? extends ODataJPATombstoneEntityListener> entityListener = null;
+  private boolean isVirtualAccess;
 
   @Override
   public void setJPAColumnName(final String name) {
@@ -60,4 +61,14 @@
   public Class<? extends ODataJPATombstoneEntityListener> getODataJPATombstoneEntityListener() {
     return entityListener;
   }
+
+  @Override
+  public boolean isVirtualAccess() {
+	  return isVirtualAccess;
+  }
+
+  @Override
+  public void setVirtualAccess(boolean virtualAccess) {
+	  this.isVirtualAccess=virtualAccess;
+  }
 }
diff --git a/odata2-jpa-processor/jpa-core/src/main/resources/jpaprocessor_msg.properties b/odata2-jpa-processor/jpa-core/src/main/resources/jpaprocessor_msg.properties
index 7b4bb95..a5a115c 100644
--- a/odata2-jpa-processor/jpa-core/src/main/resources/jpaprocessor_msg.properties
+++ b/odata2-jpa-processor/jpa-core/src/main/resources/jpaprocessor_msg.properties
@@ -58,6 +58,7 @@
 org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException.ERROR_JPA_BLOB_NULL="OData - JPA Runtime: Blob data type is null. Initialize Blob type by implementing callback interface org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent.
 org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException.ERROR_JPA_CLOB_NULL="OData - JPA Runtime: Clob data type is null. Initialize Clob type by implementing callback interface org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent.
 org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException.OPERATOR_EQ_NE_MISSING="OData - JPA Runtime: OData Expression parser - Operator EQ or NE missing"
+org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException.FILTER_ON_NAVIGATION_NOT_SUPPORTED="OData - JPA Runtime: OData Expression parser - Filter expressions with navigation are currently not supported"
 
 #JPA Common Errors
 org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAException.ODATA_JPACTX_NULL="OData JPA: OData JPA Context cannot be null"
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataFilterExpressionParserTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataFilterExpressionParserTest.java
index 8d1d38e..a29ba5c 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataFilterExpressionParserTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataFilterExpressionParserTest.java
@@ -49,7 +49,7 @@
   private static final String[] EXPRESSION_BINARY_AND =
   {
       "id le '123' and soId eq 123L and not (substringof(id,'123') eq false) eq true",
-      "(((E1.id <= '123') AND (E1.soId = 123L)) AND (NOT(((CASE WHEN ('123' LIKE CONCAT('%',E1.id,'%')) "
+      "(((E1.id <= '123') AND (E1.soId = 123L)) AND (NOT(((CASE WHEN ('123' LIKE CONCAT('%',CONCAT(E1.id,'%'))) "
           + "THEN TRUE ELSE FALSE END) = false)) = true))" };
   private static final String[] EXPRESSION_BINARY_OR = { "id ge '123' or soId gt 123L",
       "((E1.id >= '123') OR (E1.soId > 123L))" };
@@ -68,22 +68,23 @@
       "(SUBSTRING(E1.oValue.Currency, 2 + 1 ) NOT LIKE CONCAT('%','INR') )" };
   private static final String[] EXPRESSION_SUBSTRING_OF = {
       "substringof(id,'123') ne true",
-      "((CASE WHEN ('123' LIKE CONCAT('%',E1.id,'%')) THEN TRUE ELSE FALSE END) <> true)" };
+      "((CASE WHEN ('123' LIKE CONCAT('%',CONCAT(E1.id,'%'))) THEN TRUE ELSE FALSE END) <> true)" };
   private static final String[] EXPRESSION_STARTS_WITH_WRONG_OP = { "startswith(oValue/Currency,'INR') lt true", "" };
   private static final String[] EXPRESSION_SUBSTRING_ALL_OP = { "substring(oValue/Currency,1,3) eq 'INR'",
       "(SUBSTRING(E1.oValue.Currency, 1 + 1 , 3) = 'INR')" };
   private static final String[] EXPRESSION_SUBSTRINGOF_INJECTION1 = {
       "substringof('a'' OR 1=1 OR E1.id LIKE ''b',id) eq true",
-      "((CASE WHEN (E1.id LIKE CONCAT('%','a'' OR 1=1 OR E1.id LIKE ''b','%')) THEN TRUE ELSE FALSE END) = true)" };
+      "((CASE WHEN (E1.id LIKE CONCAT('%',CONCAT('a'' OR 1=1 OR E1.id LIKE ''b','%'))) "
+          + "THEN TRUE ELSE FALSE END) = true)" };
   private static final String[] EXPRESSION_SUBSTRINGOF_INJECTION2 =
   {
       "substringof('substringof(''a'' OR 1=1 OR E1.id LIKE ''b'',id)',id) eq true",
-      "((CASE WHEN (E1.id LIKE CONCAT('%','substringof(''a'' OR 1=1 OR E1.id LIKE ''b'',id)','%')) "
+      "((CASE WHEN (E1.id LIKE CONCAT('%',CONCAT('substringof(''a'' OR 1=1 OR E1.id LIKE ''b'',id)','%'))) "
           + "THEN TRUE ELSE FALSE END) = true)" };
   private static final String[] EXPRESSION_SUBSTRINGOF_INJECTION3 =
   {
       "substringof( substring(' ) OR execute_my_sql OR '' LIKE ',3),'de''') eq true",
-      "((CASE WHEN ('de''' LIKE CONCAT('%',SUBSTRING(' ) OR execute_my_sql OR '' LIKE ', 3 + 1 ),'%')) "
+      "((CASE WHEN ('de''' LIKE CONCAT('%',CONCAT(SUBSTRING(' ) OR execute_my_sql OR '' LIKE ', 3 + 1 ),'%'))) "
           + "THEN TRUE ELSE FALSE END) = true)" };
   private static final String[] EXPRESSION_ENDSWITH_INJECTION1 = { "endswith(id,'Str''eet') eq true",
       "(E1.id LIKE CONCAT('%','Str''eet') )" };
@@ -92,6 +93,11 @@
       "(((E1.id = '123') AND (E1.id <> '123')) OR ((E1.id = '123') AND (E1.id <> '123')))" };
   private static final String[] EXPRESSION_DATETIME = { "date eq datetime'2000-01-01T00:00:00'",
       "(E1.date = {ts '2000-01-01 00:00:00.000'})" };
+  
+  private static final String[] EXPRESSION_NULL = { "date eq null", "(E1.date IS null)" };
+
+  private static final String[] EXPRESSION_NOT_NULL = { "date ne null", "(E1.date IS NOT null)" };
+
   private static Edm edm = null;
 
   @BeforeClass
@@ -204,6 +210,16 @@
     assertEquals(EXPRESSION_MEMBER_OR[OUTPUT], parseWhereExpression(EXPRESSION_MEMBER_OR[INPUT], false));
   }
 
+  @Test
+  public void testNull() {
+    assertEquals(EXPRESSION_NULL[OUTPUT], parseWhereExpression(EXPRESSION_NULL[INPUT], false));
+  }
+
+  @Test
+  public void testNotNull() {
+    assertEquals(EXPRESSION_NOT_NULL[OUTPUT], parseWhereExpression(EXPRESSION_NOT_NULL[INPUT], false));
+  }
+  
   private String parseWhereExpression(final String input, final boolean isExceptionExpected) {
     FilterExpression expression;
     try {
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderTest.java
index 049b365..ebf268f 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/ODataJPAResponseBuilderTest.java
@@ -62,6 +62,7 @@
 import org.apache.olingo.odata2.jpa.processor.api.access.JPAPaging;
 import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
 import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
+import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmMappingImpl;
 import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmTestModelView;
 import org.easymock.EasyMock;
 import org.junit.Before;
@@ -384,9 +385,10 @@
     }
     EasyMock.replay(edmType);
     EdmProperty edmProperty = EasyMock.createMock(EdmProperty.class);
-    EdmMapping edmMapping = EasyMock.createMock(EdmMapping.class);
+    JPAEdmMappingImpl edmMapping = EasyMock.createMock(JPAEdmMappingImpl.class);
     EasyMock.expect(edmMapping.getInternalName()).andStubReturn("soId");
     EasyMock.expect(edmMapping.getMediaResourceMimeTypeKey()).andReturn(null);
+    EasyMock.expect(((JPAEdmMappingImpl) edmMapping).isVirtualAccess()).andStubReturn(false);
     EasyMock.replay(edmMapping);
     try {
       EasyMock.expect(edmProperty.getName()).andStubReturn("ID");
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserForStaticMethodTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserForStaticMethodTest.java
index 9a18f41..7a277fc 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserForStaticMethodTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserForStaticMethodTest.java
@@ -84,7 +84,7 @@
   public void testGetPropertyCharacter() {
     try {
       Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharacter", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this, "");
       assertEquals("A", output);
 
     } catch (NoSuchMethodException e) {
@@ -100,7 +100,7 @@
   public void testGetPropertyCharacterNull() {
     try {
       Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharacterNull", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this, "");
       assertNull(output);
 
     } catch (NoSuchMethodException e) {
@@ -116,7 +116,7 @@
   public void testGetPropertyCharacterArray() {
     try {
       Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharacterArray", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this, "");
       assertEquals("AB", output);
 
     } catch (NoSuchMethodException e) {
@@ -132,7 +132,7 @@
   public void testGetPropertyCharacterArrayNull() {
     try {
       Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharacterArrayNull", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this, "");
       assertNull(output);
 
     } catch (NoSuchMethodException e) {
@@ -148,7 +148,7 @@
   public void testGetPropertyChar() {
     try {
       Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getChar", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this, "");
       assertEquals("A", output);
 
     } catch (NoSuchMethodException e) {
@@ -164,7 +164,7 @@
   public void testGetPropertyCharNull() {
     try {
       Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharNull", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this, "");
       assertNull(output);
 
     } catch (NoSuchMethodException e) {
@@ -180,7 +180,7 @@
   public void testGetPropertyCharArray() {
     try {
       Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharArray", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this, "");
       assertEquals("AB", output);
 
     } catch (NoSuchMethodException e) {
@@ -196,7 +196,7 @@
   public void testGetPropertyCharArrayNull() {
     try {
       Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharArrayNull", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this, "");
       assertNull(output);
 
     } catch (NoSuchMethodException e) {
@@ -212,7 +212,7 @@
   public void testGetPropertyCharArrayValueNull() {
     try {
       Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getCharArrayValueNull", (Class<?>[]) null);
-      String output = (String) JPAEntityParser.getPropertyValue(method, this);
+      String output = (String) JPAEntityParser.getPropertyValue(method, this, "");
       assertEquals("A\u0000", output);
 
     } catch (NoSuchMethodException e) {
@@ -225,6 +225,41 @@
   }
 
   @Test
+  public void testGetPropertyObject() {
+  
+  try {
+      Method method = JPAEntityParserForStaticMethodTest.class.getMethod("getObject", (Class<?>[]) null);
+      Object output = (Object) JPAEntityParser.getPropertyValue(method, this, "");
+      assertTrue(output != null);
+
+      } catch (NoSuchMethodException e) {
+        fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+      } catch (SecurityException e) {
+        fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+      } catch (ODataJPARuntimeException e) {
+        fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+      }
+  }
+
+@Test
+  public void testGetPropertyObjectWithParameters() {
+
+    try {
+      Method method = JPAEntityParserForStaticMethodTest.class.
+            getMethod("getObjectWithParameters", getParameterTypeForMethod("getObjectWithParameters"));
+      Object output = (Object) JPAEntityParser.getPropertyValue(method, this, "obj1");
+      assertTrue(output != null);
+
+    } catch (NoSuchMethodException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (SecurityException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    } catch (ODataJPARuntimeException e) {
+      fail(ODataJPATestConstants.EXCEPTION_MSG_PART_1 + e.getMessage() + ODataJPATestConstants.EXCEPTION_MSG_PART_2);
+    }
+  }
+
+@Test
   public void testGetString() {
     char[] expectedChar = new char[] { 'a', 'b', 'c' };
     try {
@@ -315,4 +350,23 @@
   public char[] getCharArrayValueNull() {
     return new char[] { 'A', '\u0000' };
   }
+
+  public Object getObject() {
+    return new Object();
+  }
+
+  public Object getObjectWithParameters(Object ob1) {
+    return new Object();
+  }
+
+  private Class<?>[] getParameterTypeForMethod(String methodName) {
+
+    Method[] methods = JPAEntityParserForStaticMethodTest.class.getMethods();
+      for (Method method: methods) {
+        if (method.getName().equals(methodName)) {
+          return method.getParameterTypes();
+        }
+     }
+    return null;
+  }
 }
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserTest.java
index 01bf774..8035f2b 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAEntityParserTest.java
@@ -39,6 +39,7 @@
 import org.apache.olingo.odata2.api.edm.EdmTypeKind;
 import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
 import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
+import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmMappingImpl;
 import org.easymock.EasyMock;
 import org.junit.Test;
 
@@ -66,14 +67,15 @@
     EdmType edmType = EasyMock.createMock(EdmType.class);
     EdmProperty edmTyped01 = EasyMock.createMock(EdmProperty.class);
     EdmType edmType01 = EasyMock.createMock(EdmType.class);
-    EdmMapping edmMapping = EasyMock.createMock(EdmMapping.class);
-    EdmMapping edmMapping01 = EasyMock.createMock(EdmMapping.class);
+    EdmMapping edmMapping = EasyMock.createMock(JPAEdmMappingImpl.class);
+    EdmMapping edmMapping01 = EasyMock.createMock(JPAEdmMappingImpl.class);
 
     try {
       EasyMock.expect(edmType.getKind()).andStubReturn(EdmTypeKind.SIMPLE);
       EasyMock.expect(edmTyped.getName()).andStubReturn("identifier");
       EasyMock.replay(edmType);
       EasyMock.expect(edmMapping.getInternalName()).andStubReturn("id");
+      EasyMock.expect(((JPAEdmMappingImpl) edmMapping).isVirtualAccess()).andStubReturn(false);
       EasyMock.replay(edmMapping);
       EasyMock.expect(edmTyped.getType()).andStubReturn(edmType);
       EasyMock.expect(edmTyped.getMapping()).andStubReturn(edmMapping);
@@ -84,6 +86,7 @@
       EasyMock.expect(edmTyped01.getName()).andStubReturn("Value");
       EasyMock.replay(edmType01);
       EasyMock.expect(edmMapping01.getInternalName()).andStubReturn("value");
+      EasyMock.expect(((JPAEdmMappingImpl) edmMapping01).isVirtualAccess()).andStubReturn(false);
       EasyMock.replay(edmMapping01);
       EasyMock.expect(edmTyped01.getType()).andStubReturn(edmType01);
       EasyMock.expect(edmTyped01.getMapping()).andStubReturn(edmMapping01);
@@ -119,8 +122,8 @@
     EdmType edmType = EasyMock.createMock(EdmType.class);
     EdmProperty edmTyped01 = EasyMock.createMock(EdmProperty.class);
     EdmType edmType01 = EasyMock.createMock(EdmType.class);
-    EdmMapping edmMapping = EasyMock.createMock(EdmMapping.class);
-    EdmMapping edmMapping01 = EasyMock.createMock(EdmMapping.class);
+    EdmMapping edmMapping = EasyMock.createMock(JPAEdmMappingImpl.class);
+    EdmMapping edmMapping01 = EasyMock.createMock(JPAEdmMappingImpl.class);
 
     try {
       EasyMock.expect(edmType.getKind())
@@ -128,6 +131,7 @@
       EasyMock.expect(edmType.getName()).andReturn("identifier");
       EasyMock.replay(edmType);
       EasyMock.expect(edmMapping.getInternalName()).andStubReturn("id");
+      EasyMock.expect(((JPAEdmMappingImpl)edmMapping).isVirtualAccess()).andStubReturn(false);
       EasyMock.replay(edmMapping);
       EasyMock.expect(edmTyped.getType()).andStubThrow(
           new EdmException(null));
@@ -143,6 +147,8 @@
       EasyMock.replay(edmType01);
       EasyMock.expect(edmMapping01.getInternalName()).andStubReturn(
           "value");
+      EasyMock.expect(((JPAEdmMappingImpl)edmMapping01).isVirtualAccess())
+      .andStubReturn(false);
       EasyMock.replay(edmMapping01);
       EasyMock.expect(edmTyped01.getName()).andReturn("value").anyTimes();
       EasyMock.expect(edmTyped01.getType()).andStubReturn(edmType01);
@@ -183,9 +189,10 @@
     List<EdmNavigationProperty> navigationPropertyList = new ArrayList<EdmNavigationProperty>();
     // Mocking a navigation property and its mapping object
     EdmNavigationProperty navigationProperty = EasyMock.createMock(EdmNavigationProperty.class);
-    EdmMapping edmMapping = EasyMock.createMock(EdmMapping.class);
+    JPAEdmMappingImpl edmMapping = EasyMock.createMock(JPAEdmMappingImpl.class);
     try {
       EasyMock.expect(edmMapping.getInternalName()).andStubReturn("relatedEntity");
+      EasyMock.expect(((JPAEdmMappingImpl)edmMapping).isVirtualAccess()).andStubReturn(false);      
       EasyMock.replay(edmMapping);
       EasyMock.expect(navigationProperty.getName()).andStubReturn("RelatedEntities");
       EasyMock.expect(navigationProperty.getMapping()).andStubReturn(edmMapping);
@@ -220,13 +227,14 @@
     EdmType edmType1 = EasyMock.createMock(EdmType.class);
     EdmStructuralType edmType2 = EasyMock.createMock(EdmStructuralType.class);
     EdmType edmComplexType = EasyMock.createMock(EdmType.class);
-    EdmMapping mapping1 = EasyMock.createMock(EdmMapping.class);
-    EdmMapping mapping2 = EasyMock.createMock(EdmMapping.class);
-    EdmMapping complexMapping = EasyMock.createMock(EdmMapping.class);
+    JPAEdmMappingImpl mapping1 = EasyMock.createMock(JPAEdmMappingImpl.class);
+    JPAEdmMappingImpl mapping2 = EasyMock.createMock(JPAEdmMappingImpl.class);
+    JPAEdmMappingImpl complexMapping = EasyMock.createMock(JPAEdmMappingImpl.class);
     try {
       EasyMock.expect(edmType1.getKind()).andStubReturn(EdmTypeKind.SIMPLE);
       EasyMock.replay(edmType1);
       EasyMock.expect(mapping1.getInternalName()).andStubReturn("id");
+      EasyMock.expect(((JPAEdmMappingImpl) mapping1).isVirtualAccess()).andStubReturn(false);
       EasyMock.replay(mapping1);
       EasyMock.expect(edmProperty1.getName()).andStubReturn("Id");
       EasyMock.expect(edmProperty1.getMapping()).andStubReturn(mapping1);
@@ -236,6 +244,7 @@
       EasyMock.expect(edmComplexType.getKind()).andStubReturn(EdmTypeKind.SIMPLE);
       EasyMock.replay(edmComplexType);
       EasyMock.expect(complexMapping.getInternalName()).andStubReturn("order");
+      EasyMock.expect(((JPAEdmMappingImpl) complexMapping).isVirtualAccess()).andStubReturn(false);
       EasyMock.replay(complexMapping);
       EasyMock.expect(edmComplexProperty.getName()).andStubReturn("OrderName");
       EasyMock.expect(edmComplexProperty.getMapping()).andStubReturn(complexMapping);
@@ -248,6 +257,7 @@
       EasyMock.expect(edmType2.getPropertyNames()).andStubReturn(propertyNames);
       EasyMock.replay(edmType2);
       EasyMock.expect(mapping2.getInternalName()).andStubReturn("relatedEntity");
+      EasyMock.expect(((JPAEdmMappingImpl) mapping2).isVirtualAccess()).andStubReturn(false);
       EasyMock.replay(mapping2);
       EasyMock.expect(edmProperty2.getName()).andStubReturn("Order");
       EasyMock.expect(edmProperty2.getMapping()).andStubReturn(mapping2);
@@ -528,8 +538,9 @@
   private EdmProperty getEdmProperty() {
     EdmProperty edmTyped = EasyMock.createMock(EdmProperty.class);
 
-    EdmMapping edmMapping = EasyMock.createMock(EdmMapping.class);
+    JPAEdmMappingImpl edmMapping = EasyMock.createMock(JPAEdmMappingImpl.class);
     EasyMock.expect(edmMapping.getInternalName()).andStubReturn("Field1");
+    EasyMock.expect(((JPAEdmMappingImpl) edmMapping).isVirtualAccess()).andStubReturn(false);
     EasyMock.replay(edmMapping);
 
     EdmType edmType = EasyMock.createMock(EdmType.class);
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAExpandCallBackTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAExpandCallBackTest.java
index 29a2a7a..ae59cfd 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAExpandCallBackTest.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/access/data/JPAExpandCallBackTest.java
@@ -44,7 +44,6 @@
 import org.apache.olingo.odata2.jpa.processor.core.callback.JPAExpandCallBack;
 import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
 import org.apache.olingo.odata2.jpa.processor.core.mock.data.EdmMockUtil;
-import org.easymock.EasyMock;
 import org.junit.Test;
 
 public class JPAExpandCallBackTest {
diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/EdmMockUtil.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/EdmMockUtil.java
index 7bd7bcf..b0e713e 100644
--- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/EdmMockUtil.java
+++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/mock/data/EdmMockUtil.java
@@ -42,6 +42,7 @@
 import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
 import org.apache.olingo.odata2.api.uri.NavigationPropertySegment;
 import org.apache.olingo.odata2.jpa.processor.core.common.ODataJPATestConstants;
+import org.apache.olingo.odata2.jpa.processor.core.model.JPAEdmMappingImpl;
 import org.easymock.EasyMock;
 
 public class EdmMockUtil {
@@ -320,8 +321,9 @@
     EdmType type = EasyMock.createMock(EdmType.class);
     EasyMock.expect(type.getKind()).andStubReturn(EdmTypeKind.SIMPLE);
     EasyMock.replay(type);
-    EdmMapping mapping = EasyMock.createMock(EdmMapping.class);
+    JPAEdmMappingImpl mapping = EasyMock.createMock(JPAEdmMappingImpl.class);
     EasyMock.expect(mapping.getInternalName()).andStubReturn("price");
+    EasyMock.expect(((JPAEdmMappingImpl) mapping).isVirtualAccess()).andStubReturn(false);
     EasyMock.replay(mapping);
     try {
       EasyMock.expect(edmProperty.getName()).andStubReturn("price");
diff --git a/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/web/JPAReferenceServiceFactory.java b/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/web/JPAReferenceServiceFactory.java
index fa499c8..6e59903 100644
--- a/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/web/JPAReferenceServiceFactory.java
+++ b/odata2-jpa-processor/jpa-web/src/main/java/org/apache/olingo/odata2/jpa/processor/ref/web/JPAReferenceServiceFactory.java
@@ -20,6 +20,8 @@
 
 import java.util.ResourceBundle;
 
+import org.apache.olingo.odata2.api.ODataCallback;
+import org.apache.olingo.odata2.api.ODataDebugCallback;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
 import org.apache.olingo.odata2.jpa.processor.api.ODataJPAServiceFactory;
 import org.apache.olingo.odata2.jpa.processor.api.OnJPAWriteContent;
@@ -57,4 +59,18 @@
     boolean error = Boolean.parseBoolean(config.getString(SHOW_DETAIL_ERROR));
     setDetailErrors(error);
   }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public <T extends ODataCallback> T getCallback(final Class<T> callbackInterface) {
+    return (T) (callbackInterface.isAssignableFrom(ODataDebugCallback.class) ?
+        new ScenarioDebugCallback() : super.getCallback(callbackInterface));
+  }
+
+  private final class ScenarioDebugCallback implements ODataDebugCallback {
+    @Override
+    public boolean isDebugEnabled() {
+      return true;
+    }
+  }
 }
diff --git a/odata2-lib/odata-core/pom.xml b/odata2-lib/odata-core/pom.xml
index 38bb297..b05b8bf 100644
--- a/odata2-lib/odata-core/pom.xml
+++ b/odata2-lib/odata-core/pom.xml
@@ -74,6 +74,7 @@
 						<Import-Package>
 							javax.ws.rs,
 							javax.ws.rs.*,
+							com.google.gson.*;version="[2.2,$(version;+;${gson.version}))",
 							*
 						</Import-Package>
 						<Export-Package>
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/commons/XmlHelper.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/commons/XmlHelper.java
index 3433186..e5379e2 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/commons/XmlHelper.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/commons/XmlHelper.java
@@ -21,8 +21,10 @@
 import java.io.InputStream;
 
 import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.TransformerFactory;
 
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 
@@ -31,6 +33,26 @@
   /** Default used charset for reader */
   private static final String DEFAULT_CHARSET = "UTF-8";
 
+  static class XmlInputFactoryHolder {
+    private static final XMLInputFactory INSTANCE = XMLInputFactory.newInstance();
+  }
+  static class XmlOutputFactoryHolder {
+    private static final XMLOutputFactory INSTANCE = XMLOutputFactory.newInstance();
+  }
+  static class TransformerFactoryHolder {
+    private static final TransformerFactory INSTANCE = TransformerFactory.newInstance();
+  }
+
+  public static XMLInputFactory getXMLInputFactory() {
+    return XmlInputFactoryHolder.INSTANCE;
+  }
+  public static XMLOutputFactory getXMLOutputFactory() {
+    return XmlOutputFactoryHolder.INSTANCE;
+  }
+  public static TransformerFactory getTransformerFactory() {
+    return TransformerFactoryHolder.INSTANCE;
+  }
+
   public static XMLStreamReader createStreamReader(final Object content) throws EntityProviderException {
     if (content == null) {
       throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT
@@ -38,7 +60,7 @@
     }
     XMLStreamReader streamReader;
     try {
-      XMLInputFactory factory = XMLInputFactory.newInstance();
+      XMLInputFactory factory = getXMLInputFactory();
       factory.setProperty(XMLInputFactory.IS_VALIDATING, false);
       factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
       factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/debug/DebugInfoBody.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/debug/DebugInfoBody.java
index 4954c75..e2ea936 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/debug/DebugInfoBody.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/debug/DebugInfoBody.java
@@ -36,6 +36,7 @@
 import org.apache.olingo.odata2.api.commons.HttpContentType;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.core.commons.XmlHelper;
 import org.apache.olingo.odata2.core.ep.BasicEntityProvider;
 import org.apache.olingo.odata2.core.ep.util.JsonStreamWriter;
 
@@ -117,7 +118,8 @@
 
   private String formatXml(final String xml) throws IOException {
     try {
-      Transformer transformer = TransformerFactory.newInstance().newTransformer();
+      final TransformerFactory transformerFactory = XmlHelper.getTransformerFactory();
+      Transformer transformer = transformerFactory.newTransformer();
       transformer.setOutputProperty(OutputKeys.INDENT, "yes");
       transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
       StreamResult outputTarget = new StreamResult(new StringWriter());
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTime.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTime.java
index 38b213d..dddb0a2 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTime.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTime.java
@@ -84,7 +84,8 @@
 
     String valueString;
     if (literalKind == EdmLiteralKind.URI) {
-      if (value.length() > 10 && value.startsWith("datetime'") && value.endsWith("'")) {
+      //OLINGO-883 prefix is case insensitve so we need to check with lower case if we want to use startsWith()
+      if (value.length() > 10 && value.toLowerCase().startsWith("datetime'") && value.endsWith("'")) {
         valueString = value.substring(9, value.length() - 1);
       } else {
         throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTimeOffset.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTimeOffset.java
index 16f867f..cfc1a67 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTimeOffset.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTimeOffset.java
@@ -58,7 +58,8 @@
   protected <T> T internalValueOfString(final String value, final EdmLiteralKind literalKind, final EdmFacets facets,
       final Class<T> returnType) throws EdmSimpleTypeException {
     if (literalKind == EdmLiteralKind.URI) {
-      if (value.length() > 16 && value.startsWith("datetimeoffset'") && value.endsWith("'")) {
+      //OLINGO-883 prefix is case insensitve so we need to check with lower case if we want to use startsWith()
+      if (value.length() > 16 && value.toLowerCase().startsWith("datetimeoffset'") && value.endsWith("'")) {
         return internalValueOfString(value.substring(15, value.length() - 1), EdmLiteralKind.DEFAULT, facets,
             returnType);
       } else {
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmGuid.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmGuid.java
index dadd3b6..70594b3 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmGuid.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmGuid.java
@@ -46,20 +46,35 @@
   public boolean validate(final String value, final EdmLiteralKind literalKind, final EdmFacets facets) {
     return value == null ?
         facets == null || facets.isNullable() == null || facets.isNullable() :
-        validateLiteral(value, literalKind);
+        validateLiteralInternal(value, literalKind);
   }
 
-  private boolean validateLiteral(final String value, final EdmLiteralKind literalKind) {
-    return value.matches(literalKind == EdmLiteralKind.URI ? toUriLiteral(PATTERN) : PATTERN);
+  private boolean validateLiteralInternal(String value, EdmLiteralKind literalKind) {
+    String cleanValue = null;
+    if (literalKind == EdmLiteralKind.URI && value.toLowerCase().startsWith("guid'") && value.endsWith("'")) {
+      cleanValue = value.substring(5, value.length() - 1);
+    } else {
+      cleanValue = value;
+    }
+    return validateLiteral(cleanValue);
+  }
+
+  private boolean validateLiteral(final String value) {
+    return value.matches(PATTERN);
   }
 
   @Override
   protected <T> T internalValueOfString(final String value, final EdmLiteralKind literalKind, final EdmFacets facets,
       final Class<T> returnType) throws EdmSimpleTypeException {
     UUID result;
-    if (validateLiteral(value, literalKind)) {
-      result = UUID.fromString(
-          literalKind == EdmLiteralKind.URI ? value.substring(5, value.length() - 1) : value);
+    String cleanValue = null;
+    if (literalKind == EdmLiteralKind.URI && value.toLowerCase().startsWith("guid'") && value.endsWith("'")) {
+      cleanValue = value.substring(5, value.length() - 1);
+    } else {
+      cleanValue = value;
+    }
+    if (validateLiteral(cleanValue)) {
+      result = UUID.fromString(cleanValue);
     } else {
       throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
     }
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmImpl.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmImpl.java
index 80f3776..141a00e 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmImpl.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmImpl.java
@@ -81,6 +81,8 @@
           edmEntityContainers.put(name, edmEntityContainer);
         }
       }
+    } catch (EdmException e) {
+      throw e;
     } catch (ODataException e) {
       throw new EdmException(EdmException.COMMON, e);
     }
@@ -104,6 +106,8 @@
       if (edmEntityType != null) {
         edmEntityTypes.put(fqName, edmEntityType);
       }
+    } catch (EdmException e) {
+      throw e;
     } catch (ODataException e) {
       throw new EdmException(EdmException.COMMON, e);
     }
@@ -118,6 +122,8 @@
         if (aliasToNamespaceInfo == null) {
           aliasToNamespaceInfo = new HashMap<String, String>();
         }
+      } catch (EdmException e) {
+        throw e;
       } catch (ODataException e) {
         throw new EdmException(EdmException.COMMON, e);
       }
@@ -145,6 +151,8 @@
       if (edmComplexType != null) {
         edmComplexTypes.put(fqName, edmComplexType);
       }
+    } catch (EdmException e) {
+      throw e;
     } catch (ODataException e) {
       throw new EdmException(EdmException.COMMON, e);
     }
@@ -167,6 +175,8 @@
       if (edmAssociation != null) {
         edmAssociations.put(fqName, edmAssociation);
       }
+    } catch (EdmException e) {
+      throw e;
     } catch (ODataException e) {
       throw new EdmException(EdmException.COMMON, e);
     }
@@ -190,6 +200,8 @@
       if (edmEntitySets == null) {
         edmEntitySets = createEntitySets();
       }
+    } catch (EdmException e) {
+      throw e;
     } catch (ODataException e) {
       throw new EdmException(EdmException.COMMON, e);
     }
@@ -202,6 +214,8 @@
       if (edmFunctionImports == null) {
         edmFunctionImports = createFunctionImports();
       }
+    } catch (EdmException e) {
+      throw e;
     } catch (ODataException e) {
       throw new EdmException(EdmException.COMMON, e);
     }
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmTime.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmTime.java
index fb80227..fc99d6a 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmTime.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmTime.java
@@ -57,8 +57,9 @@
   protected <T> T internalValueOfString(final String value, final EdmLiteralKind literalKind, final EdmFacets facets,
       final Class<T> returnType) throws EdmSimpleTypeException {
 
+    //OLINGO-883 prefix is case insensitve so we need to check with lower case if we want to use startsWith()
     if (literalKind == EdmLiteralKind.URI
-        && (value.length() <= 6 || !value.startsWith("time'") || !value.endsWith("'"))) {
+        && (value.length() <= 6 || !value.toLowerCase().startsWith("time'") || !value.endsWith("'"))) {
       throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
     }
 
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmServiceMetadataImplProv.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmServiceMetadataImplProv.java
index e7853eb..3b2558a 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmServiceMetadataImplProv.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/provider/EdmServiceMetadataImplProv.java
@@ -42,6 +42,7 @@
 import org.apache.olingo.odata2.api.edm.provider.Schema;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.commons.XmlHelper;
 import org.apache.olingo.odata2.core.ep.producer.XmlMetadataProducer;
 import org.apache.olingo.odata2.core.ep.util.CircleStreamBuffer;
 
@@ -72,7 +73,7 @@
 
     try {
       writer = new OutputStreamWriter(csb.getOutputStream(), "UTF-8");
-      XMLStreamWriter xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(writer);
+      XMLStreamWriter xmlStreamWriter = XmlHelper.getXMLOutputFactory().createXMLStreamWriter(writer);
       XmlMetadataProducer.writeMetadata(metadata, xmlStreamWriter, null);
       return csb.getInputStream();
     } catch (XMLStreamException e) {
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 6dc6b7a..0977bec 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
@@ -52,6 +52,7 @@
 import org.apache.olingo.odata2.api.servicedocument.ServiceDocument;
 import org.apache.olingo.odata2.core.commons.ContentType;
 import org.apache.olingo.odata2.core.commons.ContentType.ODataFormat;
+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;
 import org.apache.olingo.odata2.core.ep.consumer.AtomServiceDocumentConsumer;
@@ -107,7 +108,7 @@
 
     try {
       OutputStream outStream = csb.getOutputStream();
-      XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
+      XMLStreamWriter writer = XmlHelper.getXMLOutputFactory().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
 
       XmlErrorDocumentProducer producer = new XmlErrorDocumentProducer();
       producer.writeErrorDocument(writer, errorCode, message, locale, innerError);
@@ -150,7 +151,7 @@
       throw e;
     } catch (Exception e) {
       csb.close();
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
@@ -162,7 +163,7 @@
 
     try {
       OutputStream outStream = csb.getOutputStream();
-      XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
+      XMLStreamWriter writer = XmlHelper.getXMLOutputFactory().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
       writer.writeStartDocument(DEFAULT_CHARSET, XML_VERSION);
 
       AtomEntryEntityProducer as = new AtomEntryEntityProducer(properties);
@@ -181,7 +182,7 @@
       throw e;
     } catch (Exception e) {
       csb.close();
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
@@ -198,7 +199,7 @@
 
     try {
       OutputStream outStream = csb.getOutputStream();
-      XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
+      XMLStreamWriter writer = XmlHelper.getXMLOutputFactory().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
       writer.writeStartDocument(DEFAULT_CHARSET, XML_VERSION);
 
       XmlPropertyEntityProducer ps = new XmlPropertyEntityProducer(false, true);
@@ -213,7 +214,7 @@
       throw e;
     } catch (Exception e) {
       csb.close();
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
@@ -225,7 +226,7 @@
 
     try {
       OutputStream outStream = csb.getOutputStream();
-      XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
+      XMLStreamWriter writer = XmlHelper.getXMLOutputFactory().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
       writer.writeStartDocument(DEFAULT_CHARSET, XML_VERSION);
 
       AtomFeedProducer atomFeedProvider = new AtomFeedProducer(properties);
@@ -242,7 +243,7 @@
       throw e;
     } catch (XMLStreamException e) {
       csb.close();
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
@@ -254,7 +255,7 @@
 
     try {
       OutputStream outStream = csb.getOutputStream();
-      XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
+      XMLStreamWriter writer = XmlHelper.getXMLOutputFactory().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
       writer.writeStartDocument(DEFAULT_CHARSET, XML_VERSION);
 
       XmlLinkEntityProducer entity = new XmlLinkEntityProducer(properties);
@@ -270,7 +271,7 @@
       throw e;
     } catch (Exception e) {
       csb.close();
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
 
@@ -283,7 +284,7 @@
 
     try {
       OutputStream outStream = csb.getOutputStream();
-      XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
+      XMLStreamWriter writer = XmlHelper.getXMLOutputFactory().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
       writer.writeStartDocument(DEFAULT_CHARSET, XML_VERSION);
 
       XmlLinksEntityProducer entity = new XmlLinksEntityProducer(properties);
@@ -299,7 +300,7 @@
       throw e;
     } catch (Exception e) {
       csb.close();
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
@@ -310,7 +311,7 @@
 
     try {
       OutputStream outStream = csb.getOutputStream();
-      XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
+      XMLStreamWriter writer = XmlHelper.getXMLOutputFactory().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
       writer.writeStartDocument(DEFAULT_CHARSET, XML_VERSION);
 
       XmlCollectionEntityProducer.append(writer, propertyInfo, data);
@@ -324,7 +325,7 @@
       throw e;
     } catch (Exception e) {
       csb.close();
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
@@ -349,8 +350,7 @@
         return writeSingleTypedElement(info, data);
       }
     } catch (EdmException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
-          .getSimpleName()), e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 
@@ -419,8 +419,7 @@
           new XmlEntityConsumer().readProperty(info, content, properties).get(info.getName());
       }
     } catch (final EdmException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
-          .addContent(e.getClass().getSimpleName()), e);
+      throw new EntityProviderException(e.getMessageReference(), e);
     }
   }
 }
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/BasicEntityProvider.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/BasicEntityProvider.java
index c8b2520..0b34b42 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/BasicEntityProvider.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/BasicEntityProvider.java
@@ -51,6 +51,7 @@
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.processor.ODataResponse;
 import org.apache.olingo.odata2.api.processor.ODataResponse.ODataResponseBuilder;
+import org.apache.olingo.odata2.core.commons.XmlHelper;
 import org.apache.olingo.odata2.core.ep.producer.XmlMetadataProducer;
 import org.apache.olingo.odata2.core.ep.util.CircleStreamBuffer;
 
@@ -122,8 +123,7 @@
     try {
       type = (EdmSimpleType) edmProperty.getType();
     } catch (EdmException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
-          .getSimpleName()), e);
+      throw new EntityProviderException(e.getMessageReference(), e);
     }
 
     if (type == EdmSimpleTypeKind.Binary.getEdmSimpleTypeInstance()) {
@@ -137,8 +137,7 @@
           return type.valueOfString(readText(content), EdmLiteralKind.DEFAULT, edmProperty.getFacets(), typeMapping);
         }
       } catch (EdmException e) {
-        throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
-            .getSimpleName()), e);
+        throw new EntityProviderException(e.getMessageReference(), e);
       }
     }
   }
@@ -179,8 +178,7 @@
       }
 
     } catch (EdmException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
-          .getSimpleName()), e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 
@@ -197,7 +195,7 @@
       try {
         stream = new ByteArrayInputStream(value.getBytes(DEFAULT_CHARSET));
       } catch (UnsupportedEncodingException e) {
-        throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+        throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
             .getSimpleName()), e);
       }
       builder.entity(stream);
@@ -245,16 +243,16 @@
     CircleStreamBuffer csb = new CircleStreamBuffer();
     try {
       writer = new OutputStreamWriter(csb.getOutputStream(), DEFAULT_CHARSET);
-      XMLStreamWriter xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(writer);
+      XMLStreamWriter xmlStreamWriter = XmlHelper.getXMLOutputFactory().createXMLStreamWriter(writer);
       XmlMetadataProducer.writeMetadata(metadata, xmlStreamWriter, predefinedNamespaces);
     } catch (UnsupportedEncodingException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     } catch (FactoryConfigurationError e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
     builder.entity(csb.getInputStream());
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/EntityProviderProducerException.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/EntityProviderProducerException.java
new file mode 100644
index 0000000..2c23846
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/EntityProviderProducerException.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.ep;
+
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.exception.MessageReference;
+
+public class EntityProviderProducerException extends EntityProviderException {
+
+  private static final long serialVersionUID = 1L;
+
+  public EntityProviderProducerException(final MessageReference messageReference) {
+    super(messageReference);
+  }
+
+  public EntityProviderProducerException(final MessageReference messageReference, final Throwable cause) {
+    super(messageReference, cause);
+  }
+
+  public EntityProviderProducerException(final MessageReference messageReference, final String errorCode) {
+    super(messageReference, errorCode);
+  }
+
+  public EntityProviderProducerException(final MessageReference messageReference, final Throwable cause,
+      final String errorCode) {
+    super(messageReference, cause, errorCode);
+  }
+}
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 092135b..c83b128 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
@@ -125,7 +125,8 @@
           .build();
     } catch (Exception e) {
       buffer.close();
-      throw new ODataRuntimeException(e);
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+          .getSimpleName()), e);
     }
   }
 
@@ -151,7 +152,7 @@
       throw e;
     } catch (Exception e) {
       buffer.close();
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
@@ -180,7 +181,7 @@
       throw e;
     } catch (Exception e) {
       buffer.close();
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
@@ -203,7 +204,7 @@
       throw e;
     } catch (Exception e) {
       buffer.close();
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
@@ -228,7 +229,7 @@
       throw e;
     } catch (Exception e) {
       buffer.close();
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
@@ -255,7 +256,7 @@
       throw e;
     } catch (Exception e) {
       buffer.close();
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
@@ -276,7 +277,7 @@
       throw e;
     } catch (Exception e) {
       buffer.close();
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
@@ -298,8 +299,7 @@
         return writeSingleTypedElement(info, data);
       }
     } catch (final EdmException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
-          .getSimpleName()), e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 
@@ -330,12 +330,11 @@
       } 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());
+            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);
+      throw new EntityProviderException(e.getMessageReference(), e);
     }
   }
 
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryEntityProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryEntityProducer.java
index 5e92500..6250739 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryEntityProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryEntityProducer.java
@@ -57,6 +57,7 @@
 import org.apache.olingo.odata2.core.commons.ContentType;
 import org.apache.olingo.odata2.core.commons.Encoder;
 import org.apache.olingo.odata2.core.edm.EdmDateTimeOffset;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
 import org.apache.olingo.odata2.core.ep.util.FormatXml;
@@ -139,11 +140,11 @@
 
       writer.flush();
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     } catch (EdmException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     } catch (URISyntaxException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     }
   }
 
@@ -208,7 +209,7 @@
 
       return etag;
     } catch (EdmSimpleTypeException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 
@@ -245,7 +246,7 @@
       }
       writer.writeEndElement();
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     }
   }
 
@@ -269,13 +270,13 @@
 
         ODataCallback callback = properties.getCallbacks().get(navigationPropertyName);
         if (callback == null) {
-          throw new EntityProviderException(EntityProviderException.EXPANDNOTSUPPORTED);
+          throw new EntityProviderProducerException(EntityProviderException.EXPANDNOTSUPPORTED);
         }
         WriteFeedCallbackResult result;
         try {
           result = ((OnWriteFeedContent) callback).retrieveFeedResult(context);
         } catch (ODataApplicationException e) {
-          throw new EntityProviderException(EntityProviderException.COMMON, e);
+          throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
         }
         List<Map<String, Object>> inlineData = result.getFeedData();
         if (inlineData == null) {
@@ -313,13 +314,13 @@
 
         ODataCallback callback = properties.getCallbacks().get(navigationPropertyName);
         if (callback == null) {
-          throw new EntityProviderException(EntityProviderException.EXPANDNOTSUPPORTED);
+          throw new EntityProviderProducerException(EntityProviderException.EXPANDNOTSUPPORTED);
         }
         WriteEntryCallbackResult result;
         try {
           result = ((OnWriteEntryContent) callback).retrieveEntryResult(context);
         } catch (ODataApplicationException e) {
-          throw new EntityProviderException(EntityProviderException.COMMON, e);
+          throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
         }
         Map<String, Object> inlineData = result.getEntryData();
         if (inlineData != null && !inlineData.isEmpty()) {
@@ -346,9 +347,9 @@
       writer.writeAttribute(FormatXml.ATOM_TITLE, eia.getEntityType().getName());
       writer.writeEndElement();
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     } catch (EdmException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 
@@ -373,7 +374,7 @@
       writer.writeAttribute(FormatXml.ATOM_TYPE, mediaResourceMimeType);
       writer.writeEndElement();
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     }
   }
 
@@ -410,7 +411,7 @@
       writer.writeAttribute(FormatXml.ATOM_SRC, self);
       writer.writeEndElement();
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     }
   }
 
@@ -443,9 +444,9 @@
 
       writer.writeEndElement();
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     } catch (EdmSimpleTypeException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 
@@ -477,7 +478,7 @@
       }
       return null;
     } catch (EdmSimpleTypeException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 
@@ -520,9 +521,9 @@
       writer.writeAttribute(FormatXml.ATOM_CATEGORY_SCHEME, Edm.NAMESPACE_SCHEME_2007_08);
       writer.writeEndElement();
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     } catch (EdmException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 
@@ -538,7 +539,7 @@
         writer.writeEndElement();
       }
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     }
   }
 
@@ -574,7 +575,7 @@
         keys.append(Encoder.encode(type.valueToString(data.get(name), EdmLiteralKind.URI,
             keyPropertyInfo.getFacets())));
       } catch (final EdmSimpleTypeException e) {
-        throw new EntityProviderException(EntityProviderException.COMMON, e);
+        throw new EntityProviderProducerException(e.getMessageReference(), e);
       }
     }
 
@@ -601,7 +602,7 @@
         writer.writeEndElement();
       }
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     }
   }
 
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomFeedProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomFeedProducer.java
index 5684814..0c43572 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomFeedProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomFeedProducer.java
@@ -37,6 +37,7 @@
 import org.apache.olingo.odata2.api.ep.callback.TombstoneCallbackResult;
 import org.apache.olingo.odata2.core.commons.Encoder;
 import org.apache.olingo.odata2.core.edm.EdmDateTimeOffset;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
 import org.apache.olingo.odata2.core.ep.util.FormatXml;
 
@@ -88,7 +89,7 @@
 
       writer.writeEndElement();
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     }
   }
 
@@ -120,7 +121,7 @@
         writer.writeAttribute(FormatXml.ATOM_HREF, deltaLink);
         writer.writeEndElement();
       } catch (XMLStreamException e) {
-        throw new EntityProviderException(EntityProviderException.COMMON, e);
+        throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
       }
     }
   }
@@ -132,7 +133,7 @@
       writer.writeAttribute(FormatXml.ATOM_REL, FormatXml.ATOM_NEXT_LINK);
       writer.writeEndElement();
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     }
   }
 
@@ -147,14 +148,14 @@
   private void appendInlineCount(final XMLStreamWriter writer, final Integer inlineCount)
       throws EntityProviderException {
     if (inlineCount == null || inlineCount < 0) {
-      throw new EntityProviderException(EntityProviderException.INLINECOUNT_INVALID);
+      throw new EntityProviderProducerException(EntityProviderException.INLINECOUNT_INVALID);
     }
     try {
       writer.writeStartElement(Edm.NAMESPACE_M_2007_08, FormatXml.M_COUNT);
       writer.writeCharacters(String.valueOf(inlineCount));
       writer.writeEndElement();
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     }
   }
 
@@ -175,7 +176,7 @@
       writer.writeAttribute(FormatXml.ATOM_TITLE, eia.getEntitySetName());
       writer.writeEndElement();
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     }
   }
 
@@ -217,9 +218,9 @@
       writer.writeEndElement();
 
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     } catch (EdmSimpleTypeException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomServiceDocumentProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomServiceDocumentProducer.java
index a5299f1..ffd3748 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomServiceDocumentProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomServiceDocumentProducer.java
@@ -28,10 +28,13 @@
 
 import org.apache.olingo.odata2.api.edm.Edm;
 import org.apache.olingo.odata2.api.edm.EdmEntitySetInfo;
+import org.apache.olingo.odata2.api.edm.EdmException;
 import org.apache.olingo.odata2.api.edm.EdmServiceMetadata;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.exception.ODataException;
 import org.apache.olingo.odata2.core.commons.ContentType;
+import org.apache.olingo.odata2.core.commons.XmlHelper;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.util.FormatXml;
 
 /**
@@ -55,7 +58,7 @@
     EdmServiceMetadata serviceMetadata = edm.getServiceMetadata();
 
     try {
-      XMLStreamWriter xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(writer);
+      XMLStreamWriter xmlStreamWriter = XmlHelper.getXMLOutputFactory().createXMLStreamWriter(writer);
 
       xmlStreamWriter.writeStartDocument(DEFAULT_CHARSET, XML_VERSION);
       xmlStreamWriter.setPrefix(Edm.PREFIX_XML, Edm.NAMESPACE_XML_1998);
@@ -88,11 +91,13 @@
 
       xmlStreamWriter.flush();
     } catch (FactoryConfigurationError e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
+    } catch (EdmException e) {
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     } catch (ODataException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     }
   }
 }
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonCollectionEntityProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonCollectionEntityProducer.java
index 4ba8577..0c25410 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonCollectionEntityProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonCollectionEntityProducer.java
@@ -25,6 +25,7 @@
 import org.apache.olingo.odata2.api.edm.Edm;
 import org.apache.olingo.odata2.api.edm.EdmException;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
 import org.apache.olingo.odata2.core.ep.util.FormatJson;
 import org.apache.olingo.odata2.core.ep.util.JsonStreamWriter;
@@ -69,11 +70,10 @@
       jsonStreamWriter.endObject()
           .endObject();
     } catch (final IOException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     } catch (final EdmException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
-          .getSimpleName()), e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 }
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonDeletedEntryEntityProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonDeletedEntryEntityProducer.java
index 2452228..0ce7f80 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonDeletedEntryEntityProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonDeletedEntryEntityProducer.java
@@ -25,6 +25,7 @@
 
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
 import org.apache.olingo.odata2.core.ep.util.FormatJson;
 import org.apache.olingo.odata2.core.ep.util.JsonStreamWriter;
@@ -68,7 +69,7 @@
         }
       }
     } catch (final IOException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
 
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducer.java
index fe02cc7..6615935 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducer.java
@@ -45,6 +45,7 @@
 import org.apache.olingo.odata2.api.exception.ODataApplicationException;
 import org.apache.olingo.odata2.core.commons.ContentType;
 import org.apache.olingo.odata2.core.commons.Encoder;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
 import org.apache.olingo.odata2.core.ep.util.FormatJson;
 import org.apache.olingo.odata2.core.ep.util.JsonStreamWriter;
@@ -100,11 +101,10 @@
       writer.flush();
 
     } catch (final IOException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     } catch (final EdmException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
-          .getSimpleName()), e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 
@@ -147,7 +147,7 @@
 
     ODataCallback callback = properties.getCallbacks().get(navigationPropertyName);
     if (callback == null) {
-      throw new EntityProviderException(EntityProviderException.EXPANDNOTSUPPORTED);
+      throw new EntityProviderProducerException(EntityProviderException.EXPANDNOTSUPPORTED);
     }
     try {
       if (isFeed) {
@@ -182,7 +182,7 @@
         }
       }
     } catch (final ODataApplicationException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonFeedEntityProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonFeedEntityProducer.java
index 4dc4dae..db71b63 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonFeedEntityProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonFeedEntityProducer.java
@@ -28,6 +28,7 @@
 import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
 import org.apache.olingo.odata2.api.ep.callback.TombstoneCallback;
 import org.apache.olingo.odata2.api.ep.callback.TombstoneCallbackResult;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
 import org.apache.olingo.odata2.core.ep.util.FormatJson;
 import org.apache.olingo.odata2.core.ep.util.JsonStreamWriter;
@@ -84,7 +85,7 @@
 
       jsonStreamWriter.endObject();
     } catch (final IOException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
@@ -97,7 +98,7 @@
       appendEntries(writer, entityInfo, data, jsonStreamWriter);
       jsonStreamWriter.endArray();
     } catch (final IOException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonLinkEntityProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonLinkEntityProducer.java
index 9ddfddd..7c3efd8 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonLinkEntityProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonLinkEntityProducer.java
@@ -24,6 +24,7 @@
 
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
 import org.apache.olingo.odata2.core.ep.util.FormatJson;
 import org.apache.olingo.odata2.core.ep.util.JsonStreamWriter;
@@ -56,7 +57,7 @@
         jsonStreamWriter.endObject();
       }
     } catch (final IOException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonLinksEntityProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonLinksEntityProducer.java
index 858456c..7a19ed6 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonLinksEntityProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonLinksEntityProducer.java
@@ -26,6 +26,7 @@
 import org.apache.olingo.odata2.api.commons.InlineCount;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
 import org.apache.olingo.odata2.core.ep.util.FormatJson;
 import org.apache.olingo.odata2.core.ep.util.JsonStreamWriter;
@@ -81,7 +82,7 @@
         jsonStreamWriter.endObject();
       }
     } catch (final IOException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
   }
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonPropertyEntityProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonPropertyEntityProducer.java
index 6947910..00ab712 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonPropertyEntityProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonPropertyEntityProducer.java
@@ -22,8 +22,15 @@
 import java.io.Writer;
 import java.util.Map;
 
-import org.apache.olingo.odata2.api.edm.*;
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.edm.EdmType;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityComplexPropertyInfo;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
 import org.apache.olingo.odata2.core.ep.util.FormatJson;
@@ -52,11 +59,10 @@
       jsonStreamWriter.endObject()
           .endObject();
     } catch (final IOException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     } catch (final EdmException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
-          .getSimpleName()), e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 
@@ -78,7 +84,7 @@
         }
         jsonStreamWriter.endObject();
       } else {
-        throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT
+        throw new EntityProviderProducerException(EntityProviderException.ILLEGAL_ARGUMENT
             .addContent("A complex property must have a Map as data"));
       }
     } else {
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonServiceDocumentProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonServiceDocumentProducer.java
index bca6b65..bb4d351 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonServiceDocumentProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonServiceDocumentProducer.java
@@ -23,9 +23,11 @@
 
 import org.apache.olingo.odata2.api.edm.Edm;
 import org.apache.olingo.odata2.api.edm.EdmEntitySetInfo;
+import org.apache.olingo.odata2.api.edm.EdmException;
 import org.apache.olingo.odata2.api.edm.EdmServiceMetadata;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.util.FormatJson;
 import org.apache.olingo.odata2.core.ep.util.JsonStreamWriter;
 
@@ -60,10 +62,12 @@
           .endObject()
           .endObject();
     } catch (final IOException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
+    } catch (final EdmException e) {
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     } catch (final ODataException e) {
-      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+      throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
           .getSimpleName()), e);
     }
 
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/TombstoneProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/TombstoneProducer.java
index 7f1babb..142db4d 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/TombstoneProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/TombstoneProducer.java
@@ -33,6 +33,7 @@
 import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
 import org.apache.olingo.odata2.api.ep.callback.TombstoneCallback;
 import org.apache.olingo.odata2.core.edm.EdmDateTimeOffset;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
 import org.apache.olingo.odata2.core.ep.util.FormatXml;
@@ -66,9 +67,9 @@
         writer.writeEndElement();
       }
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     } catch (EdmSimpleTypeException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlCollectionEntityProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlCollectionEntityProducer.java
index bf0bc8c..96eae72 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlCollectionEntityProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlCollectionEntityProducer.java
@@ -25,6 +25,7 @@
 
 import org.apache.olingo.odata2.api.edm.Edm;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
 import org.apache.olingo.odata2.core.ep.util.FormatXml;
 
@@ -49,7 +50,7 @@
       writer.writeEndElement();
       writer.flush();
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     }
   }
 }
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinkEntityProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinkEntityProducer.java
index fe59c4a..1e20f1c 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinkEntityProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinkEntityProducer.java
@@ -26,6 +26,7 @@
 import org.apache.olingo.odata2.api.edm.Edm;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
 import org.apache.olingo.odata2.core.ep.util.FormatXml;
 
@@ -55,7 +56,7 @@
       writer.writeEndElement();
       writer.flush();
     } catch (final XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     }
   }
 }
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinksEntityProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinksEntityProducer.java
index 84eff3b..a8a240e 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinksEntityProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinksEntityProducer.java
@@ -27,6 +27,7 @@
 import org.apache.olingo.odata2.api.edm.Edm;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
 import org.apache.olingo.odata2.core.ep.util.FormatXml;
 
@@ -60,7 +61,7 @@
       writer.writeEndElement();
       writer.flush();
     } catch (final XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     }
   }
 }
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlMetadataProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlMetadataProducer.java
index f917de7..f301482 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlMetadataProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlMetadataProducer.java
@@ -57,6 +57,7 @@
 import org.apache.olingo.odata2.api.edm.provider.SimpleProperty;
 import org.apache.olingo.odata2.api.edm.provider.Using;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.util.XmlMetadataConstants;
 import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
 
@@ -420,9 +421,9 @@
 
       xmlStreamWriter.flush();
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     } catch (FactoryConfigurationError e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     }
   }
 
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlPropertyEntityProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlPropertyEntityProducer.java
index 433e79e..587748d 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlPropertyEntityProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlPropertyEntityProducer.java
@@ -32,6 +32,7 @@
 import org.apache.olingo.odata2.api.edm.EdmSimpleType;
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityComplexPropertyInfo;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
 import org.apache.olingo.odata2.core.ep.util.FormatXml;
@@ -77,9 +78,9 @@
 
       writer.writeEndElement();
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     } catch (EdmException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 
@@ -92,9 +93,9 @@
         writer.writeEndElement();
       }
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     } catch (EdmException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 
@@ -123,9 +124,9 @@
 
       writer.writeEndElement();
     } catch (XMLStreamException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(EntityProviderException.COMMON, e);
     } catch (EdmException e) {
-      throw new EntityProviderException(EntityProviderException.COMMON, e);
+      throw new EntityProviderProducerException(e.getMessageReference(), e);
     }
   }
 
@@ -229,7 +230,7 @@
     String nsPrefix = mapping.getFcNsPrefix();
     String nsUri = mapping.getFcNsUri();
     if (nsUri == null || nsPrefix == null) {
-      throw new EntityProviderException(EntityProviderException.INVALID_NAMESPACE.addContent(name));
+      throw new EntityProviderProducerException(EntityProviderException.INVALID_NAMESPACE.addContent(name));
     }
     writer.writeStartElement(nsPrefix, name, nsUri);
     writer.writeNamespace(nsPrefix, nsUri);
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rest/ODataExceptionWrapper.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rest/ODataExceptionWrapper.java
index 30efb9c..4300ab1 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rest/ODataExceptionWrapper.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rest/ODataExceptionWrapper.java
@@ -48,6 +48,7 @@
 import org.apache.olingo.odata2.api.processor.ODataErrorContext;
 import org.apache.olingo.odata2.api.processor.ODataResponse;
 import org.apache.olingo.odata2.core.commons.ContentType;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.ProviderFacadeImpl;
 import org.apache.olingo.odata2.core.exception.MessageService;
 import org.apache.olingo.odata2.core.exception.MessageService.Message;
@@ -160,7 +161,15 @@
     if (toHandleException instanceof ODataHttpException) {
       errorContext.setHttpStatus(((ODataHttpException) toHandleException).getHttpStatus());
     } else if (toHandleException instanceof EntityProviderException) {
-      errorContext.setHttpStatus(HttpStatusCodes.BAD_REQUEST);
+      if(toHandleException instanceof EntityProviderProducerException){
+        /*
+         * As per OLINGO-763 serializer exceptions are produced by the server and must therefore result 
+         * in a 500 internal server error
+         */
+        errorContext.setHttpStatus(HttpStatusCodes.INTERNAL_SERVER_ERROR);
+      }else{
+        errorContext.setHttpStatus(HttpStatusCodes.BAD_REQUEST);
+      }
     } else if (toHandleException instanceof BatchException) {
       errorContext.setHttpStatus(HttpStatusCodes.BAD_REQUEST);
     }
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataExceptionWrapper.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataExceptionWrapper.java
index 9a87505..e012ec4 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataExceptionWrapper.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataExceptionWrapper.java
@@ -43,6 +43,7 @@
 import org.apache.olingo.odata2.api.processor.ODataErrorContext;
 import org.apache.olingo.odata2.api.processor.ODataResponse;
 import org.apache.olingo.odata2.core.commons.ContentType;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.core.ep.ProviderFacadeImpl;
 import org.apache.olingo.odata2.core.exception.MessageService;
 import org.apache.olingo.odata2.core.exception.MessageService.Message;
@@ -152,7 +153,15 @@
     if (toHandleException instanceof ODataHttpException) {
       errorContext.setHttpStatus(((ODataHttpException) toHandleException).getHttpStatus());
     } else if (toHandleException instanceof EntityProviderException) {
-      errorContext.setHttpStatus(HttpStatusCodes.BAD_REQUEST);
+      if(toHandleException instanceof EntityProviderProducerException){
+        /*
+         * As per OLINGO-763 serializer exceptions are produced by the server and must therefore result 
+         * in a 500 internal server error
+         */
+        errorContext.setHttpStatus(HttpStatusCodes.INTERNAL_SERVER_ERROR);
+      }else{
+        errorContext.setHttpStatus(HttpStatusCodes.BAD_REQUEST);
+      }
     } else if (toHandleException instanceof BatchException) {
       errorContext.setHttpStatus(HttpStatusCodes.BAD_REQUEST);
     }
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/commons/XmlHelperTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/commons/XmlHelperTest.java
index dc8fb77..e633e66 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/commons/XmlHelperTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/commons/XmlHelperTest.java
@@ -25,6 +25,8 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
 
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamException;
@@ -35,6 +37,7 @@
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
 import org.apache.olingo.odata2.testutil.mock.MockFacade;
+import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -87,13 +90,41 @@
           "  <data>&rules;</data>" +
           "</extract>";
 
+  private static Object beforeXmlInputFactory;
+
   @BeforeClass
   public static void beforeClass() {
     // CHECKSTYLE:OFF
     System.setProperty("javax.xml.stream.XMLInputFactory", "com.ctc.wstx.stax.WstxInputFactory"); // NOSONAR
+    //
+    beforeXmlInputFactory = replaceXmlInputFactoryInstance(XMLInputFactory.newInstance());
     // CHECKSTYLE:ON
   }
 
+  @AfterClass
+  public static void afterClass() {
+    replaceXmlInputFactoryInstance(beforeXmlInputFactory);
+  }
+
+  private static Object replaceXmlInputFactoryInstance(Object newInstance) {
+    try {
+      Field field = XmlHelper.XmlInputFactoryHolder.class.getDeclaredField("INSTANCE");
+      field.setAccessible(true);
+
+      Field modifiersField = Field.class.getDeclaredField("modifiers");
+      modifiersField.setAccessible(true);
+      modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
+
+      Object replaced = field.get(null);
+      field.set(null, newInstance);
+      return replaced;
+    } catch (NoSuchFieldException e) {
+      throw new RuntimeException(e);
+    } catch (IllegalAccessException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
   @Test
   public void createReader() throws Exception {
     InputStream content = new ByteArrayInputStream(XML.getBytes("UTF-8"));
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/edm/EdmSimpleTypeTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/edm/EdmSimpleTypeTest.java
index 5b1b50b..ebe6211 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/edm/EdmSimpleTypeTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/edm/EdmSimpleTypeTest.java
@@ -1139,6 +1139,10 @@
         Date.class));
     assertEquals(dateTime, instance.valueOfString("datetime'2012-02-29T23:32:03.001'", EdmLiteralKind.URI, null,
         Calendar.class));
+    
+    //OLINGO-883 prefix is case insensitive
+    assertEquals(dateTime, instance.valueOfString("DaTeTiMe'2012-02-29T23:32:03.001'", EdmLiteralKind.URI, null,
+        Calendar.class));
 
     dateTime.add(Calendar.MILLISECOND, 9);
     assertEquals(dateTime, instance.valueOfString("2012-02-29T23:32:03.01", EdmLiteralKind.DEFAULT,
@@ -1235,7 +1239,12 @@
         Calendar.class));
     assertEquals(dateTime, instance.valueOfString("datetimeoffset'2012-02-29T01:02:03-01:30'", EdmLiteralKind.URI,
         null, Calendar.class));
-
+    
+    //OLINGO-883 prefix is case insensitive
+    assertEquals(dateTime, instance.valueOfString("DaTeTiMeoFFset'2012-02-29T01:02:03-01:30'", EdmLiteralKind.URI,
+        null, Calendar.class));
+    
+    
     dateTime.clear();
     dateTime.setTimeZone(TimeZone.getTimeZone("GMT+11:00"));
     dateTime.set(2012, 1, 29, 1, 2, 3);
@@ -1438,7 +1447,11 @@
         UUID.class));
     assertEquals(uuid, instance.valueOfString("guid'AABBCCDD-aabb-ccdd-eeff-AABBCCDDEEFF'", EdmLiteralKind.URI, null,
         UUID.class));
-
+    
+    //OLINGO-883 prefix is case insensitive
+    assertEquals(uuid, instance.valueOfString("GuId'AABBCCDD-aabb-ccdd-eeff-AABBCCDDEEFF'", EdmLiteralKind.URI, null,
+        UUID.class));
+    
     expectErrorInValueOfString(instance, "AABBCCDDAABBCCDDEEFFAABBCCDDEEFF", EdmLiteralKind.DEFAULT, null,
         EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT);
     expectErrorInValueOfString(instance, "uid'AABBCCDD-aabb-ccdd-eeff-AABBCCDDEEFF'", EdmLiteralKind.URI, null,
@@ -1652,7 +1665,10 @@
     assertEquals(dateTime, instance.valueOfString("PT23H32M3.001S", EdmLiteralKind.DEFAULT, null, Calendar.class));
     assertEquals(dateTime, instance.valueOfString("PT23H32M3.001S", EdmLiteralKind.JSON, null, Calendar.class));
     assertEquals(dateTime, instance.valueOfString("time'PT23H32M3.001S'", EdmLiteralKind.URI, null, Calendar.class));
-
+    
+    //OLINGO-883 prefix is case insensitive
+    assertEquals(dateTime, instance.valueOfString("TiMe'PT23H32M3.001S'", EdmLiteralKind.URI, null, Calendar.class));
+    
     dateTime.add(Calendar.MILLISECOND, -1);
     assertEquals(dateTime, instance.valueOfString("PT23H32M3S", EdmLiteralKind.DEFAULT,
         getPrecisionScaleFacets(0, null), Calendar.class));
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/LoadXMLFactoryTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/LoadXMLFactoryTest.java
index 3af05cd..3aae2dd 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/LoadXMLFactoryTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/LoadXMLFactoryTest.java
@@ -6,9 +6,9 @@
  * 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
@@ -26,7 +26,7 @@
 import org.junit.Test;
 
 /**
- *  
+ *
  */
 public class LoadXMLFactoryTest {
   // CHECKSTYLE:OFF
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/PerformanceTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/PerformanceTest.java
index e7ab5b9..b97a0b9 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/PerformanceTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/PerformanceTest.java
@@ -36,6 +36,7 @@
 import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
 import org.apache.olingo.odata2.api.exception.ODataException;
 import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
+import org.apache.olingo.odata2.core.commons.XmlHelper;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
 import org.apache.olingo.odata2.core.ep.producer.AtomEntryEntityProducer;
 import org.apache.olingo.odata2.core.ep.util.CircleStreamBuffer;
@@ -79,7 +80,7 @@
       outStream = new ByteArrayOutputStream();
     }
 
-    writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outStream, "utf-8");
+    writer = XmlHelper.getXMLOutputFactory().createXMLStreamWriter(outStream, "utf-8");
 
     writer.writeStartElement("junit");
     writer.writeDefaultNamespace(Edm.NAMESPACE_ATOM_2005);
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryProducerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryProducerTest.java
index ff429af..c6b712d 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryProducerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryProducerTest.java
@@ -41,6 +41,7 @@
 import javax.xml.stream.XMLStreamException;
 
 import junit.framework.Assert;
+
 import org.apache.olingo.odata2.api.edm.Edm;
 import org.apache.olingo.odata2.api.edm.EdmConcurrencyMode;
 import org.apache.olingo.odata2.api.edm.EdmCustomizableFeedMappings;
@@ -60,6 +61,7 @@
 import org.apache.olingo.odata2.core.commons.ContentType;
 import org.apache.olingo.odata2.core.ep.AbstractProviderTest;
 import org.apache.olingo.odata2.core.ep.AtomEntityProvider;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
 import org.apache.olingo.odata2.testutil.helper.StringHelper;
 import org.apache.olingo.odata2.testutil.helper.XMLUnitHelper;
 import org.apache.olingo.odata2.testutil.mock.MockFacade;
@@ -465,7 +467,7 @@
     try {
       ser.writeEntry(employeesSet, employeeData, DEFAULT_PROPERTIES);
     } catch (EntityProviderException e) {
-      verifyRootCause(EntityProviderException.class, EntityProviderException.INVALID_NAMESPACE.getKey(), e);
+      verifyRootCause(EntityProviderProducerException.class, EntityProviderException.INVALID_NAMESPACE.getKey(), e);
       thrown = true;
     }
     if (!thrown) {
@@ -497,7 +499,7 @@
     try {
       ser.writeEntry(employeesSet, employeeData, DEFAULT_PROPERTIES);
     } catch (EntityProviderException e) {
-      verifyRootCause(EntityProviderException.class, EntityProviderException.INVALID_NAMESPACE.getKey(), e);
+      verifyRootCause(EntityProviderProducerException.class, EntityProviderException.INVALID_NAMESPACE.getKey(), e);
       thrown = true;
     }
     if (!thrown) {
@@ -528,7 +530,7 @@
     try {
       ser.writeEntry(employeesSet, employeeData, DEFAULT_PROPERTIES);
     } catch (EntityProviderException e) {
-      verifyRootCause(EntityProviderException.class, EntityProviderException.INVALID_NAMESPACE.getKey(), e);
+      verifyRootCause(EntityProviderProducerException.class, EntityProviderException.INVALID_NAMESPACE.getKey(), e);
       thrown = true;
     }
     if (!thrown) {
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/TombstoneProducerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/TombstoneProducerTest.java
index 11fc21a..aa2829d 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/TombstoneProducerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/TombstoneProducerTest.java
@@ -40,6 +40,7 @@
 import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
 import org.apache.olingo.odata2.api.ep.callback.TombstoneCallback;
 import org.apache.olingo.odata2.core.commons.ContentType;
+import org.apache.olingo.odata2.core.commons.XmlHelper;
 import org.apache.olingo.odata2.core.ep.AbstractProviderTest;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
 import org.apache.olingo.odata2.core.ep.util.CircleStreamBuffer;
@@ -65,7 +66,7 @@
   public void initialize() throws Exception {
     csb = new CircleStreamBuffer();
     OutputStream outStream = csb.getOutputStream();
-    writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
+    writer = XmlHelper.getXMLOutputFactory().createXMLStreamWriter(outStream, DEFAULT_CHARSET);
     defaultProperties = EntityProviderWriteProperties.serviceRoot(BASE_URI).build();
     defaultEia =
         EntityInfoAggregator.create(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"),
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/XmlMetadataProducerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/XmlMetadataProducerTest.java
index eb2a795..83961b7 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/XmlMetadataProducerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/XmlMetadataProducerTest.java
@@ -41,6 +41,7 @@
 import org.apache.olingo.odata2.api.edm.provider.PropertyRef;
 import org.apache.olingo.odata2.api.edm.provider.Schema;
 import org.apache.olingo.odata2.api.edm.provider.SimpleProperty;
+import org.apache.olingo.odata2.core.commons.XmlHelper;
 import org.apache.olingo.odata2.core.ep.AbstractXmlProducerTestHelper;
 import org.apache.olingo.odata2.core.ep.util.CircleStreamBuffer;
 import org.apache.olingo.odata2.testutil.helper.StringHelper;
@@ -60,7 +61,7 @@
 
   @Before
   public void before() {
-    xmlStreamWriterFactory = XMLOutputFactory.newInstance();
+    xmlStreamWriterFactory = XmlHelper.getXMLOutputFactory();
   }
 
   @Test
diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/InvalidDataInScenarioTest.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/InvalidDataInScenarioTest.java
new file mode 100644
index 0000000..10be915
--- /dev/null
+++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/ref/InvalidDataInScenarioTest.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * 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.
+ ******************************************************************************/
+package org.apache.olingo.odata2.fit.ref;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.http.HttpResponse;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.provider.EdmProvider;
+import org.apache.olingo.odata2.api.ep.EntityProvider;
+import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
+import org.apache.olingo.odata2.api.uri.info.GetSimplePropertyUriInfo;
+import org.apache.olingo.odata2.core.processor.ODataSingleProcessorService;
+import org.apache.olingo.odata2.ref.edm.ScenarioEdmProvider;
+import org.apache.olingo.odata2.testutil.server.ServletType;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Based on OLINGO-763 we changed the behaviour of serializer exceptions. Now they must result in 500 internal server
+ * errors if an application provides false data. This test is to ensure that the serializer throws the correct exception
+ * which then results in the correct status code.
+ */
+public class InvalidDataInScenarioTest extends AbstractRefTest {
+
+  public InvalidDataInScenarioTest(ServletType servletType) {
+    super(servletType);
+  }
+
+  @Override
+  protected ODataSingleProcessorService createService() {
+    ODataSingleProcessor processor = new LocalProcessor();
+    EdmProvider provider = new ScenarioEdmProvider();
+
+    return new ODataSingleProcessorService(provider, processor) {};
+  }
+
+  @Before
+  public void showStacktrace() {
+    disableLogging();
+  }
+
+  @Test
+  public void nullKeyInEntryData() throws Exception {
+    HttpResponse response = callUri("Employees('1')", HttpStatusCodes.INTERNAL_SERVER_ERROR);
+    System.out.println(getBody(response));
+    response = callUri("Employees('1')?$format=json", HttpStatusCodes.INTERNAL_SERVER_ERROR);
+    assertTrue(getBody(response).contains("null value"));
+  }
+
+  @Test
+  public void violatedFacetsInEntry() throws Exception {
+    HttpResponse response = callUri("Employees('2')", HttpStatusCodes.INTERNAL_SERVER_ERROR);
+    assertTrue(getBody(response).contains("metadata constraints"));
+    response = callUri("Employees('2')?$format=json", HttpStatusCodes.INTERNAL_SERVER_ERROR);
+    assertTrue(getBody(response).contains("metadata constraints"));
+  }
+
+  @Test
+  public void nullKeyInFeedData() throws Exception {
+    HttpResponse response = callUri("Employees", HttpStatusCodes.INTERNAL_SERVER_ERROR);
+    assertTrue(getBody(response).contains("null value"));
+    response = callUri("Employees?$format=json", HttpStatusCodes.INTERNAL_SERVER_ERROR);
+    assertTrue(getBody(response).contains("null value"));
+  }
+
+  @Test
+  public void wrongPropertyValueIsNull() throws Exception {
+    HttpResponse response = callUri("Employees('1')/EmployeeId", HttpStatusCodes.INTERNAL_SERVER_ERROR);
+    assertTrue(getBody(response).contains("null value"));
+    response = callUri("Employees('1')/EmployeeId?$format=json", HttpStatusCodes.INTERNAL_SERVER_ERROR);
+    assertTrue(getBody(response).contains("null value"));
+  }
+
+  @Test
+  public void wrongPropertyValueWithFacets() throws Exception {
+    HttpResponse response = callUri("Employees('2')/TeamId", HttpStatusCodes.INTERNAL_SERVER_ERROR);
+    assertTrue(getBody(response).contains("metadata constraints"));
+    response = callUri("Employees('2')/TeamId?$format=json", HttpStatusCodes.INTERNAL_SERVER_ERROR);
+    assertTrue(getBody(response).contains("metadata constraints"));
+  }
+
+  public class LocalProcessor extends ODataSingleProcessor {
+
+    @Override
+    public ODataResponse readEntity(GetEntityUriInfo uriInfo, String contentType) throws ODataException {
+      HashMap<String, Object> data = new HashMap<String, Object>();
+
+      if ("Employees".equals(uriInfo.getTargetEntitySet().getName())) {
+        if ("2".equals(uriInfo.getKeyPredicates().get(0).getLiteral())) {
+          data.put("EmployeeId", "1");
+          data.put("TeamId", "420");
+        }
+
+        ODataContext context = getContext();
+        EntityProviderWriteProperties writeProperties =
+            EntityProviderWriteProperties.serviceRoot(context.getPathInfo().getServiceRoot()).build();
+
+        return EntityProvider.writeEntry(contentType, uriInfo.getTargetEntitySet(), data, writeProperties);
+      } else {
+        throw new ODataApplicationException("Wrong testcall", Locale.getDefault(), HttpStatusCodes.NOT_IMPLEMENTED);
+      }
+    }
+
+    @Override
+    public ODataResponse readEntitySet(GetEntitySetUriInfo uriInfo, String contentType) throws ODataException {
+      if ("Employees".equals(uriInfo.getTargetEntitySet().getName())) {
+        ODataContext context = getContext();
+        EntityProviderWriteProperties writeProperties =
+            EntityProviderWriteProperties.serviceRoot(context.getPathInfo().getServiceRoot()).build();
+        List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
+        data.add(new HashMap<String, Object>());
+        return EntityProvider.writeFeed(contentType, uriInfo.getTargetEntitySet(), data, writeProperties);
+      } else {
+        throw new ODataApplicationException("Wrong testcall", Locale.getDefault(), HttpStatusCodes.NOT_IMPLEMENTED);
+      }
+    }
+
+    @Override
+    public ODataResponse readEntitySimpleProperty(GetSimplePropertyUriInfo uriInfo, String contentType)
+        throws ODataException {
+      EdmProperty edmProperty = uriInfo.getPropertyPath().get(0);
+      Object value = null;
+      if ("EmployeeId".equals(edmProperty.getName())) {
+        // must be null for a specific test
+        value = null;
+      } else if ("TeamId".equals(edmProperty.getName())) {
+        value = new Integer(520);
+      }
+
+      return EntityProvider.writeProperty(contentType, edmProperty, value);
+    }
+  }
+}