You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2016/02/04 14:02:18 UTC

[1/7] olingo-odata4 git commit: [OLINGO-834] better alias support in URI parser

Repository: olingo-odata4
Updated Branches:
  refs/heads/master b317b9006 -> 5d7c1287f


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/AliasImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/AliasImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/AliasImpl.java
index f506dc2..07602c2 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/AliasImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/expression/AliasImpl.java
@@ -19,6 +19,7 @@
 package org.apache.olingo.server.core.uri.queryoption.expression;
 
 import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
 import org.apache.olingo.server.api.uri.queryoption.expression.Alias;
 import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
 import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor;
@@ -26,9 +27,11 @@ import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor
 public class AliasImpl implements Alias {
 
   private final String parameterName;
+  private final AliasQueryOption alias;
 
-  public AliasImpl(final String parameterName) {
+  public AliasImpl(final String parameterName, final AliasQueryOption alias) {
     this.parameterName = parameterName;
+    this.alias = alias;
   }
 
   @Override
@@ -36,6 +39,10 @@ public class AliasImpl implements Alias {
     return parameterName;
   }
 
+  public AliasQueryOption getAlias() {
+    return alias;
+  }
+
   @Override
   public <T> T accept(final ExpressionVisitor<T> visitor) throws ExpressionVisitException, ODataApplicationException {
     return visitor.visitAlias(parameterName);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java
index 1656150..2b446a7 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java
@@ -56,7 +56,9 @@ public class UriValidationException extends ODataLibraryException {
     /** parameter: unallowed resource path */
     UNALLOWED_RESOURCE_PATH,
     /** parameter: missing parameter name */
-    MISSING_PARAMETER;
+    MISSING_PARAMETER,
+    /** parameter: missing alias name */
+    MISSING_ALIAS;
 
     @Override
     public String getKey() {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
index 5d842fb..cec2fc0 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
@@ -18,28 +18,22 @@
  */
 package org.apache.olingo.server.core.uri.validator;
 
-import java.util.HashMap;
+import java.util.Collections;
+import java.util.EnumMap;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.commons.api.edm.EdmFunction;
-import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmProperty;
 import org.apache.olingo.commons.api.edm.EdmReturnType;
 import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
 import org.apache.olingo.commons.api.http.HttpMethod;
 import org.apache.olingo.server.api.uri.UriInfo;
-import org.apache.olingo.server.api.uri.UriParameter;
 import org.apache.olingo.server.api.uri.UriResource;
 import org.apache.olingo.server.api.uri.UriResourceAction;
-import org.apache.olingo.server.api.uri.UriResourceEntitySet;
 import org.apache.olingo.server.api.uri.UriResourceFunction;
 import org.apache.olingo.server.api.uri.UriResourceKind;
-import org.apache.olingo.server.api.uri.UriResourceNavigation;
 import org.apache.olingo.server.api.uri.UriResourcePartTyped;
 import org.apache.olingo.server.api.uri.UriResourceProperty;
 import org.apache.olingo.server.api.uri.queryoption.SystemQueryOption;
@@ -49,7 +43,7 @@ public class UriValidator {
 
   //@formatter:off (Eclipse formatter)
   //CHECKSTYLE:OFF (Maven checkstyle)
-  private final boolean[][] decisionMatrix =
+  private static final boolean[][] decisionMatrix =
     {
       /*                                          0-FILTER 1-FORMAT 2-EXPAND 3-ID     4-COUNT  5-ORDERBY 6-SEARCH 7-SELECT 8-SKIP   9-SKIPTOKEN 10-TOP */
       /*                              all  0 */ { true ,   true ,   true ,   false,   true ,   true ,    true ,   true ,   true ,   true ,      true  },
@@ -62,7 +56,7 @@ public class UriValidator {
       /*                   entitySetCount  7 */ { true ,   false,   false,   false,   false,   false,    true ,   false,   false,   false,      false },
       /*                           entity  8 */ { false,   true ,   true ,   false,   false,   false,    false,   true ,   false,   false,      false },
       /*                      mediaStream  9 */ { false,   false,   false,   false,   false,   false,    false,   false,   false,   false,      false },
-      /*                       references 10 */ { true ,   true ,   false,   true ,   true ,   true ,    true ,   false,   true ,   true ,      true  },
+      /*                       references 10 */ { true ,   true ,   false,   false,   true ,   true ,    true ,   false,   true ,   true ,      true  },
       /*                        reference 11 */ { false,   true ,   false,   false,   false,   false,    false,   false,   false,   false,      false },
       /*                  propertyComplex 12 */ { false,   true ,   true ,   false,   false,   false,    false,   true ,   false,   false,      false },
       /*        propertyComplexCollection 13 */ { true ,   true ,   true ,   false,   true ,   true ,    false,   true ,   true ,   true ,      true  },
@@ -76,7 +70,7 @@ public class UriValidator {
   //CHECKSTYLE:ON
   //@formatter:on
 
-  private enum RowIndexForUriType {
+  private enum UriType {
     all(0),
     batch(1),
     crossjoin(2),
@@ -100,7 +94,7 @@ public class UriValidator {
 
     private final int idx;
 
-    RowIndexForUriType(final int i) {
+    UriType(final int i) {
       idx = i;
     }
 
@@ -109,308 +103,230 @@ public class UriValidator {
     }
   }
 
-  private enum ColumnIndex {
-    filter(0),
-    format(1),
-    expand(2),
-    id(3),
-    count(4),
-    orderby(5),
-    search(6),
-    select(7),
-    skip(8),
-    skiptoken(9),
-    top(10);
-
-    private final int idx;
-
-    ColumnIndex(final int i) {
-      idx = i;
-    }
-
-    public int getIndex() {
-      return idx;
-    }
+  private static Map<SystemQueryOptionKind, Integer> OPTION_INDEX;
+  static {
+    Map<SystemQueryOptionKind, Integer> temp =
+        new EnumMap<SystemQueryOptionKind, Integer>(SystemQueryOptionKind.class);
+    temp.put(SystemQueryOptionKind.FILTER, 0);
+    temp.put(SystemQueryOptionKind.FORMAT, 1);
+    temp.put(SystemQueryOptionKind.EXPAND, 2);
+    temp.put(SystemQueryOptionKind.ID, 3);
+    temp.put(SystemQueryOptionKind.COUNT, 4);
+    temp.put(SystemQueryOptionKind.ORDERBY, 5);
+    temp.put(SystemQueryOptionKind.SEARCH, 6);
+    temp.put(SystemQueryOptionKind.SELECT, 7);
+    temp.put(SystemQueryOptionKind.SKIP, 8);
+    temp.put(SystemQueryOptionKind.SKIPTOKEN, 9);
+    temp.put(SystemQueryOptionKind.TOP, 10);
+    OPTION_INDEX = Collections.unmodifiableMap(temp);
   }
 
   public void validate(final UriInfo uriInfo, final HttpMethod httpMethod) throws UriValidationException {
-    if (HttpMethod.GET != httpMethod) {
-      validateForHttpMethod(uriInfo, httpMethod);
-    }
-    validateQueryOptions(uriInfo);
-    validateParameters(uriInfo);
-    validateKeyPredicates(uriInfo);
-    validatePropertyOperations(uriInfo, httpMethod);
-  }
-
-  private ColumnIndex colIndex(final SystemQueryOptionKind queryOptionKind) throws UriValidationException {
-    ColumnIndex idx;
-    switch (queryOptionKind) {
-    case FILTER:
-      idx = ColumnIndex.filter;
-      break;
-    case FORMAT:
-      idx = ColumnIndex.format;
-      break;
-    case EXPAND:
-      idx = ColumnIndex.expand;
-      break;
-    case ID:
-      idx = ColumnIndex.id;
-      break;
-    case COUNT:
-      idx = ColumnIndex.count;
-      break;
-    case ORDERBY:
-      idx = ColumnIndex.orderby;
-      break;
-    case SEARCH:
-      idx = ColumnIndex.search;
-      break;
-    case SELECT:
-      idx = ColumnIndex.select;
-      break;
-    case SKIP:
-      idx = ColumnIndex.skip;
-      break;
-    case SKIPTOKEN:
-      idx = ColumnIndex.skiptoken;
-      break;
-    case TOP:
-      idx = ColumnIndex.top;
-      break;
-    default:
-      throw new UriValidationException("Unsupported option: " + queryOptionKind.toString(),
-          UriValidationException.MessageKeys.UNSUPPORTED_QUERY_OPTION, queryOptionKind.toString());
+    final UriType uriType = getUriType(uriInfo);
+    if (HttpMethod.GET == httpMethod) {
+      validateReadQueryOptions(uriType, uriInfo.getSystemQueryOptions());
+    } else {
+      validateNonReadQueryOptions(uriType, isAction(uriInfo), uriInfo.getSystemQueryOptions(), httpMethod);
+      validatePropertyOperations(uriInfo, httpMethod);
     }
-
-    return idx;
   }
 
-  private RowIndexForUriType rowIndexForUriType(final UriInfo uriInfo) throws UriValidationException {
-    RowIndexForUriType idx;
+  private UriType getUriType(final UriInfo uriInfo) throws UriValidationException {
+    UriType uriType;
 
     switch (uriInfo.getKind()) {
     case all:
-      idx = RowIndexForUriType.all;
+      uriType = UriType.all;
       break;
     case batch:
-      idx = RowIndexForUriType.batch;
+      uriType = UriType.batch;
       break;
     case crossjoin:
-      idx = RowIndexForUriType.crossjoin;
+      uriType = UriType.crossjoin;
       break;
     case entityId:
-      idx = RowIndexForUriType.entityId;
+      uriType = UriType.entityId;
       break;
     case metadata:
-      idx = RowIndexForUriType.metadata;
+      uriType = UriType.metadata;
       break;
     case resource:
-      idx = rowIndexForResourceKind(uriInfo);
+      uriType = getUriTypeForResource(uriInfo.getUriResourceParts());
       break;
     case service:
-      idx = RowIndexForUriType.service;
+      uriType = UriType.service;
       break;
     default:
       throw new UriValidationException("Unsupported uriInfo kind: " + uriInfo.getKind(),
           UriValidationException.MessageKeys.UNSUPPORTED_URI_KIND, uriInfo.getKind().toString());
     }
 
-    return idx;
+    return uriType;
   }
 
-  private RowIndexForUriType rowIndexForResourceKind(final UriInfo uriInfo) throws UriValidationException {
-    RowIndexForUriType idx;
-    int lastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 1;
-    UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
+  /**
+   * Determines the URI type for a resource path.
+   * The URI parser has already made sure that there are enough segments for a given type of the last segment,
+   * but don't try to extract always the second-to-last segment, it could cause an {@link IndexOutOfBoundsException}.
+   */
+  private UriType getUriTypeForResource(final List<UriResource> segments) throws UriValidationException {
+    final UriResource lastPathSegment = segments.get(segments.size() - 1);
 
+    UriType uriType;
     switch (lastPathSegment.getKind()) {
     case count:
-      idx = rowIndexForCount(uriInfo);
+      uriType = getUriTypeForCount(segments.get(segments.size() - 2));
       break;
     case action:
-      idx = rowIndexForAction(lastPathSegment);
+      uriType = getUriTypeForAction(lastPathSegment);
       break;
     case complexProperty:
-      idx = rowIndexForComplexProperty(lastPathSegment);
+      uriType = getUriTypeForComplexProperty(lastPathSegment);
       break;
     case entitySet:
     case navigationProperty:
-      idx = rowIndexForEntitySet(lastPathSegment);
+      uriType = getUriTypeForEntitySet(lastPathSegment);
       break;
     case function:
-      idx = rowIndexForFunction(lastPathSegment);
+      uriType = getUriTypeForFunction(lastPathSegment);
       break;
     case primitiveProperty:
-      idx = rowIndexForPrimitiveProperty(lastPathSegment);
+      uriType = getUriTypeForPrimitiveProperty(lastPathSegment);
       break;
     case ref:
-      idx = rowIndexForRef(uriInfo, lastPathSegment);
-      break;
-    case root:
-      idx = RowIndexForUriType.service;
+      uriType = getUriTypeForRef(segments.get(segments.size() - 2));
       break;
     case singleton:
-      idx = RowIndexForUriType.entity;
+      uriType = UriType.entity;
       break;
     case value:
-      idx = rowIndexForValue(uriInfo);
+      uriType = getUriTypeForValue(segments.get(segments.size() - 2));
       break;
     default:
       throw new UriValidationException("Unsupported uriResource kind: " + lastPathSegment.getKind(),
           UriValidationException.MessageKeys.UNSUPPORTED_URI_RESOURCE_KIND, lastPathSegment.getKind().toString());
     }
 
-    return idx;
+    return uriType;
   }
 
-  private RowIndexForUriType rowIndexForValue(final UriInfo uriInfo) throws UriValidationException {
-    RowIndexForUriType idx;
-    int secondLastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 2;
-    UriResource secondLastPathSegment = uriInfo.getUriResourceParts().get(secondLastPathSegmentIndex);
-
+  private UriType getUriTypeForValue(final UriResource secondLastPathSegment) throws UriValidationException {
+    UriType uriType;
     switch (secondLastPathSegment.getKind()) {
     case primitiveProperty:
-      idx = RowIndexForUriType.propertyPrimitiveValue;
+      uriType = UriType.propertyPrimitiveValue;
       break;
     case entitySet:
     case navigationProperty:
     case singleton:
-      idx = RowIndexForUriType.mediaStream;
+      uriType = UriType.mediaStream;
       break;
     case function:
       UriResourceFunction uriFunction = (UriResourceFunction) secondLastPathSegment;
       final EdmFunction function = uriFunction.getFunction();
-      idx = function.getReturnType().getType().getKind() == EdmTypeKind.ENTITY ?
-          RowIndexForUriType.mediaStream : RowIndexForUriType.propertyPrimitiveValue;
+      uriType = function.getReturnType().getType().getKind() == EdmTypeKind.ENTITY ?
+          UriType.mediaStream : UriType.propertyPrimitiveValue;
       break;
     default:
       throw new UriValidationException(
           "Unexpected kind in path segment before $value: " + secondLastPathSegment.getKind(),
           UriValidationException.MessageKeys.UNALLOWED_KIND_BEFORE_VALUE, secondLastPathSegment.toString());
     }
-    return idx;
+    return uriType;
   }
 
-  private RowIndexForUriType rowIndexForRef(final UriInfo uriInfo, final UriResource lastPathSegment)
-      throws UriValidationException {
-    int secondLastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 2;
-    UriResource secondLastPathSegment = uriInfo.getUriResourceParts().get(secondLastPathSegmentIndex);
+  private UriType getUriTypeForRef(final UriResource secondLastPathSegment) throws UriValidationException {
+    return isCollection(secondLastPathSegment) ? UriType.references : UriType.reference;
+  }
 
-    if (secondLastPathSegment instanceof UriResourcePartTyped) {
-      return ((UriResourcePartTyped) secondLastPathSegment).isCollection() ?
-          RowIndexForUriType.references : RowIndexForUriType.reference;
+  private boolean isCollection(final UriResource pathSegment) throws UriValidationException {
+    if (pathSegment instanceof UriResourcePartTyped) {
+      return ((UriResourcePartTyped) pathSegment).isCollection();
     } else {
       throw new UriValidationException(
-          "secondLastPathSegment not a class of UriResourcePartTyped: " + lastPathSegment.getClass(),
-          UriValidationException.MessageKeys.LAST_SEGMENT_NOT_TYPED, lastPathSegment.toString());
+          "Path segment is not an instance of UriResourcePartTyped but " + pathSegment.getClass(),
+          UriValidationException.MessageKeys.LAST_SEGMENT_NOT_TYPED, pathSegment.toString());
     }
   }
 
-  private RowIndexForUriType rowIndexForPrimitiveProperty(final UriResource lastPathSegment)
-      throws UriValidationException {
-    if (lastPathSegment instanceof UriResourcePartTyped) {
-      return ((UriResourcePartTyped) lastPathSegment).isCollection() ?
-          RowIndexForUriType.propertyPrimitiveCollection : RowIndexForUriType.propertyPrimitive;
-    } else {
-      throw new UriValidationException(
-          "lastPathSegment not a class of UriResourcePartTyped: " + lastPathSegment.getClass(),
-          UriValidationException.MessageKeys.LAST_SEGMENT_NOT_TYPED, lastPathSegment.toString());
-    }
+  private UriType getUriTypeForPrimitiveProperty(final UriResource lastPathSegment) throws UriValidationException {
+    return isCollection(lastPathSegment) ? UriType.propertyPrimitiveCollection : UriType.propertyPrimitive;
   }
 
-  private RowIndexForUriType rowIndexForFunction(final UriResource lastPathSegment) throws UriValidationException {
+  private UriType getUriTypeForFunction(final UriResource lastPathSegment) throws UriValidationException {
     final UriResourceFunction uriFunction = (UriResourceFunction) lastPathSegment;
     if (!uriFunction.getFunction().isComposable()) {
-      return RowIndexForUriType.none;
+      return UriType.none;
     }
 
     final boolean isCollection = uriFunction.isCollection();
     final EdmTypeKind typeKind = uriFunction.getFunction().getReturnType().getType().getKind();
-    RowIndexForUriType idx;
+    UriType uriType;
     switch (typeKind) {
     case ENTITY:
-      idx = isCollection ? RowIndexForUriType.entitySet : RowIndexForUriType.entity;
+      uriType = isCollection ? UriType.entitySet : UriType.entity;
       break;
     case PRIMITIVE:
     case ENUM:
     case DEFINITION:
-      idx = isCollection ? RowIndexForUriType.propertyPrimitiveCollection : RowIndexForUriType.propertyPrimitive;
+      uriType = isCollection ? UriType.propertyPrimitiveCollection : UriType.propertyPrimitive;
       break;
     case COMPLEX:
-      idx = isCollection ? RowIndexForUriType.propertyComplexCollection : RowIndexForUriType.propertyComplex;
+      uriType = isCollection ? UriType.propertyComplexCollection : UriType.propertyComplex;
       break;
     default:
       throw new UriValidationException("Unsupported function return type: " + typeKind,
           UriValidationException.MessageKeys.UNSUPPORTED_FUNCTION_RETURN_TYPE, typeKind.toString());
     }
 
-    return idx;
+    return uriType;
   }
 
-  private RowIndexForUriType rowIndexForEntitySet(final UriResource lastPathSegment) throws UriValidationException {
-    if (lastPathSegment instanceof UriResourcePartTyped) {
-      return ((UriResourcePartTyped) lastPathSegment).isCollection() ?
-          RowIndexForUriType.entitySet : RowIndexForUriType.entity;
-    } else {
-      throw new UriValidationException("lastPathSegment not a class of UriResourcePartTyped: "
-          + lastPathSegment.getClass(), UriValidationException.MessageKeys.LAST_SEGMENT_NOT_TYPED,
-          lastPathSegment.toString());
-    }
+  private UriType getUriTypeForEntitySet(final UriResource lastPathSegment) throws UriValidationException {
+    return isCollection(lastPathSegment) ? UriType.entitySet : UriType.entity;
   }
 
-  private RowIndexForUriType rowIndexForComplexProperty(final UriResource lastPathSegment)
-      throws UriValidationException {
-    if (lastPathSegment instanceof UriResourcePartTyped) {
-      return ((UriResourcePartTyped) lastPathSegment).isCollection() ?
-          RowIndexForUriType.propertyComplexCollection : RowIndexForUriType.propertyComplex;
-    } else {
-      throw new UriValidationException("lastPathSegment not a class of UriResourcePartTyped: "
-          + lastPathSegment.getClass(), UriValidationException.MessageKeys.LAST_SEGMENT_NOT_TYPED,
-          lastPathSegment.toString());
-    }
+  private UriType getUriTypeForComplexProperty(final UriResource lastPathSegment) throws UriValidationException {
+    return isCollection(lastPathSegment) ? UriType.propertyComplexCollection : UriType.propertyComplex;
   }
 
-  private RowIndexForUriType rowIndexForAction(final UriResource lastPathSegment) throws UriValidationException {
+  private UriType getUriTypeForAction(final UriResource lastPathSegment) throws UriValidationException {
     final EdmReturnType rt = ((UriResourceAction) lastPathSegment).getAction().getReturnType();
     if (rt == null) {
-      return RowIndexForUriType.none;
+      return UriType.none;
     }
-    RowIndexForUriType idx;
+    UriType uriType;
     switch (rt.getType().getKind()) {
     case ENTITY:
-      idx = rt.isCollection() ? RowIndexForUriType.entitySet : RowIndexForUriType.entity;
+      uriType = rt.isCollection() ? UriType.entitySet : UriType.entity;
       break;
     case PRIMITIVE:
     case ENUM:
     case DEFINITION:
-      idx = rt.isCollection() ? RowIndexForUriType.propertyPrimitiveCollection : RowIndexForUriType.propertyPrimitive;
+      uriType = rt.isCollection() ? UriType.propertyPrimitiveCollection : UriType.propertyPrimitive;
       break;
     case COMPLEX:
-      idx = rt.isCollection() ? RowIndexForUriType.propertyComplexCollection : RowIndexForUriType.propertyComplex;
+      uriType = rt.isCollection() ? UriType.propertyComplexCollection : UriType.propertyComplex;
       break;
     default:
       throw new UriValidationException("Unsupported action return type: " + rt.getType().getKind(),
           UriValidationException.MessageKeys.UNSUPPORTED_ACTION_RETURN_TYPE, rt.getType().getKind().toString());
     }
-    return idx;
+    return uriType;
   }
 
-  private RowIndexForUriType rowIndexForCount(final UriInfo uriInfo) throws UriValidationException {
-    RowIndexForUriType idx;
-    int secondLastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 2;
-    UriResource secondLastPathSegment = uriInfo.getUriResourceParts().get(secondLastPathSegmentIndex);
+  private UriType getUriTypeForCount(final UriResource secondLastPathSegment) throws UriValidationException {
+    UriType uriType;
     switch (secondLastPathSegment.getKind()) {
     case entitySet:
     case navigationProperty:
-      idx = RowIndexForUriType.entitySetCount;
+      uriType = UriType.entitySetCount;
       break;
     case complexProperty:
-      idx = RowIndexForUriType.propertyComplexCollectionCount;
+      uriType = UriType.propertyComplexCollectionCount;
       break;
     case primitiveProperty:
-      idx = RowIndexForUriType.propertyPrimitiveCollectionCount;
+      uriType = UriType.propertyPrimitiveCollectionCount;
       break;
     case function:
       final UriResourceFunction uriFunction = (UriResourceFunction) secondLastPathSegment;
@@ -418,15 +334,15 @@ public class UriValidator {
       final EdmType returnType = function.getReturnType().getType();
       switch (returnType.getKind()) {
       case ENTITY:
-        idx = RowIndexForUriType.entitySetCount;
+        uriType = UriType.entitySetCount;
         break;
       case COMPLEX:
-        idx = RowIndexForUriType.propertyComplexCollectionCount;
+        uriType = UriType.propertyComplexCollectionCount;
         break;
       case PRIMITIVE:
       case ENUM:
       case DEFINITION:
-        idx = RowIndexForUriType.propertyPrimitiveCollectionCount;
+        uriType = UriType.propertyPrimitiveCollectionCount;
         break;
       default:
         throw new UriValidationException("Unsupported return type: " + returnType.getKind(),
@@ -438,80 +354,54 @@ public class UriValidator {
           UriValidationException.MessageKeys.UNALLOWED_KIND_BEFORE_COUNT, secondLastPathSegment.toString());
     }
 
-    return idx;
+    return uriType;
   }
 
-  private void validateQueryOptions(final UriInfo uriInfo) throws UriValidationException {
-    RowIndexForUriType row = rowIndexForUriType(uriInfo);
-
-    for (SystemQueryOption option : uriInfo.getSystemQueryOptions()) {
-      ColumnIndex col = colIndex(option.getKind());
-
-      if (!decisionMatrix[row.getIndex()][col.getIndex()]) {
-        throw new UriValidationException("System query option not allowed: " + option.getName(),
-            UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED, option.getName());
-      }
-    }
-  }
-
-  private void validateForHttpMethod(final UriInfo uriInfo, final HttpMethod httpMethod) throws UriValidationException {
-    switch (httpMethod) {
-    case POST:
-      if (!isAction(uriInfo)) {
-        // POST and SystemQueryOptions only allowed if addressed resource is an action
-        validateNoQueryOptionsForHttpMethod(uriInfo, httpMethod);
-      }
-      break;
-    case DELETE:
-      if (!isReferences(uriInfo)) {
-        // DELETE and SystemQueryOptions only allowed if addressed resource is a reference collection
-        validateNoQueryOptionsForHttpMethod(uriInfo, httpMethod);
-      } else {
-        // Only $id allowed as SystemQueryOption for DELETE and references
-        for (SystemQueryOption option : uriInfo.getSystemQueryOptions()) {
-          if (SystemQueryOptionKind.ID != option.getKind()) {
-            throw new UriValidationException(
-                "System query option " + option.getName() + " not allowed for method " + httpMethod,
-                UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED_FOR_HTTP_METHOD,
-                option.getName(), httpMethod.toString());
-          }
+  private void validateReadQueryOptions(final UriType uriType, final List<SystemQueryOption> options)
+      throws UriValidationException {
+    for (final SystemQueryOption option : options) {
+      final SystemQueryOptionKind kind = option.getKind();
+      if (OPTION_INDEX.containsKey(kind)) {
+        final int columnIndex = OPTION_INDEX.get(kind);
+        if (!decisionMatrix[uriType.getIndex()][columnIndex]) {
+          throw new UriValidationException("System query option not allowed: " + option.getName(),
+              UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED, option.getName());
         }
+      } else {
+        throw new UriValidationException("Unsupported option: " + kind,
+            UriValidationException.MessageKeys.UNSUPPORTED_QUERY_OPTION, kind.toString());
       }
-      break;
-    case PUT:
-    case PATCH:
-      // PUT and PATCH do not allow system query options
-      validateNoQueryOptionsForHttpMethod(uriInfo, httpMethod);
-      break;
-    default:
-      throw new UriValidationException("HTTP method not supported: " + httpMethod,
-          UriValidationException.MessageKeys.UNSUPPORTED_HTTP_METHOD, httpMethod.toString());
     }
-
   }
 
-  private boolean isReferences(final UriInfo uriInfo) {
-    if (!uriInfo.getSystemQueryOptions().isEmpty()) {
-      List<UriResource> uriResourceParts = uriInfo.getUriResourceParts();
-      if (UriResourceKind.ref == uriResourceParts.get(uriResourceParts.size() - 1).getKind()) {
-        UriResourcePartTyped previousSegment = (UriResourcePartTyped) uriResourceParts.get(uriResourceParts.size() - 2);
-        return previousSegment.isCollection();
+  private void validateNonReadQueryOptions(final UriType uriType, final boolean isAction,
+      final List<SystemQueryOption> options, final HttpMethod httpMethod) throws UriValidationException {
+    if (httpMethod == HttpMethod.POST && isAction) {
+      // From the OData specification:
+      // For POST requests to an action URL the return type of the action determines the applicable
+      // system query options that a service MAY support, following the same rules as GET requests.
+      validateReadQueryOptions(uriType, options);
+
+    } else if (httpMethod == HttpMethod.DELETE && uriType == UriType.references) {
+      // Only $id is allowed as SystemQueryOption for DELETE on a reference collection.
+      for (final SystemQueryOption option : options) {
+        if (SystemQueryOptionKind.ID != option.getKind()) {
+          throw new UriValidationException(
+              "System query option " + option.getName() + " is not allowed for method " + httpMethod,
+              UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED_FOR_HTTP_METHOD,
+              option.getName(), httpMethod.toString());
+        }
       }
-    }
-    return false;
-  }
 
-  private void validateNoQueryOptionsForHttpMethod(final UriInfo uriInfo, final HttpMethod httpMethod)
-      throws UriValidationException {
-    if (!uriInfo.getSystemQueryOptions().isEmpty()) {
-      StringBuilder options = new StringBuilder();
-      for (SystemQueryOption option : uriInfo.getSystemQueryOptions()) {
-        options.append(option.getName()).append(" ");
+    } else if (!options.isEmpty()) {
+      StringBuilder optionsString = new StringBuilder();
+      for (final SystemQueryOption option : options) {
+        optionsString.append(option.getName()).append(' ');
       }
       throw new UriValidationException(
-          "System query option " + options.toString() + " not allowed for method " + httpMethod,
+          "System query option(s) " + optionsString.toString() + "not allowed for method " + httpMethod,
           UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED_FOR_HTTP_METHOD,
-          options.toString(), httpMethod.toString());
+          optionsString.toString(), httpMethod.toString());
     }
   }
 
@@ -521,139 +411,6 @@ public class UriValidator {
         && UriResourceKind.action == uriResourceParts.get(uriResourceParts.size() - 1).getKind();
   }
 
-  private void validateParameters(final UriInfo uriInfo) throws UriValidationException {
-    for (UriResource pathSegment : uriInfo.getUriResourceParts()) {
-      final boolean isFunction = pathSegment.getKind() == UriResourceKind.function;
-
-      if (isFunction) {
-        final UriResourceFunction functionPathSegment = (UriResourceFunction) pathSegment;
-        final EdmFunction edmFunction = functionPathSegment.getFunction();
-
-        final Map<String, UriParameter> parameters = new HashMap<String, UriParameter>();
-        for (final UriParameter parameter : functionPathSegment.getParameters()) {
-          parameters.put(parameter.getName(), parameter);
-        }
-
-        boolean firstParameter = true;
-        for (final String parameterName : edmFunction.getParameterNames()) {
-          final UriParameter parameter = parameters.get(parameterName);
-          final boolean isNullable = edmFunction.getParameter(parameterName).isNullable();
-
-          if (parameter != null) {
-            /** No alias, value explicit null */
-            if (parameter.getText() == null
-                && parameter.getAlias() == null && !isNullable) {
-              throw new UriValidationException("Missing non nullable parameter " + parameterName,
-                  UriValidationException.MessageKeys.MISSING_PARAMETER, parameterName);
-            } else if (parameter.getText() == null && parameter.getAlias() != null) {
-              final String valueForAlias = uriInfo.getValueForAlias(parameter.getAlias());
-              /** Alias value is missing or explicit null **/
-              if (valueForAlias == null && !isNullable) {
-                throw new UriValidationException("Missing non nullable parameter " + parameterName,
-                    UriValidationException.MessageKeys.MISSING_PARAMETER, parameterName);
-              }
-            }
-
-            parameters.remove(parameterName);
-          } else if (!isNullable && !(firstParameter && edmFunction.isBound())) {
-            // The first parameter of bound functions is implicit provided by the preceding path segment
-            throw new UriValidationException("Missing non nullable parameter " + parameterName,
-                UriValidationException.MessageKeys.MISSING_PARAMETER, parameterName);
-          }
-
-          firstParameter = false;
-        }
-
-        if (!parameters.isEmpty()) {
-          final String parameterName = parameters.keySet().iterator().next();
-          throw new UriValidationException("Unsupported parameter " + parameterName,
-              UriValidationException.MessageKeys.UNSUPPORTED_PARAMETER, parameterName);
-        }
-      }
-    }
-  }
-
-  private void validateKeyPredicates(final UriInfo uriInfo) throws UriValidationException {
-    for (UriResource pathSegment : uriInfo.getUriResourceParts()) {
-      final boolean isEntitySet = pathSegment.getKind() == UriResourceKind.entitySet;
-      final boolean isEntityColFunction = isEntityColFunction(pathSegment);
-
-      if (isEntitySet || pathSegment.getKind() == UriResourceKind.navigationProperty || isEntityColFunction) {
-        final List<UriParameter> keyPredicates = isEntitySet ?
-            ((UriResourceEntitySet) pathSegment).getKeyPredicates() :
-            isEntityColFunction ?
-                ((UriResourceFunction) pathSegment).getKeyPredicates() :
-                ((UriResourceNavigation) pathSegment).getKeyPredicates();
-
-        if (keyPredicates != null) {
-                final EdmEntityType entityType = isEntitySet ?
-                    ((UriResourceEntitySet) pathSegment).getEntityType() :
-                      isEntityColFunction ? (EdmEntityType) ((UriResourceFunction) pathSegment).getType()
-                  : (EdmEntityType) ((UriResourceNavigation) pathSegment).getType();
-                      final List<String> keyPredicateNames = entityType.getKeyPredicateNames();
-                      Map<String, EdmKeyPropertyRef> edmKeys = new HashMap<String, EdmKeyPropertyRef>();
-                      for (EdmKeyPropertyRef key : entityType.getKeyPropertyRefs()) {
-                        edmKeys.put(key.getName(), key);
-                        final String alias = key.getAlias();
-                        if (alias != null) {
-                          edmKeys.put(alias, key);
-                        }
-                      }
-
-                      for (UriParameter keyPredicate : keyPredicates) {
-                        final String name = keyPredicate.getName();
-                        final String alias = keyPredicate.getAlias();
-
-                        if (keyPredicate.getReferencedProperty() == null) {
-                          final String value = alias == null ?
-                              keyPredicate.getText() :
-                                uriInfo.getValueForAlias(alias);
-
-                              EdmKeyPropertyRef edmKey = edmKeys.get(name);
-                              if (edmKey == null) {
-                                if (keyPredicateNames.contains(name)) {
-                                  throw new UriValidationException("Double key property: " + name,
-                                      UriValidationException.MessageKeys.DOUBLE_KEY_PROPERTY, name);
-                                } else {
-                                  throw new UriValidationException("Unknown key property: " + name,
-                                      UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, name);
-                                }
-                              }
-
-                              final EdmProperty property = edmKey.getProperty();
-                              final EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) property.getType();
-                              try {
-                                if (!edmPrimitiveType.validate(edmPrimitiveType.fromUriLiteral(value),
-                                    property.isNullable(), property.getMaxLength(),
-                                    property.getPrecision(), property.getScale(), property.isUnicode())) {
-                                  throw new UriValidationException("PrimitiveTypeException",
-                                      UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, name);
-                                }
-                              } catch (EdmPrimitiveTypeException e) {
-                                throw new UriValidationException("PrimitiveTypeException", e,
-                                    UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, name);
-                              }
-                        }
-
-                        edmKeys.remove(name);
-                        edmKeys.remove(alias);
-                      }
-              }
-      }
-    }
-  }
-
-  private boolean isEntityColFunction(final UriResource pathSegment) {
-    if (pathSegment.getKind() == UriResourceKind.function) {
-      final UriResourceFunction resourceFunction = (UriResourceFunction) pathSegment;
-      final EdmReturnType returnType = resourceFunction.getFunction().getReturnType();
-
-      return returnType.isCollection() && returnType.getType().getKind() == EdmTypeKind.ENTITY;
-    } else {
-      return false;
-    }
-  }
-
   private void validatePropertyOperations(final UriInfo uriInfo, final HttpMethod method)
       throws UriValidationException {
     final List<UriResource> parts = uriInfo.getUriResourceParts();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
index 6bbad3b..ef5e744 100644
--- a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
+++ b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
@@ -89,6 +89,7 @@ UriValidationException.UNALLOWED_KIND_BEFORE_VALUE=The kind '%1$s' is not allowe
 UriValidationException.UNALLOWED_KIND_BEFORE_COUNT=The kind '%1$s' is not allowed before '$count'.
 UriValidationException.UNALLOWED_RESOURCE_PATH=The resource part '%1$s' is not allowed.
 UriValidationException.MISSING_PARAMETER=Missing mandatory parameter '%1$s'.
+UriValidationException.MISSING_ALIAS=Missing alias '%1$s'.
 
 ContentNegotiatorException.UNSUPPORTED_ACCEPT_TYPES=The content-type range '%1$s' is not supported as value of the Accept header.
 ContentNegotiatorException.UNSUPPORTED_CONTENT_TYPE=The content type '%1$s' is not supported.

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
index 68e6637..bdc2986 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
@@ -23,8 +23,6 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-import java.util.Arrays;
-
 import org.apache.olingo.commons.api.edm.EdmAction;
 import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.commons.api.ex.ODataRuntimeException;
@@ -122,31 +120,30 @@ public class UriInfoImplTest {
     final QueryOption top = new TopOptionImpl().setName("");
     final QueryOption levels = new LevelsOptionImpl().setName("");
 
-    final QueryOption customOption0 = new CustomQueryOptionImpl().setName("").setText("A");
-    final QueryOption customOption1 = new CustomQueryOptionImpl().setName("").setText("B");
+    final QueryOption customOption0 = new CustomQueryOptionImpl().setName("0").setText("A");
+    final QueryOption customOption1 = new CustomQueryOptionImpl().setName("1").setText("B");
 
     final QueryOption initialQueryOption = new CustomQueryOptionImpl();
 
     final QueryOption alias = new AliasQueryOptionImpl().setName("alias").setText("C");
 
     final UriInfo uriInfo = new UriInfoImpl()
-        .setQueryOptions(Arrays.asList(
-            expand,
-            filter,
-            format,
-            id,
-            inlinecount,
-            orderby,
-            search,
-            select,
-            skip,
-            skipToken,
-            top,
-            customOption0,
-            customOption1,
-            levels,
-            initialQueryOption,
-            alias));
+        .setQueryOption(expand)
+        .setQueryOption(filter)
+        .setQueryOption(format)
+        .setQueryOption(id)
+        .setQueryOption(inlinecount)
+        .setQueryOption(orderby)
+        .setQueryOption(search)
+        .setQueryOption(select)
+        .setQueryOption(skip)
+        .setQueryOption(skipToken)
+        .setQueryOption(top)
+        .setQueryOption(customOption0)
+        .setQueryOption(customOption1)
+        .setQueryOption(levels)
+        .setQueryOption(initialQueryOption)
+        .setQueryOption(alias);
 
     assertEquals(12, uriInfo.getSystemQueryOptions().size());
     assertEquals(expand, uriInfo.getExpandOption());
@@ -164,7 +161,7 @@ public class UriInfoImplTest {
     assertArrayEquals(new QueryOption[] { alias }, uriInfo.getAliases().toArray());
     assertEquals("C", uriInfo.getValueForAlias("alias"));
 
-    assertArrayEquals(new QueryOption[] { customOption0, customOption1, initialQueryOption },
+    assertArrayEquals(new QueryOption[] { customOption0, customOption1 },
         uriInfo.getCustomQueryOptions().toArray());
   }
 
@@ -185,7 +182,6 @@ public class UriInfoImplTest {
   @Test
   public void alias() {
     final UriInfo uriInfo = new UriInfoImpl()
-        .addAlias((AliasQueryOption) new AliasQueryOptionImpl().setName("A").setText("notUsed"))
         .addAlias((AliasQueryOption) new AliasQueryOptionImpl().setName("A").setText("X"))
         .addAlias((AliasQueryOption) new AliasQueryOptionImpl().setName("B").setText("Y"))
         .addAlias((AliasQueryOption) new AliasQueryOptionImpl().setName("C").setText("Z"));
@@ -199,4 +195,12 @@ public class UriInfoImplTest {
     assertTrue(uriInfo.getSystemQueryOptions().isEmpty());
     assertTrue(uriInfo.getCustomQueryOptions().isEmpty());
   }
+
+  @Test(expected = ODataRuntimeException.class)
+  public void doubleAlias() {
+    final AliasQueryOption alias = (AliasQueryOption) new AliasQueryOptionImpl().setName("A");
+    new UriInfoImpl()
+        .addAlias(alias)
+        .addAlias(alias);
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/ExpressionParserTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/ExpressionParserTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/ExpressionParserTest.java
index a5fda50..1fce7b5 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/ExpressionParserTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/ExpressionParserTest.java
@@ -252,7 +252,7 @@ public class ExpressionParserTest {
   private Expression parseExpression(final String expressionString)
       throws UriParserException, UriValidationException {
     UriTokenizer tokenizer = new UriTokenizer(expressionString);
-    final Expression expression = new ExpressionParser(mock(Edm.class), odata).parse(tokenizer, null, null);
+    final Expression expression = new ExpressionParser(mock(Edm.class), odata).parse(tokenizer, null, null, null);
     assertNotNull(expression);
     assertTrue(tokenizer.next(TokenKind.EOF));
     return expression;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/UriTokenizerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/UriTokenizerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/UriTokenizerTest.java
index 3ca49c8..118e2ea 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/UriTokenizerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/UriTokenizerTest.java
@@ -371,6 +371,9 @@ public class UriTokenizerTest {
     assertTrue(new UriTokenizer("{\"name\":null}").next(TokenKind.jsonArrayOrObject));
     assertTrue(new UriTokenizer("{\"name\":\"value\"}").next(TokenKind.jsonArrayOrObject));
     assertTrue(new UriTokenizer("{\"name\":\"value\",\"name2\":null}").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new UriTokenizer("{\"name\"}").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new UriTokenizer("{\"name\":}").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new UriTokenizer("{0}").next(TokenKind.jsonArrayOrObject));
 
     // array with values
     assertTrue(new UriTokenizer("[]").next(TokenKind.jsonArrayOrObject));

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
index 20cbf94..9dad2b9 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
@@ -62,6 +62,7 @@ import org.apache.olingo.server.api.serializer.SerializerException;
 import org.apache.olingo.server.api.uri.UriInfoResource;
 import org.apache.olingo.server.api.uri.UriParameter;
 import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+import org.apache.olingo.server.api.uri.queryoption.expression.Literal;
 
 public class DataProvider {
 
@@ -104,7 +105,12 @@ public class DataProvider {
           final EdmProperty property = (EdmProperty) edmEntityType.getProperty(key.getName());
           final EdmPrimitiveType type = (EdmPrimitiveType) property.getType();
           final Object value = entity.getProperty(key.getName()).getValue();
-          final Object keyValue = type.valueOfString(type.fromUriLiteral(key.getText()),
+          if (key.getExpression() != null && !(key.getExpression() instanceof Literal)) {
+            throw new DataProviderException("Expression in key value is not supported yet!",
+                HttpStatusCode.NOT_IMPLEMENTED);
+          }
+          final String text = key.getAlias() == null ? key.getText() : ((Literal) key.getExpression()).getText();
+          final Object keyValue = type.valueOfString(type.fromUriLiteral(text),
               property.isNullable(), property.getMaxLength(), property.getPrecision(), property.getScale(),
               property.isUnicode(),
               Calendar.class.isAssignableFrom(value.getClass()) ? Calendar.class : value.getClass());
@@ -540,6 +546,10 @@ public class DataProvider {
       final List<UriParameter> parameters, final UriInfoResource uriInfo) throws DataProviderException {
     Map<String, Parameter> values = new HashMap<String, Parameter>();
     for (final UriParameter parameter : parameters) {
+      if (parameter.getExpression() != null && !(parameter.getExpression() instanceof Literal)) {
+        throw new DataProviderException("Expression in function-parameter value is not supported yet!",
+            HttpStatusCode.NOT_IMPLEMENTED);
+      }
       final EdmParameter edmParameter = function.getParameter(parameter.getName());
       final String text = parameter.getAlias() == null ?
           parameter.getText() :

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/SystemQueryOptionsRuntimeException.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/SystemQueryOptionsRuntimeException.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/SystemQueryOptionsRuntimeException.java
index 469052d..9b74378 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/SystemQueryOptionsRuntimeException.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/SystemQueryOptionsRuntimeException.java
@@ -18,13 +18,14 @@
  */
 package org.apache.olingo.server.tecsvc.processor.queryoptions.options;
 
+import org.apache.olingo.commons.api.ex.ODataException;
 import org.apache.olingo.commons.api.ex.ODataRuntimeException;
 
 public class SystemQueryOptionsRuntimeException extends ODataRuntimeException {
 
   private static final long serialVersionUID = 1L;
 
-  public SystemQueryOptionsRuntimeException(final Exception cause) {
+  public SystemQueryOptionsRuntimeException(final ODataException cause) {
     super(cause);
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java
index 3fc164e..aeeb167 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ContainerProvider.java
@@ -206,7 +206,7 @@ public class ContainerProvider {
             .setAnnotations(Arrays.asList(
                 new CsdlAnnotation().setTerm("Core.Description")
                     .setExpression(new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.String)
-                        .setValue("Contains entities with two primitve types")),
+                        .setValue("Contains entities with two primitive types")),
                 new CsdlAnnotation().setTerm(TermProvider.TERM_DATA.getFullQualifiedNameAsString()).setExpression(
                     new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.Bool, "true"))));
       } else if (name.equals("ESMixPrimCollComp")) {
@@ -217,7 +217,7 @@ public class ContainerProvider {
                 new CsdlAnnotation().setTerm("Core.Description")
                     .setExpression(new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.String)
                         .setValue("Contains entities with various properties of type primitive, collection "
-                            + "of primitve, complex and collection of complex")),
+                            + "of primitive, complex and collection of complex")),
                 new CsdlAnnotation().setTerm(TermProvider.TERM_DATA.getFullQualifiedNameAsString()).setExpression(
                     new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.Bool, "true"))));
 
@@ -609,7 +609,7 @@ public class ContainerProvider {
                 new CsdlAnnotation().setTerm("Core.Description")
                     .setExpression(new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.String)
                         .setValue("Contains entities with a complex type, "
-                            + "various nested primitve types and collections")),
+                            + "various nested primitive types and collections")),
                 new CsdlAnnotation().setTerm(TermProvider.TERM_DATA.getFullQualifiedNameAsString()).setExpression(
                     new CsdlConstantExpression(CsdlConstantExpression.ConstantExpressionType.Bool, "true"))));
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/TestFullResourcePath.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/TestFullResourcePath.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/TestFullResourcePath.java
index 5a03676..fc9a0b8 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/TestFullResourcePath.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/TestFullResourcePath.java
@@ -53,13 +53,9 @@ public class TestFullResourcePath {
   private static final OData oData = OData.newInstance();
   private static final Edm edm = oData.createServiceMetadata(
       new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
-  private final TestUriValidator testUri;
-  private final FilterValidator testFilter;
 
-  public TestFullResourcePath() {
-    testUri = new TestUriValidator().setEdm(edm);
-    testFilter = new FilterValidator().setEdm(edm);
-  }
+  private final TestUriValidator testUri = new TestUriValidator().setEdm(edm);
+  private final FilterValidator testFilter = new FilterValidator().setEdm(edm);
 
   @Test
   public void enumAndTypeDefAsKey() throws Exception {
@@ -1229,7 +1225,6 @@ public class TestFullResourcePath {
         .isType(EntityTypeProvider.nameETTwoPrim, false)
         .isTypeFilterOnCollection(EntityTypeProvider.nameETTwoBase)
         .isKeyPredicate(0, "PropertyInt16", "-32768");
-
   }
 
   @Test
@@ -2062,15 +2057,6 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void runFunctionImpEsAlias() throws Exception {
-
-    testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=@parameterAlias)", "@parameterAlias=1");
-    testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=@parameterAlias)/$count", "@parameterAlias=1");
-    testUri.runEx("FICRTCollESTwoKeyNavParam(ParameterInt16=@invalidAlias)", "@validAlias=1")
-        .isExValidation(UriValidationException.MessageKeys.MISSING_PARAMETER);
-  }
-
-  @Test
   public void runFunctionImpEsCast() throws Exception {
 
     testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=1)/olingo.odata.test1.ETBaseTwoKeyNav")
@@ -2650,6 +2636,13 @@ public class TestFullResourcePath {
         .n()
         .isNavProperty("NavPropertyETTwoKeyNavOne", EntityTypeProvider.nameETTwoKeyNav, false);
 
+    testUri.run("ESTwoKeyNav", "$expand=olingo.odata.test1.ETBaseTwoKeyNav/PropertyCompNav/*")
+        .isKind(UriInfoKind.resource).goPath().first()
+        .goExpand().first()
+        .isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
+        .isSegmentStar()
+        .goPath().last().isComplexProperty("PropertyCompNav", ComplexTypeProvider.nameCTBasePrimCompNav, false);
+
     testUri.run("ESTwoKeyNav", "$expand=olingo.odata.test1.ETBaseTwoKeyNav/PropertyCompNav"
         + "/olingo.odata.test1.CTTwoBasePrimCompNav/NavPropertyETTwoKeyNavOne")
         .isKind(UriInfoKind.resource).goPath().first()
@@ -2736,6 +2729,8 @@ public class TestFullResourcePath {
         .isExSemantic(MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
     testUri.runEx("ESTwoKeyNav", "$expand=PropertyCompNav/undefined")
         .isExSemantic(MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
+    testUri.runEx("ESTwoKeyNav", "$expand=PropertyCompNav/*+")
+        .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
   }
 
   @Test
@@ -2874,6 +2869,7 @@ public class TestFullResourcePath {
         .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
     testUri.runEx("ESTwoKeyNav", "$select=olingo.odata.test1.1")
         .isExSemantic(MessageKeys.UNKNOWN_PART);
+    testUri.runEx("ESTwoKeyNav", "$select=unknown_namespace.*").isExSemantic(MessageKeys.UNKNOWN_PART);
     testUri.runEx("ESTwoKeyNav", "$select=olingo.odata.test1.ETKeyNav")
         .isExSemantic(MessageKeys.INCOMPATIBLE_TYPE_FILTER);
     testUri.runEx("ESTwoKeyNav", "$select=PropertyCompNav/olingo.odata.test1.CTTwoPrim")
@@ -3771,7 +3767,8 @@ public class TestFullResourcePath {
   @Test
   public void filterFunctions() throws Exception {
     testFilter.runOnETAllPrim(
-        "olingo.odata.test1.UFCRTETTwoKeyNavParamCTTwoPrim(ParameterCTTwoPrim=@ParamAlias) eq null")
+        "olingo.odata.test1.UFCRTETTwoKeyNavParamCTTwoPrim(ParameterCTTwoPrim=@ParamAlias) eq null"
+        + "&@ParamAlias={}")
         .is("<<UFCRTETTwoKeyNavParamCTTwoPrim> eq <null>>")
         .left().goPath()
         .first()
@@ -3803,14 +3800,14 @@ public class TestFullResourcePath {
         .n().isPrimitiveProperty("PropertyString", PropertyProvider.nameString, false);
 
     testFilter.runOnETTwoKeyNav("PropertyComp/olingo.odata.test1.BFCCTPrimCompRTETTwoKeyNavParam"
-        + "(ParameterString=null)/PropertyString eq 'SomeString'")
+        + "(ParameterString='1')/PropertyString eq 'SomeString'")
         .is("<<PropertyComp/BFCCTPrimCompRTETTwoKeyNavParam/PropertyString> eq <'SomeString'>>")
         .root().left().goPath()
         .first()
         .isComplexProperty("PropertyComp", ComplexTypeProvider.nameCTPrimComp, false)
         .n()
         .isFunction("BFCCTPrimCompRTETTwoKeyNavParam")
-        .isParameter(0, "ParameterString", null)
+        .isParameter(0, "ParameterString", "'1'")
         .n()
         .isPrimitiveProperty("PropertyString", PropertyProvider.nameString, false);
 
@@ -3880,7 +3877,8 @@ public class TestFullResourcePath {
         .isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, false);
 
     testFilter.runOnETTwoKeyNav("olingo.odata.test1.UFCRTETTwoKeyNavParam(ParameterInt16=@Param1Alias)"
-        + "/PropertyInt16 eq 2")
+        + "/PropertyInt16 eq 2"
+        + "&@Param1Alias=1")
         .root().left().goPath()
         .first()
         .isFunction("UFCRTETTwoKeyNavParam")
@@ -3912,6 +3910,9 @@ public class TestFullResourcePath {
         .n().isComplexProperty("PropertyComp", ComplexTypeProvider.nameCTPrimComp, false)
         .n().isComplexProperty("PropertyComp", ComplexTypeProvider.nameCTAllPrim, false)
         .n().isPrimitiveProperty("PropertyString", PropertyProvider.nameString, false);
+
+    testFilter.runOnETTwoKeyNavEx("olingo.odata.test1.UFCRTETTwoKeyNavParam(ParameterInt16=@alias)")
+        .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
   }
 
   @Test
@@ -4629,12 +4630,12 @@ public class TestFullResourcePath {
         .goParameter(1).isTypedLiteral(EntityTypeProvider.nameETKeyPrimNav);
 
     testFilter.runOnETAllPrim(
-        "olingo.odata.test1.UFCRTCTTwoPrimTwoParam(ParameterInt16=null,ParameterString=null) ne null")
+        "olingo.odata.test1.UFCRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString='1') ne null")
         .left()
         .goPath()
         .isFunction("UFCRTCTTwoPrimTwoParam")
-        .isParameter(0, "ParameterInt16", null)
-        .isParameter(1, "ParameterString", null);
+        .isParameter(0, "ParameterInt16", "1")
+        .isParameter(1, "ParameterString", "'1'");
 
     testFilter.runOnETKeyNavEx("cast(NavPropertyETKeyPrimNavOne,olingo.odata.test1.ETKeyNav)")
         .isExSemantic(MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
@@ -5023,21 +5024,24 @@ public class TestFullResourcePath {
         .n().isPrimitiveProperty("PropertyDate", PropertyProvider.nameDate, false);
 
     testFilter.runOrderByOnETTwoKeyNav("olingo.odata.test1.UFCRTETAllPrimTwoParam("
-        + "ParameterString=@ParamStringAlias,ParameterInt16=@ParamInt16Alias)/PropertyString eq 'SomeString'")
+        + "ParameterString=@ParamStringAlias,ParameterInt16=@ParamInt16Alias)/PropertyString eq 'SomeString'"
+        + "&@ParamStringAlias='1'&@ParamInt16Alias=1")
         .isSortOrder(0, false)
         .goOrder(0).isBinary(BinaryOperatorKind.EQ).left().goPath()
         .first().isFunction("UFCRTETAllPrimTwoParam").goUpFilterValidator()
         .goOrder(0).right().isLiteral("'SomeString'");
 
     testFilter.runOrderByOnETTwoKeyNav("olingo.odata.test1.UFCRTETAllPrimTwoParam("
-        + "ParameterString=@ParamStringAlias,ParameterInt16=@ParamInt16Alias)/PropertyString eq 'SomeString' asc")
+        + "ParameterString=@ParamStringAlias,ParameterInt16=@ParamInt16Alias)/PropertyString eq 'SomeString' asc"
+        + "&@ParamStringAlias='1'&@ParamInt16Alias=1")
         .isSortOrder(0, false)
         .goOrder(0).isBinary(BinaryOperatorKind.EQ).left().goPath()
         .first().isFunction("UFCRTETAllPrimTwoParam").goUpFilterValidator()
         .goOrder(0).right().isLiteral("'SomeString'");
 
     testFilter.runOrderByOnETTwoKeyNav("olingo.odata.test1.UFCRTETAllPrimTwoParam("
-        + "ParameterString=@ParamStringAlias,ParameterInt16=@ParamInt16Alias)/PropertyString eq 'SomeString' desc")
+        + "ParameterString=@ParamStringAlias,ParameterInt16=@ParamInt16Alias)/PropertyString eq 'SomeString' desc"
+        + "&@ParamStringAlias='1'&@ParamInt16Alias=1")
         .isSortOrder(0, true)
         .goOrder(0).isBinary(BinaryOperatorKind.EQ).left().goPath()
         .first().isFunction("UFCRTETAllPrimTwoParam").goUpFilterValidator()
@@ -5045,7 +5049,8 @@ public class TestFullResourcePath {
 
     testFilter.runOrderByOnETTwoKeyNav("olingo.odata.test1.UFCRTETAllPrimTwoParam("
         + "ParameterString=@ParamStringAlias,ParameterInt16=@ParamInt16Alias)/PropertyString eq 'SomeString' desc,"
-        + "PropertyString eq '1'")
+        + "PropertyString eq '1'"
+        + "&@ParamStringAlias='1'&@ParamInt16Alias=1")
         .isSortOrder(0, true)
         .goOrder(0).isBinary(BinaryOperatorKind.EQ).left().goPath()
         .first().isFunction("UFCRTETAllPrimTwoParam").goUpFilterValidator()
@@ -5553,14 +5558,6 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void alias() throws Exception {
-    testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString=@A)", "@A='2'").goPath()
-        .isKeyPredicate(0, "PropertyInt16", "1")
-        .isKeyPredicateAlias(1, "PropertyString", "@A")
-        .isInAliasToValueMap("@A", "'2'");
-  }
-
-  @Test
   public void doublePercentDecoding() throws Exception {
     testUri.runEx("ESAllPrim%252832767%29").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
   }
@@ -5775,13 +5772,42 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void parameterAliasLiteralValidation() throws Exception {
-    testUri.run("ESAllPrim(PropertyInt16=@p1)", "@p1=1");
-    testUri.run("ESAllPrim(PropertyInt16=@p1)", "@p1=-2");
-    testUri.runEx("ESAllPrim(PropertyInt16=@p1)", "@p1='ewe'")
-        .isExValidation(UriValidationException.MessageKeys.INVALID_KEY_PROPERTY);
+  public void alias() throws Exception {
+    testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString=@A)", "@A='2'").goPath()
+        .isKeyPredicate(0, "PropertyInt16", "1")
+        .isKeyPredicateAlias(1, "PropertyString", "@A")
+        .isInAliasToValueMap("@A", "'2'");
+    testUri.run("ESAllPrim(PropertyInt16=@p1)", "@p1=1").goPath()
+        .isKeyPredicateAlias(0, "PropertyInt16", "@p1")
+        .isInAliasToValueMap("@p1", "1");
+    testUri.run("ESAllPrim(@p1)", "@p1=-2").goPath()
+        .isKeyPredicateAlias(0, "PropertyInt16", "@p1")
+        .isInAliasToValueMap("@p1", "-2");
+
+    testFilter.runOnETAllPrim("PropertyInt16 gt @alias&@alias=1")
+        .right().isAlias("@alias");
+    testFilter.runOnETAllPrim("@alias&@alias=@otherAlias&@otherAlias=true")
+        .isAlias("@alias");
+
+    testUri.runEx("ESAllPrim(@p1)")
+        .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
+    testUri.runEx("ESAllPrim(PropertyInt16=@p1)", "@p1='ewe'").isExSemantic(MessageKeys.UNKNOWN_PART);
     testUri.runEx("ESAllPrim(PropertyInt16=@p1)", "@p1='ewe")
         .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
+    testFilter.runOnETKeyNavEx("PropertyInt16 gt @alias")
+        .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
+    testFilter.runOnETKeyNavEx("PropertyInt16 gt @alias&@alias=@alias")
+        .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
+    testFilter.runOnETKeyNavEx("@alias&@alias=@alias2&@alias2=true or @alias")
+        .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
+  }
+
+  @Test
+  public void functionImportParameterAlias() throws Exception {
+    testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=@parameterAlias)", "@parameterAlias=1");
+    testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=@parameterAlias)/$count", "@parameterAlias=1");
+    testUri.runEx("FICRTCollESTwoKeyNavParam(ParameterInt16=@invalidAlias)", "@validAlias=1")
+        .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
   }
 
   @Test
@@ -5854,10 +5880,10 @@ public class TestFullResourcePath {
         .isExValidation(UriValidationException.MessageKeys.MISSING_PARAMETER);
 
     testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)")
-        .isExValidation(UriValidationException.MessageKeys.MISSING_PARAMETER);
+        .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
 
     testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)", "@test=null")
-        .isExValidation(UriValidationException.MessageKeys.MISSING_PARAMETER);
+        .isExValidation(UriValidationException.MessageKeys.MISSING_ALIAS);
 
     testUri.run("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)", "@test='null'");
 
@@ -5881,7 +5907,7 @@ public class TestFullResourcePath {
 
     testUri.runEx("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
         + "(ParameterComp=@p1) eq '0'&@p1={\"PropertyInt16\":1,\"PropertyString\":\"1\"}}")
-        .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
+        .isExSemantic(MessageKeys.UNKNOWN_PART);
 
     testUri.runEx("ESTwoKeyNav", "$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
         + "(ParameterComp=@p1) eq '0'&@p1={\"PropertyInt16\":[1,2,3]],\"PropertyString\":\"1\"}")

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/QueryOptionTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/QueryOptionTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/QueryOptionTest.java
index c3d90c9..4643283 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/QueryOptionTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/QueryOptionTest.java
@@ -132,7 +132,7 @@ public class QueryOptionTest {
     FilterOptionImpl option = new FilterOptionImpl();
     assertEquals(SystemQueryOptionKind.FILTER, option.getKind());
 
-    AliasImpl expression = new AliasImpl(null);
+    AliasImpl expression = new AliasImpl(null, null);
 
     option.setExpression(expression);
     assertEquals(expression, option.getExpression());
@@ -184,7 +184,7 @@ public class QueryOptionTest {
   public void testOrderByItemImpl() {
     OrderByItemImpl option = new OrderByItemImpl();
 
-    AliasImpl expression = new AliasImpl(null);
+    AliasImpl expression = new AliasImpl(null, null);
     option.setExpression(expression);
     assertEquals(expression, option.getExpression());
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/expression/ExpressionTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/expression/ExpressionTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/expression/ExpressionTest.java
index fad718b..66528a0 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/expression/ExpressionTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/queryoption/expression/ExpressionTest.java
@@ -70,12 +70,12 @@ public class ExpressionTest {
 
   @Test
   public void aliasExpression() throws Exception {
-    AliasImpl expression = new AliasImpl("Test");
+    AliasImpl expression = new AliasImpl("@Test", null);
 
-    assertEquals("Test", expression.getParameterName());
+    assertEquals("@Test", expression.getParameterName());
 
     String output = expression.accept(new FilterTreeToText());
-    assertEquals("<Test>", output);
+    assertEquals("<@Test>", output);
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java
index 161299c..600a2bd 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java
@@ -36,6 +36,7 @@ import org.apache.olingo.server.api.uri.UriInfoKind;
 import org.apache.olingo.server.api.uri.UriResource;
 import org.apache.olingo.server.api.uri.queryoption.FilterOption;
 import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
+import org.apache.olingo.server.api.uri.queryoption.expression.Alias;
 import org.apache.olingo.server.api.uri.queryoption.expression.Binary;
 import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
 import org.apache.olingo.server.api.uri.queryoption.expression.Enumeration;
@@ -102,11 +103,6 @@ public class FilterValidator implements TestValidator {
     return this;
   }
 
-  public FilterValidator setOrderBy(final OrderByOption orderBy) {
-    this.orderBy = orderBy;
-    return this;
-  }
-
   public FilterValidator setExpression(final Expression expression) {
     rootExpression = curExpression = expression;
     return this;
@@ -189,10 +185,7 @@ public class FilterValidator implements TestValidator {
 
   public FilterValidator runUri(final String path, final String query)
       throws UriParserException, UriValidationException {
-    Parser parser = new Parser(edm, odata);
-    UriInfo uriInfo = null;
-
-    uriInfo = parser.parseUri(path, query, null);
+    final UriInfo uriInfo = new Parser(edm, odata).parseUri(path, query, null);
 
     if (uriInfo.getKind() != UriInfoKind.resource) {
       fail("Filtervalidator can only be used on resourcePaths");
@@ -224,7 +217,7 @@ public class FilterValidator implements TestValidator {
       fail("Filtervalidator can only be used on resourcePaths");
     }
 
-    setOrderBy(uriInfo.getOrderByOption());
+    orderBy = uriInfo.getOrderByOption();
     return this;
   }
 
@@ -323,6 +316,11 @@ public class FilterValidator implements TestValidator {
     return this;
   }
 
+  public FilterValidator root() {
+    curExpression = filter == null ? rootExpression : filter.getExpression();
+    return this;
+  }
+
   public FilterValidator left() {
     if (!(curExpression instanceof Binary)) {
       fail("Current expression not a binary operator");
@@ -332,11 +330,6 @@ public class FilterValidator implements TestValidator {
     return this;
   }
 
-  public FilterValidator root() {
-    curExpression = filter == null ? rootExpression : filter.getExpression();
-    return this;
-  }
-
   public FilterValidator right() {
     if (!(curExpression instanceof Binary)) {
       fail("Current expression is not a binary operator");
@@ -360,7 +353,7 @@ public class FilterValidator implements TestValidator {
     if (!(curExpression instanceof Literal)) {
       fail("Current expression is not a literal");
     }
-    
+
     final EdmType type = ((Literal) curExpression).getType();
     assertNotNull(type);
     assertEquals(edmType, type);
@@ -448,7 +441,7 @@ public class FilterValidator implements TestValidator {
     return this;
   }
 
-  public FilterValidator isEnum(final FullQualifiedName nameenstring, final List<String> enumValues) {
+  public FilterValidator isEnum(final FullQualifiedName name, final List<String> enumValues) {
     if (!(curExpression instanceof Enumeration)) {
       fail("Current expression not a enumeration");
     }
@@ -456,18 +449,24 @@ public class FilterValidator implements TestValidator {
     Enumeration enumeration = (Enumeration) curExpression;
 
     // check name
-    assertEquals(nameenstring, enumeration.getType().getFullQualifiedName());
+    assertEquals(name, enumeration.getType().getFullQualifiedName());
 
     // check values
-    int i = 0;
-    for (String item : enumValues) {
-      assertEquals(item, enumeration.getValues().get(i));
-      i++;
-    }
+    assertEquals(enumValues, enumeration.getValues());
 
     return this;
   }
 
+  public FilterValidator isAlias(final String name) {
+    if (curExpression instanceof Alias) {
+      final Alias alias = (Alias) curExpression;
+      assertEquals(name, alias.getParameterName());
+    } else {
+      fail("Current expression is not an alias.");
+    }
+    return this;
+  }
+
   public FilterValidator isSortOrder(final int index, final boolean descending) {
     assertEquals(descending, orderBy.getOrders().get(index).isDescending());
     return this;
@@ -489,4 +488,10 @@ public class FilterValidator implements TestValidator {
     assertEquals(messageKey, exception.getMessageKey());
     return this;
   }
+
+  public FilterValidator isExValidation(final UriValidationException.MessageKeys messageKey) {
+    assertEquals(UriValidationException.class, exception.getClass());
+    assertEquals(messageKey, exception.getMessageKey());
+    return this;
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
index 673b8ff..3d5e97f 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
@@ -30,7 +30,6 @@ import org.apache.olingo.server.api.edmx.EdmxReference;
 import org.apache.olingo.server.core.uri.parser.Parser;
 import org.apache.olingo.server.core.uri.parser.UriParserException;
 import org.apache.olingo.server.core.uri.parser.UriParserSemanticException;
-import org.apache.olingo.server.core.uri.parser.UriParserSyntaxException;
 import org.apache.olingo.server.core.uri.testutil.TestUriValidator;
 import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
 import org.junit.Test;
@@ -118,7 +117,7 @@ public class UriValidatorTest {
 
       { URI_REFERENCES, QO_FILTER }, { URI_REFERENCES, QO_FORMAT }, { URI_REFERENCES, QO_ORDERBY },
       { URI_REFERENCES, QO_SEARCH }, { URI_REFERENCES, QO_SKIP }, { URI_REFERENCES, QO_SKIPTOKEN },
-      { URI_REFERENCES, QO_TOP }, { URI_REFERENCES, QO_ID }, { URI_REFERENCES, QO_COUNT },
+      { URI_REFERENCES, QO_TOP }, { URI_REFERENCES, QO_COUNT },
 
       { URI_REFERENCE, QO_FORMAT },
 
@@ -204,7 +203,7 @@ public class UriValidatorTest {
       { URI_MEDIA_STREAM, QO_SEARCH }, { URI_MEDIA_STREAM, QO_SELECT }, { URI_MEDIA_STREAM, QO_SKIP },
       { URI_MEDIA_STREAM, QO_SKIPTOKEN }, { URI_MEDIA_STREAM, QO_TOP },
 
-      { URI_REFERENCES, QO_EXPAND }, { URI_REFERENCES, QO_SELECT },
+      { URI_REFERENCES, QO_ID }, { URI_REFERENCES, QO_EXPAND }, { URI_REFERENCES, QO_SELECT },
 
       { URI_REFERENCE, QO_FILTER }, { URI_REFERENCE, QO_ID }, { URI_REFERENCE, QO_EXPAND },
       { URI_REFERENCE, QO_COUNT }, { URI_REFERENCE, QO_ORDERBY }, { URI_REFERENCE, QO_SEARCH },
@@ -328,22 +327,18 @@ public class UriValidatorTest {
       new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
 
   @Test
-  public void serviceDocumentMustNotFailForHttpPostPutPatchDelete() throws Exception {
-    // We must not fail with a nullpointer here as the HTTP method to resource validation happens in the dispatcher
-    validate(URI_SERVICE, null, HttpMethod.GET);
-    validate(URI_SERVICE, null, HttpMethod.POST);
-    validate(URI_SERVICE, null, HttpMethod.PUT);
-    validate(URI_SERVICE, null, HttpMethod.DELETE);
-    validate(URI_SERVICE, null, HttpMethod.PATCH);
+  public void serviceDocumentMustNotFailForAllHttpMethods() throws Exception {
+    // We must not fail with a nullpointer here as the HTTP method to resource validation happens in the dispatcher.
+    for (final HttpMethod method : HttpMethod.values()) {
+      validate(URI_SERVICE, null, method);
+    }
   }
 
   @Test
   public void validateForHttpMethods() throws Exception {
-    validate(URI_ENTITY, null, HttpMethod.GET);
-    validate(URI_ENTITY, null, HttpMethod.POST);
-    validate(URI_ENTITY, null, HttpMethod.PUT);
-    validate(URI_ENTITY, null, HttpMethod.DELETE);
-    validate(URI_ENTITY, null, HttpMethod.PATCH);
+    for (final HttpMethod method : HttpMethod.values()) {
+      validate(URI_ENTITY, null, method);
+    }
   }
 
   @Test
@@ -378,45 +373,6 @@ public class UriValidatorTest {
   }
 
   @Test
-  public void validateSelect() throws Exception {
-    new TestUriValidator().setEdm(edm).run(URI_ENTITY, "$select=PropertyString");
-  }
-
-  @Test
-  public void validateOrderBy() throws Exception {
-    final TestUriValidator testUri = new TestUriValidator().setEdm(edm);
-
-    testUri.run(URI_ENTITY_SET, "$orderby=PropertyString");
-
-    testUri.runEx(URI_ENTITY, "$orderby=XXXX")
-        .isExSemantic(UriParserSemanticException.MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
-  }
-
-  @Test
-  public void validateCountInvalid() throws Exception {
-    new TestUriValidator().setEdm(edm).runEx(URI_ENTITY_SET, "$count=foo")
-        .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
-  }
-
-  @Test
-  public void validateTopInvalid() throws Exception {
-    new TestUriValidator().setEdm(edm).runEx(URI_ENTITY_SET, "$top=foo")
-        .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
-  }
-
-  @Test
-  public void validateSkipInvalid() throws Exception {
-    new TestUriValidator().setEdm(edm).runEx(URI_ENTITY_SET, "$skip=foo")
-        .isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
-  }
-
-  @Test
-  public void validateDoubleSystemOptions() throws Exception {
-    new TestUriValidator().setEdm(edm).runEx(URI_ENTITY_SET, "$skip=1&$skip=2")
-        .isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
-  }
-
-  @Test
   public void checkKeys() throws Exception {
     final TestUriValidator testUri = new TestUriValidator().setEdm(edm);
 
@@ -502,9 +458,9 @@ public class UriValidatorTest {
     try {
       new UriValidator().validate(new Parser(edm, odata).parseUri(path, query, null), method);
     } catch (final UriParserException e) {
-      fail("Failed for uri: " + path + '?' + query);
+      fail("Failed for " + method + " on URI: " + path + '?' + query);
     } catch (final UriValidationException e) {
-      fail("Failed for uri: " + path + '?' + query);
+      fail("Failed for " + method + " on URI: " + path + '?' + query);
     }
   }
 


[7/7] olingo-odata4 git commit: [OLINGO-852] less warnings + general clean-up

Posted by ch...@apache.org.
[OLINGO-852] less warnings + general clean-up

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


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

Branch: refs/heads/master
Commit: 5d7c1287f042fbb6c50e815c2dc1af9903b74951
Parents: 110c7b0
Author: Klaus Straubinger <kl...@sap.com>
Authored: Thu Feb 4 12:28:35 2016 +0100
Committer: Christian Amend <ch...@sap.com>
Committed: Thu Feb 4 12:42:29 2016 +0100

----------------------------------------------------------------------
 .../commons/AbstractInvocationHandler.java      |   17 +-
 .../AbstractStructuredInvocationHandler.java    |    2 +-
 .../commons/AnnotatationsInvocationHandler.java |    2 +-
 .../ComplexCollectionInvocationHandler.java     |    2 +-
 .../proxy/commons/ComplexInvocationHandler.java |    6 +-
 .../proxy/commons/EdmStreamValueHandler.java    |    2 +-
 .../EntityCollectionInvocationHandler.java      |    2 +-
 .../EntityContainerInvocationHandler.java       |    4 +-
 .../proxy/commons/EntityInvocationHandler.java  |    6 +-
 .../commons/EntitySetInvocationHandler.java     |    2 +-
 .../proxy/commons/InvokerInvocationHandler.java |    2 +-
 .../commons/OperationInvocationHandler.java     |    2 +-
 .../PrimitiveCollectionInvocationHandler.java   |    2 +-
 ...turedComposableInvokerInvocationHandler.java |    2 +-
 .../olingo/ext/proxy/utils/CoreUtils.java       |    5 +-
 .../org/apache/olingo/fit/AbstractServices.java | 1947 --------------
 .../main/java/org/apache/olingo/fit/Demo.java   |    6 +-
 .../java/org/apache/olingo/fit/OpenType.java    |    5 +-
 .../java/org/apache/olingo/fit/Services.java    | 2511 +++++++++++++++---
 .../org/apache/olingo/fit/Vocabularies.java     |   10 +-
 .../apache/olingo/fit/metadata/EntitySet.java   |    8 -
 .../olingo/fit/rest/OAuth2RequestFilter.java    |    3 +-
 .../fit/serializer/FITAtomDeserializer.java     |   13 +-
 .../olingo/fit/utils/AbstractUtilities.java     |   22 +-
 .../org/apache/olingo/fit/utils/Accept.java     |   31 +-
 .../org/apache/olingo/fit/utils/Commons.java    |   24 +-
 .../apache/olingo/fit/utils/ConstantKey.java    |   10 +-
 .../org/apache/olingo/fit/utils/Constants.java  |    7 -
 .../org/apache/olingo/fit/utils/FSManager.java  |   25 +-
 .../fit/utils/InjectableSerializerProvider.java |   42 -
 .../apache/olingo/fit/utils/JSONUtilities.java  |   14 +-
 .../olingo/fit/utils/MetadataLinkInfo.java      |  182 --
 .../apache/olingo/fit/utils/XMLUtilities.java   |    3 +
 .../proxy/demo/odatademo/types/Customer.java    |    6 +-
 .../proxy/demo/odatademo/types/Employee.java    |    6 +-
 .../demo/odatademo/types/FeaturedProduct.java   |    6 +-
 .../opentypesservice/types/IndexedRow.java      |    8 +-
 .../odatawcfservice/types/CreditCardPI.java     |    6 +-
 .../odatawcfservice/types/Customer.java         |    6 +-
 .../odatawcfservice/types/Employee.java         |    6 +-
 .../odatawcfservice/types/PublicCompany.java    |    8 +-
 .../tecsvc/client/EntityReferencesITCase.java   |   13 +-
 .../ExpandWithSystemQueryOptionsITCase.java     |   74 +-
 .../core/domain/AbstractClientEntitySet.java    |  114 -
 .../core/domain/ClientCollectionValueImpl.java  |    2 +-
 .../client/core/domain/ClientEntitySetImpl.java |   74 +-
 .../core/domain/ClientPrimitiveValueImpl.java   |    5 +-
 .../client/core/domain/ClientPropertyImpl.java  |  135 +-
 .../client/core/domain/ClientValuableImpl.java  |   22 +-
 .../core/serialization/ODataBinderImpl.java     |    2 +-
 .../apache/olingo/client/core/AbstractTest.java |    9 +-
 .../org/apache/olingo/client/core/AtomTest.java |    6 -
 .../olingo/client/core/EntitySetTest.java       |   22 +-
 .../apache/olingo/client/core/EntityTest.java   |   73 +-
 .../apache/olingo/client/core/ErrorTest.java    |    8 +-
 .../org/apache/olingo/client/core/JSONTest.java |   46 +-
 .../apache/olingo/client/core/MetadataTest.java |   33 +-
 .../olingo/client/core/PrimitiveValueTest.java  |   22 +-
 .../apache/olingo/client/core/PropertyTest.java |   38 +-
 .../olingo/client/core/ServiceDocumentTest.java |   16 +-
 .../client/core/uri/FilterFactoryTest.java      |    8 +-
 .../olingo/client/core/uri/URIBuilderTest.java  |   71 +-
 .../olingo/commons/api/edm/geo/Geospatial.java  |    7 +-
 .../core/edm/EdmNavigationPropertyImpl.java     |    3 +-
 .../commons/core/edm/EdmParameterImpl.java      |    3 +-
 .../commons/core/edm/EdmPropertyImpl.java       |    5 +-
 .../core/batchhandler/BatchFacadeImpl.java      |   18 +-
 .../server/core/batchhandler/BatchHandler.java  |    2 +-
 68 files changed, 2488 insertions(+), 3316 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
index 258a496..ff4663e 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractInvocationHandler.java
@@ -69,7 +69,7 @@ abstract class AbstractInvocationHandler implements InvocationHandler {
     return service.getContext();
   }
 
-  protected boolean isSelfMethod(final Method method, final Object[] args) {
+  protected boolean isSelfMethod(final Method method) {
     final Method[] selfMethods = getClass().getMethods();
 
     boolean result = false;
@@ -161,7 +161,7 @@ abstract class AbstractInvocationHandler implements InvocationHandler {
       CoreUtils.addProperties(getClient(), handler.getPropertyChanges(), template);
       final Object key = CoreUtils.getKey(getClient(), handler, handler.getUUID().getType(), template);
 
-      entityURI = CoreUtils.buildEditLink(getClient(), baseURI.toASCIIString(), template, key).build();
+      entityURI = CoreUtils.buildEditLink(getClient(), baseURI.toASCIIString(), key).build();
       template.setEditLink(entityURI);
     } else {
       entityURI = handler.getEntityURI();
@@ -182,32 +182,25 @@ abstract class AbstractInvocationHandler implements InvocationHandler {
     }
   }
 
-  protected static URIBuilder buildEntitySetURI(
-      final Class<?> ref,
-      final AbstractService<?> service) {
+  protected static URIBuilder buildEntitySetURI(final Class<?> ref, final AbstractService<?> service) {
 
-    final String containerNS;
     final String entitySetName;
     Annotation ann = ref.getAnnotation(EntitySet.class);
     if (ann instanceof EntitySet) {
-      containerNS = EntitySet.class.cast(ann).container();
       entitySetName = EntitySet.class.cast(ann).name();
     } else {
       ann = ref.getAnnotation(Singleton.class);
       if (ann instanceof Singleton) {
-        containerNS = Singleton.class.cast(ann).container();
         entitySetName = Singleton.class.cast(ann).name();
       } else {
-        containerNS = null;
         entitySetName = null;
       }
     }
 
-    return buildEntitySetURI(containerNS, entitySetName, service);
+    return buildEntitySetURI(entitySetName, service);
   }
 
-  protected static URIBuilder buildEntitySetURI(
-      final String containerNS, final String entitySetName, final AbstractService<?> service) {
+  protected static URIBuilder buildEntitySetURI(final String entitySetName, final AbstractService<?> service) {
 
     final URIBuilder uriBuilder = service.getClient().newURIBuilder();
     final StringBuilder entitySetSegment = new StringBuilder();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
index 96b3f26..a448186 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
@@ -210,7 +210,7 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca
             || "refs".equals(method.getName())) {
       invokeSelfMethod(method, args);
       return proxy;
-    } else if (isSelfMethod(method, args)) {
+    } else if (isSelfMethod(method)) {
       return invokeSelfMethod(method, args);
     } else if ("load".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
       load();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AnnotatationsInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AnnotatationsInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AnnotatationsInvocationHandler.java
index fcd5078..8f0951d 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AnnotatationsInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AnnotatationsInvocationHandler.java
@@ -55,7 +55,7 @@ public class AnnotatationsInvocationHandler extends AbstractInvocationHandler {
 
   @Override
   public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
-    if (isSelfMethod(method, args)) {
+    if (isSelfMethod(method)) {
       return invokeSelfMethod(method, args);
     } else if (method.getName().startsWith("get") && method.getName().endsWith("Annotations")) {
       final Method getter = proxy.getClass().getInterfaces()[0].getMethod(method.getName());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexCollectionInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexCollectionInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexCollectionInvocationHandler.java
index ff4fc66..8699ed4 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexCollectionInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexCollectionInvocationHandler.java
@@ -80,7 +80,7 @@ public class ComplexCollectionInvocationHandler<T extends ComplexType<?>>
 
       invokeSelfMethod(method, args);
       return proxy;
-    } else if (isSelfMethod(method, args)) {
+    } else if (isSelfMethod(method)) {
       return invokeSelfMethod(method, args);
     } else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
       final Class<?> returnType = method.getReturnType();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexInvocationHandler.java
index 3aa3326..1e2197c 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/ComplexInvocationHandler.java
@@ -63,11 +63,7 @@ public class ComplexInvocationHandler extends AbstractStructuredInvocationHandle
     return new ImmutablePair<ClientComplexValue, Class<?>>(complex, complexTypeRef);
   }
 
-  public static ComplexInvocationHandler getInstance(
-          final String propertyName,
-          final EntityInvocationHandler handler,
-          final Class<?> typeRef) {
-
+  public static ComplexInvocationHandler getInstance(final EntityInvocationHandler handler, final Class<?> typeRef) {
     final Pair<ClientComplexValue, Class<?>> init = init(typeRef, handler.service);
     return new ComplexInvocationHandler(init.getLeft(), init.getRight(), handler);
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EdmStreamValueHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EdmStreamValueHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EdmStreamValueHandler.java
index d197f58..c13a3cf 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EdmStreamValueHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EdmStreamValueHandler.java
@@ -59,7 +59,7 @@ public class EdmStreamValueHandler extends AbstractInvocationHandler {
       load();
       return proxy;
     } else {
-      if (isSelfMethod(method, args)) {
+      if (isSelfMethod(method)) {
         return invokeSelfMethod(method, args);
       } else {
         throw new NoSuchMethodException(method.getName());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityCollectionInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityCollectionInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityCollectionInvocationHandler.java
index 5c8da2c..e7d819a 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityCollectionInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityCollectionInvocationHandler.java
@@ -62,7 +62,7 @@ public class EntityCollectionInvocationHandler<T extends EntityType<?>>
             || "execute".equals(method.getName())) {
       invokeSelfMethod(method, args);
       return proxy;
-    } else if (isSelfMethod(method, args)) {
+    } else if (isSelfMethod(method)) {
       return invokeSelfMethod(method, args);
     } else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
       final Class<?> returnType = method.getReturnType();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityContainerInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityContainerInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityContainerInvocationHandler.java
index cb72126..af8101b 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityContainerInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityContainerInvocationHandler.java
@@ -80,7 +80,7 @@ public final class EntityContainerInvocationHandler extends AbstractInvocationHa
 
   @Override
   public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
-    if (isSelfMethod(method, args)) {
+    if (isSelfMethod(method)) {
       return invokeSelfMethod(method, args);
     } else if ("flush".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
       service.getPersistenceManager().flush();
@@ -114,7 +114,7 @@ public final class EntityContainerInvocationHandler extends AbstractInvocationHa
     final Class<?> typeRef = method.getReturnType();
     final Singleton singleton = method.getAnnotation(Singleton.class);
 
-    final URI uri = buildEntitySetURI(singleton.container(), singleton.name(), service).build();
+    final URI uri = buildEntitySetURI(singleton.name(), service).build();
     final EntityUUID uuid = new EntityUUID(uri, typeRef);
     LOG.debug("Ask for singleton '{}'", typeRef.getSimpleName());
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityInvocationHandler.java
index c124402..e993140 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntityInvocationHandler.java
@@ -191,7 +191,7 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler
       this.uri = getClient().newURIBuilder(baseURI.toASCIIString());
     } else if (key != null) {
       final URIBuilder uriBuilder =
-          CoreUtils.buildEditLink(getClient(), entitySetURI.toASCIIString(), entity, key);
+          CoreUtils.buildEditLink(getClient(), entitySetURI.toASCIIString(), key);
 
       this.uri = uriBuilder;
       this.baseURI = this.uri.build();
@@ -219,7 +219,7 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler
     if (this.uri == null) {
       final URIBuilder uriBuilder =
           entity.getEditLink() == null
-              ? CoreUtils.buildEditLink(getClient(), getUUID().getEntitySetURI().toASCIIString(), entity, key)
+              ? CoreUtils.buildEditLink(getClient(), getUUID().getEntitySetURI().toASCIIString(), key)
               : getClient().newURIBuilder(entity.getEditLink().toASCIIString());
 
       this.uri = uriBuilder;
@@ -252,7 +252,7 @@ public class EntityInvocationHandler extends AbstractStructuredInvocationHandler
     if (this.uri == null) {
       final URIBuilder uriBuilder =
           getEntity().getEditLink() == null
-              ? CoreUtils.buildEditLink(getClient(), entitySetURI.toASCIIString(), getEntity(), key)
+              ? CoreUtils.buildEditLink(getClient(), entitySetURI.toASCIIString(), key)
               : getClient().newURIBuilder(getEntity().getEditLink().toASCIIString());
 
       this.uri = uriBuilder;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
index 8250f72..9d1970a 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/EntitySetInvocationHandler.java
@@ -84,7 +84,7 @@ public class EntitySetInvocationHandler<
 
       invokeSelfMethod(method, args);
       return proxy;
-    } else if (isSelfMethod(method, args)) {
+    } else if (isSelfMethod(method)) {
       return invokeSelfMethod(method, args);
     } else {
       throw new NoSuchMethodException(method.getName());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/InvokerInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/InvokerInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/InvokerInvocationHandler.java
index 53208f7..3ed6121 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/InvokerInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/InvokerInvocationHandler.java
@@ -276,7 +276,7 @@ public class InvokerInvocationHandler<T, O extends Operations> extends AbstractI
       return Proxy.newProxyInstance(
               Thread.currentThread().getContextClassLoader(),
               new Class<?>[] {operationRef}, handler);
-    } else if (isSelfMethod(method, args)) {
+    } else if (isSelfMethod(method)) {
       return invokeSelfMethod(method, args);
     } else {
       throw new NoSuchMethodException(method.getName());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
index bdab06c..23cd25c 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
@@ -133,7 +133,7 @@ final class OperationInvocationHandler extends AbstractInvocationHandler {
   @Override
   @SuppressWarnings({"unchecked", "rawtypes"})
   public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
-    if (isSelfMethod(method, args)) {
+    if (isSelfMethod(method)) {
       return invokeSelfMethod(method, args);
     } else {
       final Operation operation = method.getAnnotation(Operation.class);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/PrimitiveCollectionInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/PrimitiveCollectionInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/PrimitiveCollectionInvocationHandler.java
index 553af6e..67d6e86 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/PrimitiveCollectionInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/PrimitiveCollectionInvocationHandler.java
@@ -75,7 +75,7 @@ public class PrimitiveCollectionInvocationHandler<T extends Serializable>
 
       invokeSelfMethod(method, args);
       return proxy;
-    } else if (isSelfMethod(method, args)) {
+    } else if (isSelfMethod(method)) {
       return invokeSelfMethod(method, args);
     } else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
       final Class<?> returnType = method.getReturnType();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/StructuredComposableInvokerInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/StructuredComposableInvokerInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/StructuredComposableInvokerInvocationHandler.java
index 41ec9ce..00670b3 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/StructuredComposableInvokerInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/StructuredComposableInvokerInvocationHandler.java
@@ -75,7 +75,7 @@ public class StructuredComposableInvokerInvocationHandler<T, O extends Operation
       return super.invoke(proxy, method, args);
     } else if ("operations".equals(method.getName()) && ArrayUtils.isEmpty(args)) {
       return super.invoke(proxy, method, args);
-    } else if (isSelfMethod(method, args)) {
+    } else if (isSelfMethod(method)) {
       return invokeSelfMethod(method, args);
     } else {
       throw new NoSuchMethodException(method.getName());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
index 2776f3b..8f804fe 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/utils/CoreUtils.java
@@ -378,7 +378,6 @@ public final class CoreUtils {
   public static URIBuilder buildEditLink(
       final EdmEnabledODataClient client,
       final String entitySetURI,
-      final ClientEntity entity,
       final Object key) {
 
     if (key == null) {
@@ -506,7 +505,7 @@ public final class CoreUtils {
               final Object complex = Proxy.newProxyInstance(
                   Thread.currentThread().getContextClassLoader(),
                   new Class<?>[] { getter.getReturnType() },
-                  ComplexInvocationHandler.getInstance(property.getName(), typeHandler, getter.getReturnType()));
+                  ComplexInvocationHandler.getInstance(typeHandler, getter.getReturnType()));
 
               populate(client, typeHandler, complex, Property.class, property.getValue().asComplex().iterator());
               setPropertyValue(bean, getter, complex);
@@ -530,7 +529,7 @@ public final class CoreUtils {
                   final Object collItem = Proxy.newProxyInstance(
                       Thread.currentThread().getContextClassLoader(),
                       new Class<?>[] { collItemClass },
-                      ComplexInvocationHandler.getInstance(property.getName(), typeHandler, collItemClass));
+                      ComplexInvocationHandler.getInstance(typeHandler, collItemClass));
 
                   populate(client, typeHandler, collItem, Property.class, value.asComplex().iterator());
                   collection.add(collItem);


[3/7] olingo-odata4 git commit: [OLINGO-852] less warnings + general clean-up

Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java
index 9f5d405..0d075a9 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java
@@ -50,11 +50,6 @@ import org.junit.Test;
 
 public class EntityTest extends AbstractTest {
 
-  @Override
-  protected ODataClient getClient() {
-    return v4Client;
-  }
-
   private EdmEnabledODataClient getEdmEnabledClient() {
     return new EdmEnabledODataClientImpl(null, null, null) {
 
@@ -78,8 +73,8 @@ public class EntityTest extends AbstractTest {
 
   private void singleton(final ContentType contentType) throws Exception {
     final InputStream input = getClass().getResourceAsStream("VipCustomer." + getSuffix(contentType));
-    final ClientEntity entity = getClient().getBinder().getODataEntity(
-        getClient().getDeserializer(contentType).toEntity(input));
+    final ClientEntity entity = client.getBinder().getODataEntity(
+        client.getDeserializer(contentType).toEntity(input));
     assertNotNull(entity);
 
     assertEquals("Microsoft.Test.OData.Services.ODataWCFService.Customer", entity.getTypeName().toString());
@@ -120,8 +115,8 @@ public class EntityTest extends AbstractTest {
 
     // operations won't get serialized
     entity.getOperations().clear();
-    final ClientEntity written = getClient().getBinder().getODataEntity(
-        new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+    final ClientEntity written = client.getBinder().getODataEntity(
+        new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
     assertEquals(entity, written);
     input.close();
   }
@@ -138,8 +133,8 @@ public class EntityTest extends AbstractTest {
 
   private void withEnums(final ContentType contentType) throws Exception {
     final InputStream input = getClass().getResourceAsStream("Products_5." + getSuffix(contentType));
-    final ClientEntity entity = getClient().getBinder().getODataEntity(
-        getClient().getDeserializer(contentType).toEntity(input));
+    final ClientEntity entity = client.getBinder().getODataEntity(
+        client.getDeserializer(contentType).toEntity(input));
     assertNotNull(entity);
 
     final ClientProperty skinColor = entity.getProperty("SkinColor");
@@ -156,8 +151,8 @@ public class EntityTest extends AbstractTest {
 
     // operations won't get serialized
     entity.getOperations().clear();
-    final ClientEntity written = getClient().getBinder().getODataEntity(
-        new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+    final ClientEntity written = client.getBinder().getODataEntity(
+        new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
     assertEquals(entity, written);
     input.close();
   }
@@ -175,8 +170,8 @@ public class EntityTest extends AbstractTest {
   private void withInlineEntitySet(final ContentType contentType) throws Exception {
     final InputStream input = getClass().getResourceAsStream(
         "Accounts_101_expand_MyPaymentInstruments." + getSuffix(contentType));
-    final ClientEntity entity = getClient().getBinder().getODataEntity(
-        getClient().getDeserializer(contentType).toEntity(input));
+    final ClientEntity entity = client.getBinder().getODataEntity(
+        client.getDeserializer(contentType).toEntity(input));
     assertNotNull(entity);
 
     final ClientLink instruments = entity.getNavigationLink("MyPaymentInstruments");
@@ -191,8 +186,8 @@ public class EntityTest extends AbstractTest {
     inline.getEntitySet().setCount(3);
     // operations won't get serialized
     entity.getOperations().clear();
-    final ClientEntity written = getClient().getBinder().getODataEntity(
-        new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+    final ClientEntity written = client.getBinder().getODataEntity(
+        new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
     assertEquals(entity, written);
     input.close();
   }
@@ -210,16 +205,16 @@ public class EntityTest extends AbstractTest {
   private void mediaEntity(final ContentType contentType) throws Exception {
     final InputStream input = getClass().getResourceAsStream(
         "Advertisements_f89dee73-af9f-4cd4-b330-db93c25ff3c7." + getSuffix(contentType));
-    final ClientEntity entity = getClient().getBinder().getODataEntity(
-        getClient().getDeserializer(contentType).toEntity(input));
+    final ClientEntity entity = client.getBinder().getODataEntity(
+        client.getDeserializer(contentType).toEntity(input));
     assertNotNull(entity);
 
     assertTrue(entity.isMediaEntity());
     assertNotNull(entity.getMediaContentSource());
     assertEquals("\"8zOOKKvgOtptr4gt8IrnapX3jds=\"", entity.getMediaETag());
 
-    final ClientEntity written = getClient().getBinder().getODataEntity(
-        new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+    final ClientEntity written = client.getBinder().getODataEntity(
+        new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
     assertEquals(entity, written);
     input.close();
   }
@@ -236,8 +231,8 @@ public class EntityTest extends AbstractTest {
 
   private void withStream(final ContentType contentType) throws Exception {
     final InputStream input = getClass().getResourceAsStream("PersonDetails_1." + getSuffix(contentType));
-    final ClientEntity entity = getClient().getBinder().getODataEntity(
-        getClient().getDeserializer(contentType).toEntity(input));
+    final ClientEntity entity = client.getBinder().getODataEntity(
+        client.getDeserializer(contentType).toEntity(input));
     assertNotNull(entity);
 
     assertFalse(entity.isMediaEntity());
@@ -245,8 +240,8 @@ public class EntityTest extends AbstractTest {
     final ClientLink editMedia = entity.getMediaEditLink("Photo");
     assertNotNull(editMedia);
 
-    final ClientEntity written = getClient().getBinder().getODataEntity(
-        new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+    final ClientEntity written = client.getBinder().getODataEntity(
+        new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
     assertEquals(entity, written);
     input.close();
   }
@@ -263,14 +258,14 @@ public class EntityTest extends AbstractTest {
 
   private void ref(final ContentType contentType) throws Exception {
     final InputStream input = getClass().getResourceAsStream("entityReference." + getSuffix(contentType));
-    final ClientEntity entity = getClient().getBinder().getODataEntity(
-        getClient().getDeserializer(contentType).toEntity(input));
+    final ClientEntity entity = client.getBinder().getODataEntity(
+        client.getDeserializer(contentType).toEntity(input));
     assertNotNull(entity);
 
     assertNotNull(entity.getId());
 
-    final ClientEntity written = getClient().getBinder().getODataEntity(
-        new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+    final ClientEntity written = client.getBinder().getODataEntity(
+        new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
     assertEquals(entity, written);
     input.close();
   }
@@ -287,8 +282,8 @@ public class EntityTest extends AbstractTest {
 
   private void complexNavigationProperties(final ContentType contentType) throws Exception {
     final InputStream input = getClass().getResourceAsStream("entity.withcomplexnavigation." + getSuffix(contentType));
-    final ClientEntity entity = getClient().getBinder().getODataEntity(
-        getClient().getDeserializer(contentType).toEntity(input));
+    final ClientEntity entity = client.getBinder().getODataEntity(
+        client.getDeserializer(contentType).toEntity(input));
     assertNotNull(entity);
 
     final ClientComplexValue addressValue = entity.getProperty("Address").getComplexValue();
@@ -297,8 +292,8 @@ public class EntityTest extends AbstractTest {
 
     // ETag is not serialized
     entity.setETag(null);
-    final ClientEntity written = getClient().getBinder().getODataEntity(
-        new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+    final ClientEntity written = client.getBinder().getODataEntity(
+        new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
     assertEquals(entity, written);
     input.close();
   }
@@ -315,8 +310,8 @@ public class EntityTest extends AbstractTest {
 
   private void annotated(final ContentType contentType) throws EdmPrimitiveTypeException, Exception {
     final InputStream input = getClass().getResourceAsStream("annotated." + getSuffix(contentType));
-    final ClientEntity entity = getClient().getBinder().getODataEntity(
-        getClient().getDeserializer(contentType).toEntity(input));
+    final ClientEntity entity = client.getBinder().getODataEntity(
+        client.getDeserializer(contentType).toEntity(input));
     assertNotNull(entity);
 
     assertFalse(entity.getAnnotations().isEmpty());
@@ -343,8 +338,8 @@ public class EntityTest extends AbstractTest {
     assertEquals(2,
         annotation.getValue().asComplex().get("order").getPrimitiveValue().toCastValue(Integer.class), 0);
 
-    final ClientEntity written = getClient().getBinder().getODataEntity(
-        new ResWrap<Entity>((URI) null, null, getClient().getBinder().getEntity(entity)));
+    final ClientEntity written = client.getBinder().getODataEntity(
+        new ResWrap<Entity>((URI) null, null, client.getBinder().getEntity(entity)));
     assertEquals(entity, written);
     input.close();
   }
@@ -374,7 +369,7 @@ public class EntityTest extends AbstractTest {
 
   @Test
   public void derivedFromAtom() throws Exception {
-    derived(getClient(), ContentType.APPLICATION_ATOM_XML);
+    derived(client, ContentType.APPLICATION_ATOM_XML);
   }
 
   @Test
@@ -384,6 +379,6 @@ public class EntityTest extends AbstractTest {
 
   @Test
   public void derivedFromFullJSON() throws Exception {
-    derived(getClient(), ContentType.JSON_FULL_METADATA);
+    derived(client, ContentType.JSON_FULL_METADATA);
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/ErrorTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/ErrorTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/ErrorTest.java
index 8ced6a3..60bbcd0 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/ErrorTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/ErrorTest.java
@@ -21,7 +21,6 @@ package org.apache.olingo.client.core;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
-import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.serialization.ODataDeserializerException;
 import org.apache.olingo.commons.api.ex.ODataError;
 import org.apache.olingo.commons.api.format.ContentType;
@@ -29,13 +28,8 @@ import org.junit.Test;
 
 public class ErrorTest extends AbstractTest {
 
-  @Override
-  protected ODataClient getClient() {
-    return v4Client;
-  }
-
   private ODataError error(final String name, final ContentType contentType) throws ODataDeserializerException {
-    final ODataError error = getClient().getDeserializer(contentType).toError(
+    final ODataError error = client.getDeserializer(contentType).toError(
             getClass().getResourceAsStream(name + "." + getSuffix(contentType)));
     assertNotNull(error);
     return error;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java
index 9273229..a276c4f 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java
@@ -30,7 +30,6 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.domain.ClientCollectionValue;
 import org.apache.olingo.client.api.domain.ClientComplexValue;
 import org.apache.olingo.client.api.domain.ClientEntity;
@@ -50,11 +49,6 @@ public class JSONTest extends AbstractTest {
 
   private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
 
-  @Override
-  protected ODataClient getClient() {
-    return v4Client;
-  }
-
   protected ContentType getODataPubFormat() {
     return ContentType.JSON;
   }
@@ -129,7 +123,7 @@ public class JSONTest extends AbstractTest {
 
   protected void entitySet(final String filename, final ContentType contentType) throws Exception {
     final StringWriter writer = new StringWriter();
-    getClient().getSerializer(contentType).write(writer, getClient().getDeserializer(contentType).toEntitySet(
+    client.getSerializer(contentType).write(writer, client.getDeserializer(contentType).toEntitySet(
         getClass().getResourceAsStream(filename + "." + getSuffix(contentType))).getPayload());
 
     assertSimilar(filename + "." + getSuffix(contentType), writer.toString());
@@ -143,7 +137,7 @@ public class JSONTest extends AbstractTest {
 
   protected void entity(final String filename, final ContentType contentType) throws Exception {
     final StringWriter writer = new StringWriter();
-    getClient().getSerializer(contentType).write(writer, getClient().getDeserializer(contentType).toEntity(
+    client.getSerializer(contentType).write(writer, client.getDeserializer(contentType).toEntity(
         getClass().getResourceAsStream(filename + "." + getSuffix(contentType))).getPayload());
     assertSimilar(filename + "." + getSuffix(contentType), writer.toString());
   }
@@ -169,7 +163,7 @@ public class JSONTest extends AbstractTest {
 
   protected void property(final String filename, final ContentType contentType) throws Exception {
     final StringWriter writer = new StringWriter();
-    getClient().getSerializer(contentType).write(writer, getClient().getDeserializer(contentType).
+    client.getSerializer(contentType).write(writer, client.getDeserializer(contentType).
         toProperty(getClass().getResourceAsStream(filename + "." + getSuffix(contentType))).getPayload());
 
     assertSimilar(filename + "." + getSuffix(contentType), writer.toString());
@@ -185,12 +179,12 @@ public class JSONTest extends AbstractTest {
 
   @Test
   public void crossjoin() throws Exception {
-    assertNotNull(getClient().getDeserializer(ContentType.JSON_FULL_METADATA).toEntitySet(
+    assertNotNull(client.getDeserializer(ContentType.JSON_FULL_METADATA).toEntitySet(
         getClass().getResourceAsStream("crossjoin.json")));
   }
 
   protected void delta(final String filename, final ContentType contentType) throws Exception {
-    final Delta delta = getClient().getDeserializer(contentType).toDelta(
+    final Delta delta = client.getDeserializer(contentType).toDelta(
         getClass().getResourceAsStream(filename + "." + getSuffix(contentType))).getPayload();
     assertNotNull(delta);
     assertNotNull(delta.getDeltaLink());
@@ -223,30 +217,30 @@ public class JSONTest extends AbstractTest {
 
   @Test
   public void issueOLINGO390() throws Exception {
-    final ClientEntity message = getClient().getObjectFactory().
+    final ClientEntity message = client.getObjectFactory().
         newEntity(new FullQualifiedName("Microsoft.Exchange.Services.OData.Model.Message"));
 
-    final ClientComplexValue toRecipient = getClient().getObjectFactory().
+    final ClientComplexValue toRecipient = client.getObjectFactory().
         newComplexValue("Microsoft.Exchange.Services.OData.Model.Recipient");
-    toRecipient.add(getClient().getObjectFactory().newPrimitiveProperty("Name",
-        getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("challen_olingo_client")));
-    toRecipient.add(getClient().getObjectFactory().newPrimitiveProperty("Address",
-        getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("challenh@microsoft.com")));
-    final ClientCollectionValue<ClientValue> toRecipients = getClient().getObjectFactory().
+    toRecipient.add(client.getObjectFactory().newPrimitiveProperty("Name",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("challen_olingo_client")));
+    toRecipient.add(client.getObjectFactory().newPrimitiveProperty("Address",
+        client.getObjectFactory().newPrimitiveValueBuilder().buildString("challenh@microsoft.com")));
+    final ClientCollectionValue<ClientValue> toRecipients = client.getObjectFactory().
         newCollectionValue("Microsoft.Exchange.Services.OData.Model.Recipient");
     toRecipients.add(toRecipient);
-    message.getProperties().add(getClient().getObjectFactory().newCollectionProperty("ToRecipients", toRecipients));
+    message.getProperties().add(client.getObjectFactory().newCollectionProperty("ToRecipients", toRecipients));
 
     final ClientComplexValue body =
-        getClient().getObjectFactory().newComplexValue("Microsoft.Exchange.Services.OData.Model.ItemBody");
-    body.add(getClient().getObjectFactory().newPrimitiveProperty("Content",
-        getClient().getObjectFactory().newPrimitiveValueBuilder().
+        client.getObjectFactory().newComplexValue("Microsoft.Exchange.Services.OData.Model.ItemBody");
+    body.add(client.getObjectFactory().newPrimitiveProperty("Content",
+        client.getObjectFactory().newPrimitiveValueBuilder().
             buildString("this is a simple email body content")));
-    body.add(getClient().getObjectFactory().newEnumProperty("ContentType",
-        getClient().getObjectFactory().newEnumValue("Microsoft.Exchange.Services.OData.Model.BodyType", "text")));
-    message.getProperties().add(getClient().getObjectFactory().newComplexProperty("Body", body));
+    body.add(client.getObjectFactory().newEnumProperty("ContentType",
+        client.getObjectFactory().newEnumValue("Microsoft.Exchange.Services.OData.Model.BodyType", "text")));
+    message.getProperties().add(client.getObjectFactory().newComplexProperty("Body", body));
 
-    final String actual = IOUtils.toString(getClient().getWriter().writeEntity(message, ContentType.JSON));
+    final String actual = IOUtils.toString(client.getWriter().writeEntity(message, ContentType.JSON));
     final JsonNode expected =
         OBJECT_MAPPER.readTree(IOUtils.toString(getClass().getResourceAsStream("olingo390.json")).
             replace(Constants.JSON_NAVIGATION_LINK, Constants.JSON_BIND_LINK_SUFFIX));

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java
index a24ca36..c150e64 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/MetadataTest.java
@@ -26,7 +26,6 @@ import static org.junit.Assert.assertTrue;
 import java.io.InputStream;
 import java.util.List;
 
-import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.edm.xml.XMLMetadata;
 import org.apache.olingo.commons.api.Constants;
 import org.apache.olingo.commons.api.edm.Edm;
@@ -72,14 +71,9 @@ import org.junit.Test;
 
 public class MetadataTest extends AbstractTest {
 
-  @Override
-  protected ODataClient getClient() {
-    return v4Client;
-  }
-
   @Test
   public void parse() {
-    final Edm edm = getClient().getReader().readMetadata(getClass().getResourceAsStream("metadata.xml"));
+    final Edm edm = client.getReader().readMetadata(getClass().getResourceAsStream("metadata.xml"));
     assertNotNull(edm);
 
     // 1. Enum
@@ -140,7 +134,7 @@ public class MetadataTest extends AbstractTest {
 
   @Test
   public void demo() {
-    final XMLMetadata metadata = getClient().getDeserializer(ContentType.APPLICATION_XML).
+    final XMLMetadata metadata = client.getDeserializer(ContentType.APPLICATION_XML).
         toMetadata(getClass().getResourceAsStream("demo-metadata.xml"));
     assertNotNull(metadata);
 
@@ -154,7 +148,7 @@ public class MetadataTest extends AbstractTest {
         annots.getAnnotation("Org.OData.Publication.V1.PrivacyPolicyUrl").getExpression().asConstant().getValue());
 
     // Now let's test some edm:Annotations
-    final Edm edm = getClient().getReader().
+    final Edm edm = client.getReader().
         readMetadata(getClass().getResourceAsStream("demo-metadata.xml"));
     assertNotNull(edm);
 
@@ -181,7 +175,7 @@ public class MetadataTest extends AbstractTest {
 
   @Test
   public void multipleSchemas() {
-    final XMLMetadata metadata = getClient().getDeserializer(ContentType.APPLICATION_XML).
+    final XMLMetadata metadata = client.getDeserializer(ContentType.APPLICATION_XML).
         toMetadata(getClass().getResourceAsStream("northwind-metadata.xml"));
     assertNotNull(metadata);
 
@@ -198,10 +192,10 @@ public class MetadataTest extends AbstractTest {
 
   @Test
   public void getContainerWithoutCallingGetSchemas() {
-    final XMLMetadata metadata = getClient().getDeserializer(ContentType.APPLICATION_XML).
+    final XMLMetadata metadata = client.getDeserializer(ContentType.APPLICATION_XML).
         toMetadata(getClass().getResourceAsStream("fromdoc1-metadata.xml"));
 
-    Edm edm = getClient().getReader().readMetadata(metadata.getSchemaByNsOrAlias());
+    Edm edm = client.getReader().readMetadata(metadata.getSchemaByNsOrAlias());
 
     assertNotNull(edm.getEntityContainer());
   }
@@ -211,7 +205,7 @@ public class MetadataTest extends AbstractTest {
    */
   @Test
   public void fromdoc1() {
-    final XMLMetadata metadata = getClient().getDeserializer(ContentType.APPLICATION_XML).
+    final XMLMetadata metadata = client.getDeserializer(ContentType.APPLICATION_XML).
         toMetadata(getClass().getResourceAsStream("fromdoc1-metadata.xml"));
     assertNotNull(metadata);
 
@@ -249,7 +243,7 @@ public class MetadataTest extends AbstractTest {
         functionImport.getFunction());
 
     // Now let's go high-level
-    final Edm edm = getClient().getReader().readMetadata(getClass().getResourceAsStream("fromdoc1-metadata.xml"));
+    final Edm edm = client.getReader().readMetadata(getClass().getResourceAsStream("fromdoc1-metadata.xml"));
     assertNotNull(edm);
 
     List<EdmSchema> schemaList = edm.getSchemas();
@@ -291,7 +285,7 @@ public class MetadataTest extends AbstractTest {
    */
   @Test
   public void fromdoc2() {
-    final XMLMetadata metadata = getClient().getDeserializer(ContentType.APPLICATION_XML)
+    final XMLMetadata metadata = client.getDeserializer(ContentType.APPLICATION_XML)
         .toMetadata(getClass().getResourceAsStream("fromdoc2-metadata.xml"));
     assertNotNull(metadata);
 
@@ -336,7 +330,7 @@ public class MetadataTest extends AbstractTest {
    */
   @Test
   public void fromdoc3() {
-    final Edm edm = getClient().getReader().readMetadata(getClass().getResourceAsStream("fromdoc3-metadata.xml"));
+    final Edm edm = client.getReader().readMetadata(getClass().getResourceAsStream("fromdoc3-metadata.xml"));
     assertNotNull(edm);
 
     final EdmAnnotations group = edm.getSchema("Annotations").getAnnotationGroups().get(0);
@@ -354,7 +348,7 @@ public class MetadataTest extends AbstractTest {
    */
   @Test
   public void fromdoc4() {
-    final XMLMetadata metadata = getClient().getDeserializer(ContentType.APPLICATION_XML).
+    final XMLMetadata metadata = client.getDeserializer(ContentType.APPLICATION_XML).
         toMetadata(getClass().getResourceAsStream("fromdoc4-metadata.xml"));
     assertNotNull(metadata);
 
@@ -382,7 +376,7 @@ public class MetadataTest extends AbstractTest {
     assertTrue(urlRef.getValue().asDynamic().isApply());
 
     // Now let's go high-level
-    final Edm edm = getClient().getReader().readMetadata(getClass().getResourceAsStream("fromdoc4-metadata.xml"));
+    final Edm edm = client.getReader().readMetadata(getClass().getResourceAsStream("fromdoc4-metadata.xml"));
     assertNotNull(edm);
 
     final EdmAnnotations edmGroup = edm.getSchemas().get(0).getAnnotationGroups().get(0);
@@ -410,8 +404,7 @@ public class MetadataTest extends AbstractTest {
   @Test
   public void metadataWithCapabilities() throws Exception {
     InputStream input = getClass().getResourceAsStream("Metadata-With-Capabilities.xml");
-    final XMLMetadata metadata = getClient().getDeserializer(ContentType.APPLICATION_XML).
-        toMetadata(input);
+    final XMLMetadata metadata = client.getDeserializer(ContentType.APPLICATION_XML).toMetadata(input);
 
     CsdlSchema schema = metadata.getSchema("Capabilities");
     assertNotNull(schema);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/PrimitiveValueTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/PrimitiveValueTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/PrimitiveValueTest.java
index f46f272..3c31b55 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/PrimitiveValueTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/PrimitiveValueTest.java
@@ -18,31 +18,25 @@
  */
 package org.apache.olingo.client.core;
 
-import org.apache.olingo.client.api.ODataClient;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Calendar;
+
 import org.apache.olingo.client.api.domain.ClientValue;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.junit.Test;
 
-import java.util.Calendar;
-
-import static org.junit.Assert.assertEquals;
-
 public class PrimitiveValueTest extends AbstractTest {
 
-  @Override
-  protected ODataClient getClient() {
-    return v4Client;
-  }
-
   @Test
   public void timeOfDay() throws EdmPrimitiveTypeException {
     final Calendar expected = Calendar.getInstance();
     expected.clear();
     expected.set(2013, 0, 10, 21, 45, 17);
 
-    final ClientValue value = getClient().getObjectFactory().newPrimitiveValueBuilder().
-            setType(EdmPrimitiveTypeKind.TimeOfDay).setValue(expected).build();
+    final ClientValue value = client.getObjectFactory().newPrimitiveValueBuilder()
+        .setType(EdmPrimitiveTypeKind.TimeOfDay).setValue(expected).build();
     assertEquals(EdmPrimitiveTypeKind.TimeOfDay, value.asPrimitive().getTypeKind());
 
     final Calendar actual = value.asPrimitive().toCastValue(Calendar.class);
@@ -59,8 +53,8 @@ public class PrimitiveValueTest extends AbstractTest {
     expected.clear();
     expected.set(2013, 0, 10);
 
-    final ClientValue value = getClient().getObjectFactory().newPrimitiveValueBuilder().
-            setType(EdmPrimitiveTypeKind.Date).setValue(expected).build();
+    final ClientValue value = client.getObjectFactory().newPrimitiveValueBuilder()
+        .setType(EdmPrimitiveTypeKind.Date).setValue(expected).build();
     assertEquals(EdmPrimitiveTypeKind.Date, value.asPrimitive().getTypeKind());
 
     final Calendar actual = value.asPrimitive().toCastValue(Calendar.class);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/PropertyTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/PropertyTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/PropertyTest.java
index a545dc2..e7dc9ce 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/PropertyTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/PropertyTest.java
@@ -25,35 +25,29 @@ import static org.junit.Assert.assertTrue;
 import java.io.InputStream;
 import java.util.Iterator;
 
-import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.domain.ClientCollectionValue;
 import org.apache.olingo.client.api.domain.ClientComplexValue;
 import org.apache.olingo.client.api.domain.ClientProperty;
 import org.apache.olingo.client.api.domain.ClientValue;
-import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.client.api.serialization.ODataDeserializerException;
 import org.apache.olingo.client.api.serialization.ODataSerializerException;
+import org.apache.olingo.commons.api.format.ContentType;
 import org.junit.Test;
 
 public class PropertyTest extends AbstractTest {
 
-  @Override
-  protected ODataClient getClient() {
-    return v4Client;
-  }
-
   private void _enum(final ContentType contentType) throws ODataDeserializerException, ODataSerializerException {
     final InputStream input = getClass().getResourceAsStream("Products_5_SkinColor." + getSuffix(contentType));
-    final ClientProperty property = getClient().getReader().readProperty(input, contentType);
+    final ClientProperty property = client.getReader().readProperty(input, contentType);
     assertNotNull(property);
     assertTrue(property.hasEnumValue());
 
-    final ClientProperty written = getClient().getReader().readProperty(
-            getClient().getWriter().writeProperty(property, contentType), contentType);
+    final ClientProperty written = client.getReader().readProperty(
+            client.getWriter().writeProperty(property, contentType), contentType);
     // This is needed because type information gets lost with serialization
     if (contentType.isCompatible(ContentType.APPLICATION_XML)) {
-      final ClientProperty comparable = getClient().getObjectFactory().newEnumProperty(property.getName(),
-              getClient().getObjectFactory().
+      final ClientProperty comparable = client.getObjectFactory().newEnumProperty(property.getName(),
+              client.getObjectFactory().
               newEnumValue(property.getEnumValue().getTypeName(), written.getEnumValue().getValue()));
 
       assertEquals(property, comparable);
@@ -72,21 +66,21 @@ public class PropertyTest extends AbstractTest {
 
   private void complex(final ContentType contentType) throws ODataDeserializerException, ODataSerializerException {
     final InputStream input = getClass().getResourceAsStream("Employees_3_HomeAddress." + getSuffix(contentType));
-    final ClientProperty property = getClient().getReader().readProperty(input, contentType);
+    final ClientProperty property = client.getReader().readProperty(input, contentType);
     assertNotNull(property);
     assertTrue(property.hasComplexValue());
     assertEquals(3, property.getComplexValue().size());
 
-    final ClientProperty written = getClient().getReader().readProperty(
-            getClient().getWriter().writeProperty(property, contentType), contentType);
+    final ClientProperty written = client.getReader().readProperty(
+            client.getWriter().writeProperty(property, contentType), contentType);
     // This is needed because type information gets lost with JSON serialization
-    final ClientComplexValue typedValue = getClient().getObjectFactory().
+    final ClientComplexValue typedValue = client.getObjectFactory().
             newComplexValue(property.getComplexValue().getTypeName());
     for (final Iterator<ClientProperty> itor = written.getComplexValue().iterator(); itor.hasNext();) {
       final ClientProperty prop = itor.next();
       typedValue.add(prop);
     }
-    final ClientProperty comparable = getClient().getObjectFactory().
+    final ClientProperty comparable = client.getObjectFactory().
             newComplexProperty(property.getName(), typedValue);
 
     assertEquals(property, comparable);
@@ -104,22 +98,22 @@ public class PropertyTest extends AbstractTest {
 
   private void collection(final ContentType contentType) throws ODataDeserializerException, ODataSerializerException {
     final InputStream input = getClass().getResourceAsStream("Products_5_CoverColors." + getSuffix(contentType));
-    final ClientProperty property = getClient().getReader().readProperty(input, contentType);
+    final ClientProperty property = client.getReader().readProperty(input, contentType);
     assertNotNull(property);
     assertTrue(property.hasCollectionValue());
     assertEquals(3, property.getCollectionValue().size());
 
-    final ClientProperty written = getClient().getReader().readProperty(
-            getClient().getWriter().writeProperty(property, contentType), contentType);
+    final ClientProperty written = client.getReader().readProperty(
+            client.getWriter().writeProperty(property, contentType), contentType);
     // This is needed because type information gets lost with JSON serialization
     if(contentType.isCompatible(ContentType.APPLICATION_XML)) {
-      final ClientCollectionValue<ClientValue> typedValue = getClient().getObjectFactory().
+      final ClientCollectionValue<ClientValue> typedValue = client.getObjectFactory().
               newCollectionValue(property.getCollectionValue().getTypeName());
       for (final Iterator<ClientValue> itor = written.getCollectionValue().iterator(); itor.hasNext();) {
         final ClientValue value = itor.next();
         typedValue.add(value);
       }
-      final ClientProperty comparable = getClient().getObjectFactory().
+      final ClientProperty comparable = client.getObjectFactory().
               newCollectionProperty(property.getName(), typedValue);
 
       assertEquals(property, comparable);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/ServiceDocumentTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/ServiceDocumentTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/ServiceDocumentTest.java
index ae06f90..7a66fac 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/ServiceDocumentTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/ServiceDocumentTest.java
@@ -24,7 +24,6 @@ import static org.junit.Assert.assertTrue;
 
 import java.net.URI;
 
-import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.data.ResWrap;
 import org.apache.olingo.client.api.data.ServiceDocument;
 import org.apache.olingo.client.api.domain.ClientServiceDocument;
@@ -34,23 +33,14 @@ import org.junit.Test;
 
 public class ServiceDocumentTest extends AbstractTest {
 
-  @Override
-  protected ODataClient getClient() {
-    return v4Client;
-  }
-
-  private String getFileExtension(final ContentType contentType) {
-    return contentType.isCompatible(ContentType.APPLICATION_XML) ? "xml" : "json";
-  }
-
   private ClientServiceDocument parse(final ContentType contentType) throws ODataDeserializerException {
-    ResWrap<ServiceDocument> service = getClient().getDeserializer(contentType).toServiceDocument(
-        getClass().getResourceAsStream("serviceDocument." + getFileExtension(contentType)));
+    ResWrap<ServiceDocument> service = client.getDeserializer(contentType).toServiceDocument(
+        getClass().getResourceAsStream("serviceDocument." + getSuffix(contentType)));
 
     assertEquals(URI.create("http://host/service/$metadata"), service.getContextURL());
     assertEquals("W/\"MjAxMy0wNS0xM1QxNDo1NFo=\"", service.getMetadataETag());
 
-    final ClientServiceDocument serviceDocument = getClient().getBinder().getODataServiceDocument(service.getPayload());
+    final ClientServiceDocument serviceDocument = client.getBinder().getODataServiceDocument(service.getPayload());
     assertNotNull(serviceDocument);
 
     assertTrue(serviceDocument.getEntitySetNames().contains("Order Details"));

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/FilterFactoryTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/FilterFactoryTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/FilterFactoryTest.java
index 1d26f81..3b2c294 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/FilterFactoryTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/FilterFactoryTest.java
@@ -25,7 +25,6 @@ import java.net.URLEncoder;
 import java.util.Calendar;
 import java.util.TimeZone;
 
-import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.uri.FilterArgFactory;
 import org.apache.olingo.client.api.uri.FilterFactory;
 import org.apache.olingo.client.api.uri.URIFilter;
@@ -39,13 +38,8 @@ import org.junit.Test;
 
 public class FilterFactoryTest extends AbstractTest {
 
-  @Override
-  protected ODataClient getClient() {
-    return v4Client;
-  }
-
   private FilterFactory getFilterFactory() {
-    return getClient().getFilterFactory();
+    return client.getFilterFactory();
   }
 
   private FilterArgFactory getFilterArgFactory() {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/URIBuilderTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/URIBuilderTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/URIBuilderTest.java
index 2af662f..5f9cc8b 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/URIBuilderTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/uri/URIBuilderTest.java
@@ -26,32 +26,25 @@ import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
-import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.uri.QueryOption;
 import org.apache.olingo.client.api.uri.URIBuilder;
 import org.apache.olingo.client.core.AbstractTest;
-import org.apache.olingo.client.core.uri.ParameterAlias;
 import org.junit.Test;
 
 public class URIBuilderTest extends AbstractTest {
 
   private static final String SERVICE_ROOT = "http://host/service";
 
-  @Override
-  protected ODataClient getClient() {
-    return v4Client;
-  }
-
   @Test
   public void metadata() throws URISyntaxException {
-    final URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendMetadataSegment().build();
+    final URI uri = client.newURIBuilder(SERVICE_ROOT).appendMetadataSegment().build();
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/$metadata").build(), uri);
   }
 
   @Test
   public void entity() throws URISyntaxException {
-    final URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("AnEntitySet").
+    final URI uri = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("AnEntitySet").
         appendKeySegment(11).build();
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/AnEntitySet(11)").build(), uri);
@@ -59,21 +52,21 @@ public class URIBuilderTest extends AbstractTest {
     final Map<String, Object> multiKey = new LinkedHashMap<String, Object>();
     multiKey.put("OrderId", -10);
     multiKey.put("ProductId", -10);
-    URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+    URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
         appendEntitySetSegment("OrderLine").appendKeySegment(multiKey).
         appendPropertySegment("Quantity").appendValueSegment();
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(
         SERVICE_ROOT + "/OrderLine(OrderId=-10,ProductId=-10)/Quantity/$value").build(), uriBuilder.build());
 
-    uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+    uriBuilder = client.newURIBuilder(SERVICE_ROOT).
         appendEntitySetSegment("Customer").appendKeySegment(-10).
         select("CustomerId", "Name", "Orders").expand("Orders");
     assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Customer(-10)").
         addParameter("$select", "CustomerId,Name,Orders").addParameter("$expand", "Orders").build(),
         uriBuilder.build());
 
-    uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+    uriBuilder = client.newURIBuilder(SERVICE_ROOT).
         appendEntitySetSegment("Customer").appendKeySegment(-10).appendNavigationSegment("Orders").appendRefSegment();
     assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Customer(-10)/Orders/$ref").build(),
         uriBuilder.build());
@@ -81,7 +74,7 @@ public class URIBuilderTest extends AbstractTest {
 
   @Test
   public void expandWithOptions() throws URISyntaxException {
-    final URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(5).
+    final URI uri = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(5).
         expandWithOptions("ProductDetails", new LinkedHashMap<QueryOption, Object>() {
           private static final long serialVersionUID = 3109256773218160485L;
 
@@ -96,7 +89,7 @@ public class URIBuilderTest extends AbstractTest {
   }
 
   public void expandWithLevels() throws URISyntaxException {
-    final URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(1).
+    final URI uri = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(1).
         expandWithOptions("Customer", Collections.<QueryOption, Object> singletonMap(QueryOption.LEVELS, 4)).
         build();
 
@@ -106,11 +99,11 @@ public class URIBuilderTest extends AbstractTest {
 
   @Test
   public void count() throws URISyntaxException {
-    URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").count().build();
+    URI uri = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").count().build();
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Products/$count").build(), uri);
 
-    uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").count(true).build();
+    uri = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").count(true).build();
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Products").
         addParameter("$count", "true").build(), uri);
@@ -118,34 +111,34 @@ public class URIBuilderTest extends AbstractTest {
 
   @Test
   public void filter() throws URISyntaxException {
-    final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("AnEntitySet").
-        filter(getClient().getFilterFactory().lt("VIN", 16));
+    final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("AnEntitySet").
+        filter(client.getFilterFactory().lt("VIN", 16));
 
     assertEquals("http://host/service/AnEntitySet?%24filter=%28VIN%20lt%2016%29", uriBuilder.build().toASCIIString());
 
-//    assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/AnEntitySet").
-//        addParameter("$filter", "(VIN lt 16)").build(),
-//        uriBuilder.build());
+    //    assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/AnEntitySet").
+    //        addParameter("$filter", "(VIN lt 16)").build(),
+    //        uriBuilder.build());
   }
 
   @Test
   public void filterWithParameter() throws URISyntaxException {
     // http://host/service.svc/Employees?$filter=Region eq @p1&@p1='WA'
-    final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Employees").
-        filter(getClient().getFilterFactory().eq("Region", new ParameterAlias("p1"))).
+    final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Employees").
+        filter(client.getFilterFactory().eq("Region", new ParameterAlias("p1"))).
         addParameterAlias("p1", "'WA'");
 
     assertEquals("http://host/service/Employees?%24filter=%28Region%20eq%20%40p1%29&%40p1='WA'", uriBuilder.build()
         .toASCIIString());
 
-//    assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Employees").
-//        addParameter("$filter", "(Region eq @p1)").addParameter("@p1", "'WA'").build(),
-//        uriBuilder.build());
+    //    assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Employees").
+    //        addParameter("$filter", "(Region eq @p1)").addParameter("@p1", "'WA'").build(),
+    //        uriBuilder.build());
   }
 
   @Test
   public void expandMoreThenOnce() throws URISyntaxException {
-    URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(5).
+    URI uri = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Products").appendKeySegment(5).
         expand("Orders", "Customers").expand("Info").build();
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Products(5)").
@@ -154,7 +147,7 @@ public class URIBuilderTest extends AbstractTest {
 
   @Test
   public void selectMoreThenOnce() throws URISyntaxException {
-    URI uri = getClient().newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Customers").appendKeySegment(5).
+    URI uri = client.newURIBuilder(SERVICE_ROOT).appendEntitySetSegment("Customers").appendKeySegment(5).
         select("Name", "Surname").expand("Info").select("Gender").build();
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(SERVICE_ROOT + "/Customers(5)").
@@ -163,7 +156,7 @@ public class URIBuilderTest extends AbstractTest {
 
   @Test
   public void singleton() throws URISyntaxException {
-    final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+    final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
         appendSingletonSegment("BestProductEverCreated");
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(
@@ -172,7 +165,7 @@ public class URIBuilderTest extends AbstractTest {
 
   @Test
   public void entityId() throws URISyntaxException {
-    final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+    final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
         appendEntityIdSegment("Products(0)");
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(
@@ -181,7 +174,7 @@ public class URIBuilderTest extends AbstractTest {
 
   @Test
   public void boundAction() throws URISyntaxException {
-    final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+    final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
         appendEntitySetSegment("Categories").appendKeySegment(1).
         appendNavigationSegment("Products").
         appendActionCallSegment("Model.AllOrders");
@@ -189,10 +182,10 @@ public class URIBuilderTest extends AbstractTest {
     assertEquals(new org.apache.http.client.utils.URIBuilder(
         SERVICE_ROOT + "/Categories(1)/Products/Model.AllOrders").build(), uriBuilder.build());
   }
-  
+
   @Test
   public void boundOperation() throws URISyntaxException {
-    final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+    final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
         appendEntitySetSegment("Categories").appendKeySegment(1).
         appendNavigationSegment("Products").
         appendOperationCallSegment("Model.AllOrders");
@@ -203,14 +196,14 @@ public class URIBuilderTest extends AbstractTest {
 
   @Test
   public void ref() throws URISyntaxException {
-    URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+    URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
         appendEntitySetSegment("Categories").appendKeySegment(1).
         appendNavigationSegment("Products").appendRefSegment();
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(
         SERVICE_ROOT + "/Categories(1)/Products/$ref").build(), uriBuilder.build());
 
-    uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+    uriBuilder = client.newURIBuilder(SERVICE_ROOT).
         appendEntitySetSegment("Categories").appendKeySegment(1).
         appendNavigationSegment("Products").appendRefSegment().id("../../Products(0)");
 
@@ -221,7 +214,7 @@ public class URIBuilderTest extends AbstractTest {
 
   @Test
   public void derived() throws URISyntaxException {
-    final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+    final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
         appendEntitySetSegment("Customers").appendDerivedEntityTypeSegment("Model.VipCustomer").appendKeySegment(1);
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(
@@ -230,7 +223,7 @@ public class URIBuilderTest extends AbstractTest {
 
   @Test
   public void crossjoin() throws URISyntaxException {
-    final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+    final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
         appendCrossjoinSegment("Products", "Sales");
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(
@@ -239,7 +232,7 @@ public class URIBuilderTest extends AbstractTest {
 
   @Test
   public void all() throws URISyntaxException {
-    final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).appendAllSegment();
+    final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).appendAllSegment();
 
     assertEquals(new org.apache.http.client.utils.URIBuilder(
         SERVICE_ROOT + "/$all").build(), uriBuilder.build());
@@ -247,7 +240,7 @@ public class URIBuilderTest extends AbstractTest {
 
   @Test
   public void search() throws URISyntaxException {
-    final URIBuilder uriBuilder = getClient().newURIBuilder(SERVICE_ROOT).
+    final URIBuilder uriBuilder = client.newURIBuilder(SERVICE_ROOT).
         appendEntitySetSegment("Products").search("blue OR green");
 
     assertEquals(new URI("http://host/service/Products?%24search=blue%20OR%20green"), uriBuilder.build());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/geo/Geospatial.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/geo/Geospatial.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/geo/Geospatial.java
index 63d8b3f..860cbcc 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/geo/Geospatial.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/geo/Geospatial.java
@@ -72,7 +72,6 @@ public abstract class Geospatial {
      * The OGIS geometry type number for feature collections.
      */
     GEOSPATIALCOLLECTION
-
   }
 
   protected final Dimension dimension;
@@ -87,8 +86,8 @@ public abstract class Geospatial {
   /**
    * Constructor.
    *
-   * @param dimension dimension.
-   * @param type type.
+   * @param dimension dimension
+   * @param type type
    * @param srid SRID
    */
   protected Geospatial(final Dimension dimension, final Type type, final SRID srid) {
@@ -129,7 +128,7 @@ public abstract class Geospatial {
 
   /**
    * Returns the {@link EdmPrimitiveTypeKind}
-   * @return Edm primitve type kind
+   * @return EDM primitive type kind
    */
   public abstract EdmPrimitiveTypeKind getEdmPrimitiveTypeKind();
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNavigationPropertyImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNavigationPropertyImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNavigationPropertyImpl.java
index bf5dbc6..05abab9 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNavigationPropertyImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmNavigationPropertyImpl.java
@@ -23,7 +23,6 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.commons.api.edm.EdmElement;
 import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.commons.api.edm.EdmException;
 import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
@@ -32,7 +31,7 @@ import org.apache.olingo.commons.api.edm.EdmStructuredType;
 import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty;
 import org.apache.olingo.commons.api.edm.provider.CsdlReferentialConstraint;
 
-public class EdmNavigationPropertyImpl extends AbstractEdmNamed implements EdmElement, EdmNavigationProperty {
+public class EdmNavigationPropertyImpl extends AbstractEdmNamed implements EdmNavigationProperty {
 
   private final CsdlNavigationProperty navigationProperty;
   private List<EdmReferentialConstraint> referentialConstraints;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmParameterImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmParameterImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmParameterImpl.java
index 69af130..2f67761 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmParameterImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmParameterImpl.java
@@ -19,7 +19,6 @@
 package org.apache.olingo.commons.core.edm;
 
 import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.commons.api.edm.EdmElement;
 import org.apache.olingo.commons.api.edm.EdmException;
 import org.apache.olingo.commons.api.edm.EdmMapping;
 import org.apache.olingo.commons.api.edm.EdmParameter;
@@ -27,7 +26,7 @@ import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.edm.geo.SRID;
 import org.apache.olingo.commons.api.edm.provider.CsdlParameter;
 
-public class EdmParameterImpl extends AbstractEdmNamed implements EdmParameter, EdmElement {
+public class EdmParameterImpl extends AbstractEdmNamed implements EdmParameter {
 
   private final CsdlParameter parameter;
   private EdmType typeImpl;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java
index 5385d8a..67d0a21 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmPropertyImpl.java
@@ -19,7 +19,6 @@
 package org.apache.olingo.commons.core.edm;
 
 import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.commons.api.edm.EdmElement;
 import org.apache.olingo.commons.api.edm.EdmException;
 import org.apache.olingo.commons.api.edm.EdmMapping;
 import org.apache.olingo.commons.api.edm.EdmProperty;
@@ -27,7 +26,7 @@ import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.edm.geo.SRID;
 import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
 
-public class EdmPropertyImpl extends AbstractEdmNamed implements EdmProperty, EdmElement {
+public class EdmPropertyImpl extends AbstractEdmNamed implements EdmProperty {
 
   private final CsdlProperty property;
   private EdmTypeInfo typeInfo;
@@ -59,7 +58,7 @@ public class EdmPropertyImpl extends AbstractEdmNamed implements EdmProperty, Ed
     if (property.getType() == null) {
       throw new EdmException("Property " + property.getName() + " must hava a full qualified type.");
     }
-    typeInfo = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(property.getType().toString()).build();
+    typeInfo = new EdmTypeInfo.Builder().setEdm(edm).setTypeExpression(property.getType()).build();
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchFacadeImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchFacadeImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchFacadeImpl.java
index 9fe52c8..98bf563 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchFacadeImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchFacadeImpl.java
@@ -33,20 +33,26 @@ import org.apache.olingo.server.core.deserializer.batch.BatchParserCommon;
 public class BatchFacadeImpl implements BatchFacade {
   private final BatchPartHandler partHandler;
 
-  public BatchFacadeImpl(final ODataHandler oDataHandler, final ODataRequest request,
-      final BatchProcessor batchProcessor, final boolean isStrict) {
+  /**
+   * Creates a new BatchFacade.
+   * @param oDataHandler   handler
+   * @param batchProcessor batch processor
+   * @param isStrict       mode switch (currently not used)
+   */
+  public BatchFacadeImpl(final ODataHandler oDataHandler, final BatchProcessor batchProcessor,
+      final boolean isStrict) {
     partHandler = new BatchPartHandler(oDataHandler, batchProcessor, this);
   }
 
   @Override
-  public ODataResponse handleODataRequest(final ODataRequest request) throws ODataApplicationException,
-  ODataLibraryException {
+  public ODataResponse handleODataRequest(final ODataRequest request)
+      throws ODataApplicationException, ODataLibraryException {
     return partHandler.handleODataRequest(request);
   }
 
   @Override
-  public ODataResponsePart handleBatchRequest(final BatchRequestPart request) throws ODataApplicationException,
-  ODataLibraryException {
+  public ODataResponsePart handleBatchRequest(final BatchRequestPart request)
+      throws ODataApplicationException, ODataLibraryException {
     return partHandler.handleBatchRequest(request);
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchHandler.java
index ca253dc..121734e 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/batchhandler/BatchHandler.java
@@ -46,7 +46,7 @@ public class BatchHandler {
       throws ODataApplicationException, ODataLibraryException {
     validateRequest(request);
 
-    final BatchFacade operation = new BatchFacadeImpl(oDataHandler, request, batchProcessor, isStrict);
+    final BatchFacade operation = new BatchFacadeImpl(oDataHandler, batchProcessor, isStrict);
     batchProcessor.processBatch(operation, request, response);
   }
 


[4/7] olingo-odata4 git commit: [OLINGO-852] less warnings + general clean-up

Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/Vocabularies.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/Vocabularies.java b/fit/src/main/java/org/apache/olingo/fit/Vocabularies.java
index 0390eae..c13bf35 100644
--- a/fit/src/main/java/org/apache/olingo/fit/Vocabularies.java
+++ b/fit/src/main/java/org/apache/olingo/fit/Vocabularies.java
@@ -27,7 +27,6 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.apache.olingo.fit.metadata.Metadata;
 import org.apache.olingo.fit.utils.Accept;
 import org.apache.olingo.fit.utils.ConstantKey;
@@ -43,8 +42,8 @@ public class Vocabularies {
   private final XMLUtilities xml;
 
   public Vocabularies() throws IOException {
-    Metadata metadata = new Metadata(FSManager.instance(ODataServiceVersion.V40).readRes(
-            "vocabularies-" + Constants.get(ConstantKey.METADATA), Accept.XML));
+    Metadata metadata = new Metadata(FSManager.instance()
+        .readRes("vocabularies-" + Constants.get(ConstantKey.METADATA), Accept.XML));
     xml = new XMLUtilities(metadata);
   }
 
@@ -55,8 +54,7 @@ public class Vocabularies {
     try {
       return xml.createResponse(
           null,
-          FSManager.instance(ODataServiceVersion.V40).readRes(
-              "vocabularies-" + Constants.get(ConstantKey.METADATA), Accept.XML),
+          FSManager.instance().readRes("vocabularies-" + Constants.get(ConstantKey.METADATA), Accept.XML),
               null,
               Accept.XML);
     } catch (Exception e) {
@@ -71,7 +69,7 @@ public class Vocabularies {
     try {
       return xml.createResponse(
           null,
-          FSManager.instance(ODataServiceVersion.V40).readFile(vocabulary, null),
+          FSManager.instance().readFile(vocabulary, null),
           null,
           Accept.XML);
     } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/metadata/EntitySet.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/metadata/EntitySet.java b/fit/src/main/java/org/apache/olingo/fit/metadata/EntitySet.java
index 15285d2..c165bb7 100644
--- a/fit/src/main/java/org/apache/olingo/fit/metadata/EntitySet.java
+++ b/fit/src/main/java/org/apache/olingo/fit/metadata/EntitySet.java
@@ -24,18 +24,10 @@ import java.util.Map;
 public class EntitySet extends AbstractMetadataElement {
 
   private final String name;
-
   private String type;
-
   private final boolean singleton;
-
-  // --------------------------
-  // V4 only
-  // --------------------------
   private final Map<String, String> binding;
 
-  // --------------------------
-
   public EntitySet(final String name, final boolean singleton) {
     this.name = name;
     this.singleton = singleton;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2RequestFilter.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2RequestFilter.java b/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2RequestFilter.java
index 17476dd..a7ab945 100644
--- a/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2RequestFilter.java
+++ b/fit/src/main/java/org/apache/olingo/fit/rest/OAuth2RequestFilter.java
@@ -19,14 +19,13 @@
 package org.apache.olingo.fit.rest;
 
 import javax.ws.rs.container.ContainerRequestContext;
-import javax.ws.rs.container.ContainerRequestFilter;
 import javax.ws.rs.ext.Provider;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.cxf.rs.security.oauth2.filters.OAuthRequestFilter;
 
 @Provider
-public class OAuth2RequestFilter extends OAuthRequestFilter implements ContainerRequestFilter {
+public class OAuth2RequestFilter extends OAuthRequestFilter {
 
   @Override
   public void filter(final ContainerRequestContext context) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/serializer/FITAtomDeserializer.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/serializer/FITAtomDeserializer.java b/fit/src/main/java/org/apache/olingo/fit/serializer/FITAtomDeserializer.java
index d02475d..357dc5a 100644
--- a/fit/src/main/java/org/apache/olingo/fit/serializer/FITAtomDeserializer.java
+++ b/fit/src/main/java/org/apache/olingo/fit/serializer/FITAtomDeserializer.java
@@ -21,7 +21,6 @@ package org.apache.olingo.fit.serializer;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CodingErrorAction;
 
 import javax.xml.stream.XMLEventReader;
@@ -32,19 +31,15 @@ import org.apache.olingo.commons.api.Constants;
 
 public class FITAtomDeserializer extends AtomDeserializer {
 
-  private static final Charset ENCODING = Charset.forName(Constants.UTF8);
-
   public FITAtomDeserializer() {
     super();
   }
 
   @Override
   protected XMLEventReader getReader(final InputStream input) throws XMLStreamException {
-    final CharsetDecoder decoder = ENCODING.newDecoder();
-    decoder.onMalformedInput(CodingErrorAction.IGNORE);
-    decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
-
-    return FACTORY.createXMLEventReader(new InputStreamReader(input, decoder));
+    return FACTORY.createXMLEventReader(new InputStreamReader(input,
+        Charset.forName(Constants.UTF8).newDecoder()
+            .onMalformedInput(CodingErrorAction.IGNORE)
+            .onUnmappableCharacter(CodingErrorAction.IGNORE)));
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
index ee87eb0..a14cb8b 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/AbstractUtilities.java
@@ -34,7 +34,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
-import java.util.regex.Pattern;
 
 import javax.ws.rs.NotFoundException;
 import javax.ws.rs.core.Response;
@@ -70,38 +69,19 @@ public abstract class AbstractUtilities {
    */
   protected static final Logger LOG = LoggerFactory.getLogger(AbstractUtilities.class);
 
-  protected static final Pattern ENTITY_URI_PATTERN = Pattern.compile(".*\\/.*\\(.*\\)");
-
-  /**
-   * Batch/Changeset content type.
-   */
-  public static final String MULTIPART_CONTENT_TYPE = "multipart/mixed";
-
-  /**
-   * Batch item content type.
-   */
-  public static final String ITEM_CONTENT_TYPE = "application/http";
-
-  /**
-   * Boundary key.
-   */
-  public static final String BOUNDARY = "boundary";
-
   protected final Metadata metadata;
 
   protected final FSManager fsManager;
 
   protected final ODataDeserializer atomDeserializer;
-
   protected final ODataDeserializer jsonDeserializer;
 
   protected final ODataSerializer atomSerializer;
-
   protected final ODataSerializer jsonSerializer;
 
   public AbstractUtilities(final Metadata metadata) throws IOException {
     this.metadata = metadata;
-    fsManager = FSManager.instance(ODataServiceVersion.V40);
+    fsManager = FSManager.instance();
     atomDeserializer = new FITAtomDeserializer();
     jsonDeserializer = new JsonDeserializer(true);
     atomSerializer = new AtomSerializer(true);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java b/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
index 5f9a724..9acda31 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/Accept.java
@@ -20,33 +20,31 @@ package org.apache.olingo.fit.utils;
 
 import java.util.regex.Pattern;
 
-import org.apache.commons.lang3.StringUtils;
-import org.apache.http.entity.ContentType;
+import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.fit.UnsupportedMediaTypeException;
 
 public enum Accept {
 
-  TEXT(ContentType.TEXT_PLAIN.getMimeType(), ".txt"),
-  XML(ContentType.APPLICATION_XML.getMimeType(), ".xml"),
-  ATOM(ContentType.APPLICATION_ATOM_XML.getMimeType(), ".xml"),
-  JSON(ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=minimal", ".full.json"),
-  JSON_NOMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=none", ".full.json"),
-  JSON_FULLMETA(ContentType.APPLICATION_JSON.getMimeType() + ";odata.metadata=full", ".full.json");
+  TEXT(ContentType.TEXT_PLAIN, ".txt"),
+  XML(ContentType.APPLICATION_XML, ".xml"),
+  ATOM(ContentType.APPLICATION_ATOM_XML, ".xml"),
+  JSON(ContentType.JSON, ".full.json"),
+  JSON_NOMETA(ContentType.JSON_NO_METADATA, ".full.json"),
+  JSON_FULLMETA(ContentType.JSON_FULL_METADATA, ".full.json");
 
-  private final String contentTypeV4;
+  private static Pattern allTypesPattern = Pattern.compile("(.*,)?\\*/\\*([,;].*)?");
 
+  private final ContentType contentType;
   private final String fileExtension;
 
-  private static Pattern allTypesPattern = Pattern.compile("(.*,)?\\*/\\*([,;].*)?");
-
-  Accept(final String contentTypeV4, final String fileExtension) {
-    this.contentTypeV4 = contentTypeV4;
+  Accept(final ContentType contentType, final String fileExtension) {
+    this.contentType = contentType;
     this.fileExtension = fileExtension;
   }
 
   @Override
   public String toString() {
-    return contentTypeV4;
+    return contentType.toContentTypeString();
   }
 
   public String getExtension() {
@@ -58,15 +56,14 @@ public enum Accept {
   }
 
   public static Accept parse(final String contentType, final Accept def) {
-    if (StringUtils.isBlank(contentType) || allTypesPattern.matcher(contentType).matches()) {
+    if (contentType == null || contentType.isEmpty() || allTypesPattern.matcher(contentType).matches()) {
       return def;
     } else if (contentType.startsWith(JSON_NOMETA.toString())) {
       return JSON_NOMETA;
     } else if (contentType.startsWith(JSON_FULLMETA.toString())) {
       return JSON_FULLMETA;
     } else if (contentType.startsWith(JSON.toString())
-        || contentType.startsWith(ContentType.APPLICATION_JSON.getMimeType())) {
-
+        || contentType.startsWith(ContentType.APPLICATION_JSON.toContentTypeString())) {
       return JSON;
     } else if (contentType.startsWith(XML.toString())) {
       return XML;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java b/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
index 32644d9..5ee4d25 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/Commons.java
@@ -27,7 +27,6 @@ import java.net.URI;
 import java.util.AbstractMap.SimpleEntry;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.EnumMap;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -40,7 +39,6 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.apache.olingo.fit.metadata.Metadata;
-import org.codehaus.plexus.util.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -59,9 +57,6 @@ public abstract class Commons {
    */
   protected static final Logger LOG = LoggerFactory.getLogger(Commons.class);
 
-  private static final EnumMap<ODataServiceVersion, Metadata> METADATA =
-      new EnumMap<ODataServiceVersion, Metadata>(ODataServiceVersion.class);
-
   protected static final Pattern MULTIKEY_PATTERN = Pattern.compile("(.*=.*,?)+");
 
   protected static final Map<String, Integer> SEQUENCE = new HashMap<String, Integer>();
@@ -99,14 +94,11 @@ public abstract class Commons {
         new ImmutablePair<String, EdmPrimitiveTypeKind>("ID", EdmPrimitiveTypeKind.Guid));
   }
 
-  public static Metadata getMetadata(final ODataServiceVersion version) {
-    if (!METADATA.containsKey(version)) {
-      final InputStream is = Commons.class.getResourceAsStream("/" + version.name() + "/metadata.xml");
-
-      METADATA.put(version, new Metadata(is));
-    }
+  private static final Metadata METADATA =
+      new Metadata(Commons.class.getResourceAsStream("/" + ODataServiceVersion.V40.name() + "/metadata.xml"));
 
-    return METADATA.get(version);
+  public static Metadata getMetadata() {
+    return METADATA;
   }
 
   public static Map<String, Pair<String, EdmPrimitiveTypeKind>> getMediaContent() {
@@ -115,13 +107,13 @@ public abstract class Commons {
 
   public static String getEntityURI(final String entitySetName, final String entityKey) {
     // expected singleton in case of null key
-    return entitySetName + (StringUtils.isNotBlank(entityKey) ? "(" + entityKey + ")" : "");
+    return entitySetName + (entityKey == null || entityKey.isEmpty() ? "" : "(" + entityKey + ")");
   }
 
   public static String getEntityBasePath(final String entitySetName, final String entityKey) {
     // expected singleton in case of null key
     return entitySetName + File.separatorChar
-        + (StringUtils.isNotBlank(entityKey) ? getEntityKey(entityKey) + File.separatorChar : "");
+        + (entityKey == null || entityKey.isEmpty() ? "" : getEntityKey(entityKey) + File.separatorChar);
   }
 
   public static String getLinksURI(final String entitySetName, final String entityId, final String linkName)
@@ -138,7 +130,7 @@ public abstract class Commons {
   public static String getLinksPath(final String basePath, final String linkName, final Accept accept)
       throws IOException {
     try {
-      return FSManager.instance(ODataServiceVersion.V40)
+      return FSManager.instance()
           .getAbsolutePath(basePath + Constants.get(ConstantKey.LINKS_FILE_PATH)
               + File.separatorChar + linkName, accept);
     } catch (Exception e) {
@@ -281,7 +273,7 @@ public abstract class Commons {
 
   public static String getETag(final String basePath) throws Exception {
     try {
-      final InputStream is = FSManager.instance(ODataServiceVersion.V40).readFile(basePath + "etag", Accept.TEXT);
+      final InputStream is = FSManager.instance().readFile(basePath + "etag", Accept.TEXT);
       if (is.available() <= 0) {
         return null;
       } else {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/ConstantKey.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/ConstantKey.java b/fit/src/main/java/org/apache/olingo/fit/utils/ConstantKey.java
index 7315652..a8425df 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/ConstantKey.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/ConstantKey.java
@@ -25,20 +25,13 @@ public enum ConstantKey {
   ODATA_COUNT_NAME,
   ODATA_METADATA_PREFIX,
   ODATA_METADATA_ENTITY_SUFFIX,
-  ATOM_DEF_TYPE,
   ATOM_PROPERTY_PREFIX,
-  ATOM_METADATA_PREFIX,
-  ATOM_METADATA_NS,
-  ATOM_DATASERVICE_NS,
   ATOM_LINK_ENTRY,
   ATOM_LINK_FEED,
   ATOM_LINK_REL,
-  TYPE,
   INLINE_LOCAL,
-  INLINE_FILE_PATH,
   LINKS_FILE_PATH,
   INLINE,
-  CONTENT,
   PROPERTIES,
   LINK,
   DATASERVICES_NS,
@@ -66,6 +59,5 @@ public enum ConstantKey {
   JSON_TYPE_SUFFIX,
   JSON_ID_NAME,
   JSON_EDITLINK_NAME,
-  XHTTP_HEADER_NAME;
-
+  XHTTP_HEADER_NAME
 };

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java b/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java
index d0915a4..6a1d16a 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/Constants.java
@@ -55,19 +55,12 @@ public class Constants {
         "http://localhost:9080/stub/StaticService/V40/Static.svc/$metadata#");
     constants.put(ConstantKey.ODATA_METADATA_ENTITY_SUFFIX, "/$entity");
     constants.put(ConstantKey.ODATA_COUNT_NAME, "odata.count");
-    constants.put(ConstantKey.ATOM_DEF_TYPE, "Edm.String");
     constants.put(ConstantKey.ATOM_PROPERTY_PREFIX, "d:");
-    constants.put(ConstantKey.ATOM_METADATA_PREFIX, "m:");
-    constants.put(ConstantKey.ATOM_METADATA_NS, "xmlns:m");
-    constants.put(ConstantKey.ATOM_DATASERVICE_NS, "xmlns:d");
     constants.put(ConstantKey.ATOM_LINK_ENTRY, "application/atom+xml;type=entry");
     constants.put(ConstantKey.ATOM_LINK_FEED, "application/atom+xml;type=feed");
-    constants.put(ConstantKey.TYPE, "m:type");
     constants.put(ConstantKey.INLINE_LOCAL, "inline");
-    constants.put(ConstantKey.INLINE_FILE_PATH, "inline");
     constants.put(ConstantKey.LINKS_FILE_PATH, "links");
     constants.put(ConstantKey.INLINE, "m:inline");
-    constants.put(ConstantKey.CONTENT, "content");
     constants.put(ConstantKey.PROPERTIES, "m:properties");
     constants.put(ConstantKey.LINK, "link");
     constants.put(ConstantKey.METADATA, "metadata");

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java b/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java
index d3530c8..8202619 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/FSManager.java
@@ -25,8 +25,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
-import java.util.EnumMap;
-import java.util.Map;
 
 import javax.ws.rs.NotFoundException;
 
@@ -61,37 +59,34 @@ public class FSManager {
 
   private final FileSystemManager fsManager;
 
-  private static Map<ODataServiceVersion, FSManager> instance =
-      new EnumMap<ODataServiceVersion, FSManager>(ODataServiceVersion.class);
+  private static FSManager instance = null;
 
-  private final ODataServiceVersion version;
-
-  public static FSManager instance(final ODataServiceVersion version) throws IOException {
-    if (!instance.containsKey(version)) {
-      instance.put(version, new FSManager(version));
+  public static FSManager instance() throws IOException {
+    if (instance == null) {
+      instance = new FSManager();
     }
-    return instance.get(version);
+    return instance;
   }
 
-  private FSManager(final ODataServiceVersion version) throws IOException {
-    this.version = version;
+  private FSManager() throws IOException {
     fsManager = VFS.getManager();
 
-    final FileObject basePath = fsManager.resolveFile(RES_PREFIX + File.separatorChar + version.name());
+    final FileObject basePath =
+        fsManager.resolveFile(RES_PREFIX + File.separatorChar + ODataServiceVersion.V40.name());
     final String absoluteBaseFolder = basePath.getURL().getPath();
 
     for (FileObject fo : find(basePath, null)) {
       if (fo.getType() == FileType.FILE
           && !fo.getName().getBaseName().contains("Metadata")
           && !fo.getName().getBaseName().contains("metadata")) {
-        final String path = fo.getURL().getPath().replace(absoluteBaseFolder, "//" + version.name());
+        final String path = fo.getURL().getPath().replace(absoluteBaseFolder, "//" + ODataServiceVersion.V40.name());
         putInMemory(fo.getContent().getInputStream(), path);
       }
     }
   }
 
   public String getAbsolutePath(final String relativePath, final Accept accept) {
-    return File.separatorChar + version.name() + File.separatorChar + relativePath
+    return File.separatorChar + ODataServiceVersion.V40.name() + File.separatorChar + relativePath
         + (accept == null ? "" : accept.getExtension());
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/InjectableSerializerProvider.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/InjectableSerializerProvider.java b/fit/src/main/java/org/apache/olingo/fit/utils/InjectableSerializerProvider.java
deleted file mode 100644
index 02ada09..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/utils/InjectableSerializerProvider.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.fit.utils;
-
-import com.fasterxml.jackson.databind.SerializationConfig;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;
-import com.fasterxml.jackson.databind.ser.SerializerFactory;
-
-public class InjectableSerializerProvider extends DefaultSerializerProvider {
-
-  private static final long serialVersionUID = 3432260063063739646L;
-
-  public InjectableSerializerProvider(
-      final SerializerProvider src, final SerializationConfig config, final SerializerFactory factory) {
-
-    super(src, config, factory);
-  }
-
-  @Override
-  public InjectableSerializerProvider createInstance(
-      final SerializationConfig config, final SerializerFactory factory) {
-
-    return this;
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java
index 8be6b11..b18886d 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/JSONUtilities.java
@@ -39,7 +39,6 @@ import org.apache.olingo.fit.metadata.Metadata;
 import org.apache.olingo.fit.metadata.NavigationProperty;
 
 import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.databind.InjectableValues;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ArrayNode;
@@ -48,21 +47,10 @@ import com.fasterxml.jackson.databind.node.TextNode;
 
 public class JSONUtilities extends AbstractUtilities {
 
-  private final ObjectMapper mapper;
+  private final ObjectMapper mapper = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);
 
   public JSONUtilities(final Metadata metadata) throws IOException {
     super(metadata);
-
-    mapper = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL);
-    mapper.setInjectableValues(new InjectableValues.Std().
-        addValue(Boolean.class, Boolean.TRUE));
-    // addValue(ODataServiceVersion.class, version))
-
-    mapper.setSerializerProvider(new InjectableSerializerProvider(mapper.getSerializerProvider(),
-        mapper.getSerializationConfig().
-        // withAttribute(ODataServiceVersion.class, version).
-        withAttribute(Boolean.class, Boolean.TRUE),
-        mapper.getSerializerFactory()));
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/MetadataLinkInfo.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/MetadataLinkInfo.java b/fit/src/main/java/org/apache/olingo/fit/utils/MetadataLinkInfo.java
deleted file mode 100644
index e79ce96..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/utils/MetadataLinkInfo.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 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.fit.utils;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import javax.ws.rs.NotFoundException;
-
-public class MetadataLinkInfo {
-
-  private Map<String, EntitySet> entitySets = new HashMap<String, EntitySet>();
-
-  public void setSingleton(final String entitySetName) {
-    entitySets.get(entitySetName).setSingleton(true);
-  }
-
-  public boolean isSingleton(final String entitySetName) {
-    return entitySets.get(entitySetName).isSingleton();
-  }
-
-  public Set<String> getEntitySets() {
-    return entitySets.keySet();
-  }
-
-  public void addEntitySet(final String entitySetName) {
-    if (!entitySets.containsKey(entitySetName)) {
-      entitySets.put(entitySetName, new EntitySet(entitySetName));
-    }
-  }
-
-  public void addLink(
-      final String entitySetName, final String linkName, final String targetName, final boolean isFeed) {
-    final EntitySet entitySet;
-    if (entitySets.containsKey(entitySetName)) {
-      entitySet = entitySets.get(entitySetName);
-    } else {
-      entitySet = new EntitySet(entitySetName);
-      entitySets.put(entitySetName, entitySet);
-    }
-
-    entitySet.add(linkName, targetName, isFeed);
-  }
-
-  public Set<String> getNavigationLinkNames(final String entitySetName) {
-    final Set<String> res = new HashSet<String>();
-
-    if (!entitySets.containsKey(entitySetName)) {
-      throw new NotFoundException();
-    }
-
-    for (NavigationLink navigationLink : entitySets.get(entitySetName).getLinks()) {
-      res.add(navigationLink.getName());
-    }
-
-    return res;
-  }
-
-  public boolean exists(final String entitySetName, final String linkName) {
-    try {
-      return getNavigationLinkNames(entitySetName).contains(linkName);
-    } catch (Exception e) {
-      return false;
-    }
-  }
-
-  public boolean isFeed(final String entitySetName, final String linkName) {
-    return entitySets.containsKey(entitySetName) && entitySets.get(entitySetName).isFeed(linkName);
-  }
-
-  public String getTargetName(final String entitySetName, final String linkName) {
-    if (!entitySets.containsKey(entitySetName)) {
-      throw new NotFoundException();
-    }
-
-    final String targetName = entitySets.get(entitySetName).getLink(linkName).getTargetName();
-    return targetName.substring(targetName.lastIndexOf(".") + 1);
-  }
-
-  private static class EntitySet {
-
-    private String name;
-
-    private Set<NavigationLink> links;
-
-    private boolean singleton;
-
-    public EntitySet(final String name) {
-      this.name = name;
-      links = new HashSet<NavigationLink>();
-    }
-
-    public void add(final String linkName, final String targetName, final boolean isFeed) {
-      links.add(new NavigationLink(linkName, targetName, isFeed));
-    }
-
-    public Set<NavigationLink> getLinks() {
-      return links;
-    }
-
-    public NavigationLink getLink(final String linkName) {
-      for (NavigationLink navigationLink : links) {
-        if (linkName.equalsIgnoreCase(navigationLink.getName())) {
-          return navigationLink;
-        }
-      }
-
-      throw new NotFoundException();
-    }
-
-    public boolean isFeed(final String linkName) {
-      try {
-        return getLink(linkName).isFeed();
-      } catch (Exception e) {
-        return false;
-      }
-    }
-
-    public boolean isSingleton() {
-      return singleton;
-    }
-
-    public void setSingleton(final boolean singleton) {
-      this.singleton = singleton;
-    }
-
-    @Override
-    public String toString() {
-      return name + ": " + links;
-    }
-  }
-
-  private static class NavigationLink {
-
-    private final String name;
-
-    private final String targetName;
-
-    private final boolean feed;
-
-    public NavigationLink(final String name, final String targetName, final boolean feed) {
-      this.name = name;
-      this.targetName = targetName;
-      this.feed = feed;
-    }
-
-    public String getName() {
-      return name;
-    }
-
-    public String getTargetName() {
-      return targetName;
-    }
-
-    public boolean isFeed() {
-      return feed;
-    }
-
-    @Override
-    public String toString() {
-      return name + "(feed: " + isFeed() + ")";
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java b/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
index 1078e2f..c7930f0 100644
--- a/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
+++ b/fit/src/main/java/org/apache/olingo/fit/utils/XMLUtilities.java
@@ -38,6 +38,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.regex.Pattern;
 
 import javax.ws.rs.NotFoundException;
 import javax.xml.namespace.QName;
@@ -61,6 +62,8 @@ import org.apache.olingo.fit.metadata.NavigationProperty;
 
 public class XMLUtilities extends AbstractUtilities {
 
+  private static final Pattern ENTITY_URI_PATTERN = Pattern.compile(".*\\/.*\\(.*\\)");
+
   protected static XMLInputFactory ifactory = null;
 
   protected static XMLOutputFactory ofactory = null;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Customer.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Customer.java b/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Customer.java
index 405ce0a..b9d15cc 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Customer.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Customer.java
@@ -18,9 +18,7 @@
  */
 package org.apache.olingo.fit.proxy.demo.odatademo.types;
 
-// CHECKSTYLE:OFF (Maven checkstyle)
 import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
 
 import org.apache.olingo.ext.proxy.api.annotations.Key;
 
@@ -30,9 +28,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
     hasStream = false,
     isAbstract = false,
     baseType = "ODataDemo.Person")
-public interface Customer
-    extends org.apache.olingo.ext.proxy.api.Annotatable,
-        Person {
+public interface Customer extends Person {
 
   @Override
   Customer load();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Employee.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Employee.java b/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Employee.java
index 4b55f53..8b48599 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Employee.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/Employee.java
@@ -18,9 +18,7 @@
  */
 package org.apache.olingo.fit.proxy.demo.odatademo.types;
 
-// CHECKSTYLE:OFF (Maven checkstyle)
 import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
 
 import org.apache.olingo.ext.proxy.api.annotations.Key;
 
@@ -30,9 +28,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
     hasStream = false,
     isAbstract = false,
     baseType = "ODataDemo.Person")
-public interface Employee
-    extends org.apache.olingo.ext.proxy.api.Annotatable,
-        Person {
+public interface Employee extends Person {
 
   @Override
   Employee load();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/FeaturedProduct.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/FeaturedProduct.java b/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/FeaturedProduct.java
index 0d09511..b38852c 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/FeaturedProduct.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/demo/odatademo/types/FeaturedProduct.java
@@ -18,9 +18,7 @@
  */
 package org.apache.olingo.fit.proxy.demo.odatademo.types;
 
-// CHECKSTYLE:OFF (Maven checkstyle)
 import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
 
 import org.apache.olingo.ext.proxy.api.annotations.Key;
 
@@ -30,9 +28,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
     hasStream = false,
     isAbstract = false,
     baseType = "ODataDemo.Product")
-public interface FeaturedProduct
-    extends org.apache.olingo.ext.proxy.api.Annotatable,
-        Product {
+public interface FeaturedProduct extends Product {
 
   @Override
   FeaturedProduct load();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/opentype/microsoft/test/odata/services/opentypesservice/types/IndexedRow.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/opentype/microsoft/test/odata/services/opentypesservice/types/IndexedRow.java b/fit/src/test/java/org/apache/olingo/fit/proxy/opentype/microsoft/test/odata/services/opentypesservice/types/IndexedRow.java
index 2de8869..f2618f2 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/opentype/microsoft/test/odata/services/opentypesservice/types/IndexedRow.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/opentype/microsoft/test/odata/services/opentypesservice/types/IndexedRow.java
@@ -18,11 +18,8 @@
  */
 package org.apache.olingo.fit.proxy.opentype.microsoft.test.odata.services.opentypesservice.types;
 
-// CHECKSTYLE:OFF (Maven checkstyle)
 import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
 
-import org.apache.olingo.ext.proxy.api.AbstractOpenType;
 import org.apache.olingo.ext.proxy.api.annotations.Key;
 
 @org.apache.olingo.ext.proxy.api.annotations.Namespace("Microsoft.Test.OData.Services.OpenTypesServiceV4")
@@ -31,10 +28,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
     hasStream = false,
     isAbstract = false,
     baseType = "Microsoft.Test.OData.Services.OpenTypesServiceV4.Row")
-public interface IndexedRow
-    extends org.apache.olingo.ext.proxy.api.Annotatable,
-        Row,
-    AbstractOpenType {
+public interface IndexedRow extends Row {
 
   @Override
   IndexedRow load();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/CreditCardPI.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/CreditCardPI.java b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/CreditCardPI.java
index 6873492..179f2e1 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/CreditCardPI.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/CreditCardPI.java
@@ -18,9 +18,7 @@
  */
 package org.apache.olingo.fit.proxy.staticservice.microsoft.test.odata.services.odatawcfservice.types;
 
-// CHECKSTYLE:OFF (Maven checkstyle)
 import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
 
 import org.apache.olingo.ext.proxy.api.AbstractEntitySet;
 import org.apache.olingo.ext.proxy.api.annotations.Key;
@@ -31,9 +29,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
     hasStream = false,
     isAbstract = false,
     baseType = "Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument")
-public interface CreditCardPI
-    extends org.apache.olingo.ext.proxy.api.Annotatable,
-        PaymentInstrument {
+public interface CreditCardPI extends PaymentInstrument {
 
   @Override
   CreditCardPI load();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Customer.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Customer.java b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Customer.java
index ed6fdc1..af66869 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Customer.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Customer.java
@@ -18,9 +18,7 @@
  */
 package org.apache.olingo.fit.proxy.staticservice.microsoft.test.odata.services.odatawcfservice.types;
 
-// CHECKSTYLE:OFF (Maven checkstyle)
 import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
 
 import org.apache.olingo.ext.proxy.api.annotations.Key;
 
@@ -30,9 +28,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
     hasStream = false,
     isAbstract = false,
     baseType = "Microsoft.Test.OData.Services.ODataWCFService.Person")
-public interface Customer
-    extends org.apache.olingo.ext.proxy.api.Annotatable,
-        Person {
+public interface Customer extends Person {
 
   @Override
   Customer load();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Employee.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Employee.java b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Employee.java
index f33ccb3..f0b4e80 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Employee.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/Employee.java
@@ -18,9 +18,7 @@
  */
 package org.apache.olingo.fit.proxy.staticservice.microsoft.test.odata.services.odatawcfservice.types;
 
-// CHECKSTYLE:OFF (Maven checkstyle)
 import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
 
 import org.apache.olingo.ext.proxy.api.annotations.Key;
 
@@ -30,9 +28,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
     hasStream = false,
     isAbstract = false,
     baseType = "Microsoft.Test.OData.Services.ODataWCFService.Person")
-public interface Employee
-    extends org.apache.olingo.ext.proxy.api.Annotatable,
-        Person {
+public interface Employee extends Person {
 
   @Override
   Employee load();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/PublicCompany.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/PublicCompany.java b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/PublicCompany.java
index cdace92..40144ef 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/PublicCompany.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/staticservice/microsoft/test/odata/services/odatawcfservice/types/PublicCompany.java
@@ -18,12 +18,9 @@
  */
 package org.apache.olingo.fit.proxy.staticservice.microsoft.test.odata.services.odatawcfservice.types;
 
-// CHECKSTYLE:OFF (Maven checkstyle)
 import java.util.concurrent.Future;
-// CHECKSTYLE:ON (Maven checkstyle)
 
 import org.apache.olingo.ext.proxy.api.AbstractEntitySet;
-import org.apache.olingo.ext.proxy.api.AbstractOpenType;
 import org.apache.olingo.ext.proxy.api.annotations.Key;
 
 @org.apache.olingo.ext.proxy.api.annotations.Namespace("Microsoft.Test.OData.Services.ODataWCFService")
@@ -32,10 +29,7 @@ import org.apache.olingo.ext.proxy.api.annotations.Key;
     hasStream = false,
     isAbstract = false,
     baseType = "Microsoft.Test.OData.Services.ODataWCFService.Company")
-public interface PublicCompany
-    extends org.apache.olingo.ext.proxy.api.Annotatable,
-        Company,
-    AbstractOpenType {
+public interface PublicCompany extends Company {
 
   @Override
   PublicCompany load();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/EntityReferencesITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/EntityReferencesITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/EntityReferencesITCase.java
index 94867af..bac2927 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/EntityReferencesITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/EntityReferencesITCase.java
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
 
 import java.net.URI;
+import java.util.EnumMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -553,11 +554,11 @@ public class EntityReferencesITCase extends AbstractParamTecSvcITCase {
            .getReferenceSingleChangeRequest(new URI(SERVICE_URI), uri, reference)
            .execute();
       assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode());
-      
+
       final String cookie = response.getHeader(HttpHeader.SET_COOKIE).iterator().next();
-      Map<QueryOption, Object> expandOptions = new HashMap<QueryOption, Object>();
+      Map<QueryOption, Object> expandOptions = new EnumMap<QueryOption, Object>(QueryOption.class);
       expandOptions.put(QueryOption.EXPAND, NAV_PROPERTY_ET_KEY_NAV_ONE);
-      
+
       final URI getURI = getClient().newURIBuilder(SERVICE_URI)
                                .appendEntitySetSegment(ES_TWO_KEY_NAV)
                                .appendKeySegment(esTwoKeyNavKey)
@@ -601,12 +602,12 @@ public class EntityReferencesITCase extends AbstractParamTecSvcITCase {
            .getReferenceAddingRequest(new URI(SERVICE_URI), uri, reference)
            .execute();
       assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode());
-      
+
       final String cookie = response.getHeader(HttpHeader.SET_COOKIE).iterator().next();
-      final Map<QueryOption, Object> expandOptions = new HashMap<QueryOption, Object>();
+      final Map<QueryOption, Object> expandOptions = new EnumMap<QueryOption, Object>(QueryOption.class);
       expandOptions.put(QueryOption.EXPAND, NAV_PROPERTY_ET_KEY_NAV_MANY);
       expandOptions.put(QueryOption.FILTER, "PropertyInt16 eq 1");
-      
+
       final URI getURI = getClient().newURIBuilder(SERVICE_URI)
                                .appendEntitySetSegment(ES_TWO_KEY_NAV)
                                .appendKeySegment(esTwoKeyNavKey)

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
index 507b9a9..0f3743b 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
@@ -23,6 +23,8 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 
 import java.net.URI;
+import java.util.Collections;
+import java.util.EnumMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -49,11 +51,10 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
 
   @Test
   public void filter() {
-    Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
-    options.put(QueryOption.FILTER, "PropertyString eq '2'");
-
     final ODataRetrieveResponse<ClientEntitySet> response =
-        buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options);
+        buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY,
+            Collections.singletonMap(QueryOption.FILTER, (Object) "PropertyString eq '2'"));
+
     final List<ClientEntity> entities = response.getBody().getEntities();
     assertEquals(4, entities.size());
 
@@ -87,11 +88,9 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
 
   @Test
   public void orderBy() {
-    Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
-    options.put(QueryOption.ORDERBY, "PropertyString desc");
-
     final ODataRetrieveResponse<ClientEntitySet> response =
-        buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options);
+        buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY,
+            Collections.<QueryOption, Object> singletonMap(QueryOption.ORDERBY, "PropertyString desc"));
     final List<ClientEntity> entities = response.getBody().getEntities();
     assertEquals(4, entities.size());
 
@@ -117,11 +116,9 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
 
   @Test
   public void skip() {
-    Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
-    options.put(QueryOption.SKIP, "1");
-
     final ODataRetrieveResponse<ClientEntitySet> response =
-        buildRequest(ES_KEY_NAV, NAV_PROPERTY_ET_KEY_NAV_MANY, options);
+        buildRequest(ES_KEY_NAV, NAV_PROPERTY_ET_KEY_NAV_MANY,
+            Collections.singletonMap(QueryOption.SKIP, (Object) "1"));
     final List<ClientEntity> entities = response.getBody().getEntities();
     assertEquals(3, entities.size());
 
@@ -148,11 +145,9 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
 
   @Test
   public void top() {
-    Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
-    options.put(QueryOption.TOP, "1");
-
     final ODataRetrieveResponse<ClientEntitySet> response =
-        buildRequest(ES_KEY_NAV, NAV_PROPERTY_ET_KEY_NAV_MANY, options);
+        buildRequest(ES_KEY_NAV, NAV_PROPERTY_ET_KEY_NAV_MANY,
+            Collections.<QueryOption, Object> singletonMap(QueryOption.TOP, "1"));
     final List<ClientEntity> entities = response.getBody().getEntities();
     assertEquals(3, entities.size());
 
@@ -179,7 +174,7 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
 
   @Test
   public void combinedSystemQueryOptions() {
-    Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
+    Map<QueryOption, Object> options = new EnumMap<QueryOption, Object>(QueryOption.class);
     options.put(QueryOption.SELECT, "PropertyInt16,PropertyString");
     options.put(QueryOption.FILTER, "PropertyInt16 eq 1");
     options.put(QueryOption.SKIP, "1");
@@ -217,7 +212,7 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
   @Ignore("Server do not support navigation property count annotations")
   public void count() {
     final ODataClient client = getEdmEnabledClient();
-    Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
+    Map<QueryOption, Object> options = new EnumMap<QueryOption, Object>(QueryOption.class);
     options.put(QueryOption.SELECT, "PropertyInt16");
     options.put(QueryOption.COUNT, true);
 
@@ -255,14 +250,14 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
   public void singleEntityWithExpand() {
     /* A single entity request will be dispatched to a different processor method than entity set request */
     final ODataClient client = getEdmEnabledClient();
-    Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
-    options.put(QueryOption.FILTER, "PropertyInt16 lt 2");
     Map<String, Object> keys = new HashMap<String, Object>();
     keys.put("PropertyInt16", 1);
     keys.put("PropertyString", "1");
 
     final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_TWO_KEY_NAV).appendKeySegment(keys)
-        .expandWithOptions(NAV_PROPERTY_ET_KEY_NAV_MANY, options).build();
+        .expandWithOptions(NAV_PROPERTY_ET_KEY_NAV_MANY,
+            Collections.singletonMap(QueryOption.FILTER, (Object) "PropertyInt16 lt 2"))
+        .build();
     final ODataRetrieveResponse<ClientEntity> response =
             client.getRetrieveRequestFactory().getEntityRequest(uri).execute();
     assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
@@ -275,11 +270,12 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
 
   @Test
   public void URIEscaping() {
-    Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
-    options.put(QueryOption.FILTER, "PropertyInt16 eq 1"
-        + " and PropertyComp/PropertyComp/PropertyDuration eq duration'PT1S' and length(PropertyString) gt 4");
     final ODataRetrieveResponse<ClientEntitySet> response =
-        buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options);
+        buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY,
+            Collections.<QueryOption, Object> singletonMap(QueryOption.FILTER,
+                "PropertyInt16 eq 1"
+                + " and PropertyComp/PropertyComp/PropertyDuration eq duration'PT1S'"
+                + " and length(PropertyString) gt 4"));
     final List<ClientEntity> entities = response.getBody().getEntities();
 
     assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
@@ -296,7 +292,7 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
     // Define filters to select explicit the entities at any level => Circle
 
     final ODataClient client = getEdmEnabledClient();
-    Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
+    Map<QueryOption, Object> options = new EnumMap<QueryOption, Object>(QueryOption.class);
     options.put(QueryOption.EXPAND, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY
         + "($expand=" + NAV_PROPERTY_ET_TWO_KEY_NAV_MANY
         + "($expand=" + NAV_PROPERTY_ET_TWO_KEY_NAV_MANY + "))");
@@ -371,7 +367,7 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
   @Test
   public void systemQueryOptionOnThirdLevel() {
     final ODataClient client = getEdmEnabledClient();
-    Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
+    Map<QueryOption, Object> options = new EnumMap<QueryOption, Object>(QueryOption.class);
     options.put(QueryOption.EXPAND, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY
         + "($expand=" + NAV_PROPERTY_ET_TWO_KEY_NAV_MANY
         + "($expand=" + NAV_PROPERTY_ET_TWO_KEY_NAV_MANY
@@ -444,7 +440,7 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
   @Test
   public void expandWithSearchQuery() {
     final ODataClient client = getEdmEnabledClient();
-    Map<QueryOption, Object> expandOptions = new HashMap<QueryOption, Object>();
+    Map<QueryOption, Object> expandOptions = new EnumMap<QueryOption, Object>(QueryOption.class);
     expandOptions.put(QueryOption.SEARCH, "abc");
     expandOptions.put(QueryOption.FILTER, "PropertyInt16 eq 1");
     
@@ -464,12 +460,10 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
   @Test
   public void expandWithLevels() {
     final ODataClient client = getEdmEnabledClient();
-    Map<QueryOption, Object> expandOptions = new HashMap<QueryOption, Object>();
-    expandOptions.put(QueryOption.LEVELS, 2);
 
     // expand=*($levels=2)
     URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV)
-            .expandWithOptions("*", expandOptions)
+            .expandWithOptions("*", Collections.<QueryOption, Object> singletonMap(QueryOption.LEVELS, 2))
             .build();
 
     try {
@@ -479,10 +473,9 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
     }
 
     // expand=NavPropertyETTwoKeyNavMany($levels=2)
-    expandOptions.clear();
-    expandOptions.put(QueryOption.LEVELS, 2);
     uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV)
-            .expandWithOptions(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, expandOptions)
+            .expandWithOptions(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY,
+                Collections.<QueryOption, Object> singletonMap(QueryOption.LEVELS, 2))
             .build();
 
     try {
@@ -492,10 +485,10 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
     }
 
     // expand=NavPropertyETTwoKeyNavMany($expand=NavPropertyETTwoKeyNavMany($levels=2))
-    expandOptions.clear();
-    expandOptions.put(QueryOption.EXPAND, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY + "($levels=2)");
     uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV)
-            .expandWithOptions(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, expandOptions)
+            .expandWithOptions(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY,
+                Collections.<QueryOption, Object> singletonMap(QueryOption.EXPAND,
+                    NAV_PROPERTY_ET_TWO_KEY_NAV_MANY + "($levels=2)"))
             .build();
 
     try {
@@ -505,10 +498,9 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
     }
 
     // expand=NavPropertyETTwoKeyNavMany($expand=NavPropertyETTwoKeyNavMany($levels=2);$levels=3)
-    expandOptions.clear();
-    expandOptions.put(QueryOption.LEVELS, 2);
     uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV)
-            .expandWithOptions(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, expandOptions)
+            .expandWithOptions(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY,
+                Collections.<QueryOption, Object> singletonMap(QueryOption.LEVELS, 2))
             .build();
 
     try {
@@ -518,7 +510,7 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractParamTecSvcITCas
     }
 
     // expand=NavPropertyETTwoKeyNavMany($expand=NavPropertyETTwoKeyNavMany($levels=2))
-    expandOptions.clear();
+    Map<QueryOption, Object> expandOptions = new EnumMap<QueryOption, Object>(QueryOption.class);
     expandOptions.put(QueryOption.EXPAND, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY + "($levels=2)");
     expandOptions.put(QueryOption.LEVELS, 3);
     uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV)

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/AbstractClientEntitySet.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/AbstractClientEntitySet.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/AbstractClientEntitySet.java
deleted file mode 100644
index d59af93..0000000
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/AbstractClientEntitySet.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.client.core.domain;
-
-import java.net.URI;
-
-import org.apache.olingo.client.api.domain.AbstractClientPayload;
-import org.apache.olingo.client.api.domain.ClientEntitySet;
-
-public abstract class AbstractClientEntitySet extends AbstractClientPayload implements ClientEntitySet {
-
-  /**
-   * Link to the next page.
-   */
-  private URI next;
-
-  /**
-   * Number of ODataEntities contained in this entity set.
-   * <br/>
-   * If <tt>$count</tt> was requested, this value comes from there.
-   */
-  private Integer count;
-
-  /**
-   * Constructor.
-   */
-  public AbstractClientEntitySet() {
-    super(null);
-  }
-
-  /**
-   * Constructor.
-   * 
-   * @param next next link.
-   */
-  public AbstractClientEntitySet(final URI next) {
-    super(null);
-    this.next = next;
-  }
-
-  @Override
-  public URI getNext() {
-    return next;
-  }
-
-  @Override
-  public Integer getCount() {
-    return count;
-  }
-
-  @Override
-  public void setCount(final int count) {
-    this.count = count;
-  }
-
-  @Override
-  public int hashCode() {
-    final int prime = 31;
-    int result = super.hashCode();
-    result = prime * result + ((count == null) ? 0 : count.hashCode());
-    result = prime * result + ((next == null) ? 0 : next.hashCode());
-    return result;
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (this == obj) {
-      return true;
-    }
-    if (!super.equals(obj)) {
-      return false;
-    }
-    if (!(obj instanceof AbstractClientEntitySet)) {
-      return false;
-    }
-    AbstractClientEntitySet other = (AbstractClientEntitySet) obj;
-    if (count == null) {
-      if (other.count != null) {
-        return false;
-      }
-    } else if (!count.equals(other.count)) {
-      return false;
-    }
-    if (next == null) {
-      if (other.next != null) {
-        return false;
-      }
-    } else if (!next.equals(other.next)) {
-      return false;
-    }
-    return true;
-  }
-
-  @Override
-  public String toString() {
-    return "AbstractClientEntitySet [next=" + next + ", count=" + count + "super[" + super.toString() + "]]";
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientCollectionValueImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientCollectionValueImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientCollectionValueImpl.java
index c83fceb..2a3aebc 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientCollectionValueImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientCollectionValueImpl.java
@@ -29,7 +29,7 @@ import org.apache.olingo.client.api.domain.ClientEnumValue;
 import org.apache.olingo.client.api.domain.ClientValue;
 
 public class ClientCollectionValueImpl<OV extends ClientValue> extends AbstractClientValue
-        implements ClientCollectionValue<OV>, ClientValue {
+        implements ClientCollectionValue<OV> {
 
   /**
    * Constructor.

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientEntitySetImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientEntitySetImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientEntitySetImpl.java
index 29ede4c..21e13b4 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientEntitySetImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientEntitySetImpl.java
@@ -22,11 +22,24 @@ import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.olingo.client.api.domain.AbstractClientPayload;
 import org.apache.olingo.client.api.domain.ClientAnnotation;
 import org.apache.olingo.client.api.domain.ClientEntity;
 import org.apache.olingo.client.api.domain.ClientEntitySet;
 
-public class ClientEntitySetImpl extends AbstractClientEntitySet implements ClientEntitySet {
+public class ClientEntitySetImpl extends AbstractClientPayload implements ClientEntitySet {
+
+  /**
+   * Link to the next page.
+   */
+  private final URI next;
+
+  /**
+   * Number of ODataEntities contained in this entity set.
+   * <br/>
+   * If <tt>$count</tt> was requested, this value comes from there.
+   */
+  private Integer count;
 
   private URI deltaLink;
 
@@ -35,11 +48,28 @@ public class ClientEntitySetImpl extends AbstractClientEntitySet implements Clie
   private final List<ClientAnnotation> annotations = new ArrayList<ClientAnnotation>();
 
   public ClientEntitySetImpl() {
-    super();
+    super(null);
+    next = null;
   }
 
   public ClientEntitySetImpl(final URI next) {
-    super(next);
+    super(null);
+    this.next = next;
+  }
+
+  @Override
+  public URI getNext() {
+    return next;
+  }
+
+  @Override
+  public Integer getCount() {
+    return count;
+  }
+
+  @Override
+  public void setCount(final int count) {
+    this.count = count;
   }
 
   @Override
@@ -66,6 +96,8 @@ public class ClientEntitySetImpl extends AbstractClientEntitySet implements Clie
   public int hashCode() {
     final int prime = 31;
     int result = super.hashCode();
+    result = prime * result + ((count == null) ? 0 : count.hashCode());
+    result = prime * result + ((next == null) ? 0 : next.hashCode());
     result = prime * result + ((annotations == null) ? 0 : annotations.hashCode());
     result = prime * result + ((deltaLink == null) ? 0 : deltaLink.hashCode());
     result = prime * result + ((entities == null) ? 0 : entities.hashCode());
@@ -77,40 +109,20 @@ public class ClientEntitySetImpl extends AbstractClientEntitySet implements Clie
     if (this == obj) {
       return true;
     }
-    if (!super.equals(obj)) {
-      return false;
-    }
-    if (!(obj instanceof ClientEntitySetImpl)) {
-      return false;
-    }
-    ClientEntitySetImpl other = (ClientEntitySetImpl) obj;
-    if (annotations == null) {
-      if (other.annotations != null) {
-        return false;
-      }
-    } else if (!annotations.equals(other.annotations)) {
-      return false;
-    }
-    if (deltaLink == null) {
-      if (other.deltaLink != null) {
-        return false;
-      }
-    } else if (!deltaLink.equals(other.deltaLink)) {
-      return false;
-    }
-    if (entities == null) {
-      if (other.entities != null) {
-        return false;
-      }
-    } else if (!entities.equals(other.entities)) {
+    if (obj == null || !(obj instanceof ClientEntitySetImpl)) {
       return false;
     }
-    return true;
+    final ClientEntitySetImpl other = (ClientEntitySetImpl) obj;
+    return (count == null ? other.count == null : count.equals(other.count))
+        && (next == null ? other.next == null : next.equals(other.next))
+        && annotations.equals(other.annotations)
+        && (deltaLink == null ? other.deltaLink == null : deltaLink.equals(other.deltaLink))
+        && entities.equals(other.entities);
   }
 
   @Override
   public String toString() {
     return "ClientEntitySetImpl [deltaLink=" + deltaLink + ", entities=" + entities + ", annotations=" + annotations
-        + "super[" + super.toString() + "]]";
+        + ", next=" + next + ", count=" + count + "super[" + super.toString() + "]]";
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java
index cdfe623..4824632 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java
@@ -21,11 +21,10 @@ package org.apache.olingo.client.core.domain;
 import java.math.BigDecimal;
 import java.util.UUID;
 
-import org.apache.olingo.commons.api.Constants;
 import org.apache.olingo.client.api.domain.AbstractClientValue;
 import org.apache.olingo.client.api.domain.ClientEnumValue;
 import org.apache.olingo.client.api.domain.ClientPrimitiveValue;
-import org.apache.olingo.client.api.domain.ClientValue;
+import org.apache.olingo.commons.api.Constants;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
@@ -33,7 +32,7 @@ import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
 import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
 
-public class ClientPrimitiveValueImpl extends AbstractClientValue implements ClientValue, ClientPrimitiveValue {
+public class ClientPrimitiveValueImpl extends AbstractClientValue implements ClientPrimitiveValue {
 
   public static class BuilderImpl implements Builder {
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPropertyImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPropertyImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPropertyImpl.java
index f78c506..8c8c3ee 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPropertyImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPropertyImpl.java
@@ -18,30 +18,21 @@
  */
 package org.apache.olingo.client.core.domain;
 
-import org.apache.olingo.client.api.domain.ClientAnnotatable;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.olingo.client.api.domain.ClientAnnotation;
-import org.apache.olingo.client.api.domain.ClientCollectionValue;
-import org.apache.olingo.client.api.domain.ClientComplexValue;
-import org.apache.olingo.client.api.domain.ClientEnumValue;
-import org.apache.olingo.client.api.domain.ClientPrimitiveValue;
 import org.apache.olingo.client.api.domain.ClientProperty;
-import org.apache.olingo.client.api.domain.ClientValuable;
 import org.apache.olingo.client.api.domain.ClientValue;
 
-import java.util.ArrayList;
-import java.util.List;
-
-public final class ClientPropertyImpl implements ClientProperty, ClientAnnotatable, ClientValuable {
+public final class ClientPropertyImpl extends ClientValuableImpl implements ClientProperty {
 
   private final List<ClientAnnotation> annotations = new ArrayList<ClientAnnotation>();
   private final String name;
-  private final ClientValue value;
-  private final ClientValuable valuable;
 
   public ClientPropertyImpl(final String name, final ClientValue value) {
+    super(value);
     this.name = name;
-    this.value = value;
-    this.valuable = new ClientValuableImpl(value);
   }
 
   /**
@@ -55,16 +46,6 @@ public final class ClientPropertyImpl implements ClientProperty, ClientAnnotatab
   }
 
   /**
-   * Returns property value.
-   *
-   * @return property value.
-   */
-  @Override
-  public ClientValue getValue() {
-    return value;
-  }
-
-  /**
    * Checks if has null value.
    *
    * @return 'TRUE' if has null value; 'FALSE' otherwise.
@@ -74,87 +55,18 @@ public final class ClientPropertyImpl implements ClientProperty, ClientAnnotatab
     return value == null || value.isPrimitive() && value.asPrimitive().toValue() == null;
   }
 
-  /**
-   * Checks if has primitive value.
-   *
-   * @return 'TRUE' if has primitive value; 'FALSE' otherwise.
-   */
-  @Override
-  public boolean hasPrimitiveValue() {
-    return !hasNullValue() && value.isPrimitive();
-  }
-
-  /**
-   * Gets primitive value.
-   *
-   * @return primitive value if exists; null otherwise.
-   */
-  @Override
-  public ClientPrimitiveValue getPrimitiveValue() {
-    return hasPrimitiveValue() ? value.asPrimitive() : null;
-  }
-
-  /**
-   * Checks if has complex value.
-   *
-   * @return 'TRUE' if has complex value; 'FALSE' otherwise.
-   */
-  @Override
-  public boolean hasComplexValue() {
-    return !hasNullValue() && value.isComplex();
-  }
-
-  /**
-   * Checks if has collection value.
-   *
-   * @return 'TRUE' if has collection value; 'FALSE' otherwise.
-   */
-  @Override
-  public boolean hasCollectionValue() {
-    return !hasNullValue() && value.isCollection();
-  }
-
   @Override
   public boolean equals(Object obj) {
     if (this == obj) {
       return true;
     }
-    if (obj == null) {
-      return false;
-    }
-    if (!(obj instanceof ClientPropertyImpl)) {
-      return false;
-    }
-    ClientPropertyImpl other = (ClientPropertyImpl) obj;
-    if (annotations == null) {
-      if (other.annotations != null) {
-        return false;
-      }
-    } else if (!annotations.equals(other.annotations)) {
-      return false;
-    }
-    if (name == null) {
-      if (other.name != null) {
-        return false;
-      }
-    } else if (!name.equals(other.name)) {
-      return false;
-    }
-    if (valuable == null) {
-      if (other.valuable != null) {
-        return false;
-      }
-    } else if (!valuable.equals(other.valuable)) {
+    if (obj == null || !(obj instanceof ClientPropertyImpl)) {
       return false;
     }
-    if (value == null) {
-      if (other.value != null) {
-        return false;
-      }
-    } else if (!value.equals(other.value)) {
-      return false;
-    }
-    return true;
+    final ClientPropertyImpl other = (ClientPropertyImpl) obj;
+    return annotations.equals(other.annotations)
+        && (name == null ? other.name == null : name.equals(other.name))
+        && (value == null ? other.value == null : value.equals(other.value));
   }
 
   @Override
@@ -163,42 +75,17 @@ public final class ClientPropertyImpl implements ClientProperty, ClientAnnotatab
     int result = 1;
     result = prime * result + ((annotations == null) ? 0 : annotations.hashCode());
     result = prime * result + ((name == null) ? 0 : name.hashCode());
-    result = prime * result + ((valuable == null) ? 0 : valuable.hashCode());
     result = prime * result + ((value == null) ? 0 : value.hashCode());
     return result;
   }
 
   @Override
-  public boolean hasEnumValue() {
-    return valuable.hasEnumValue();
-  }
-
-  @Override
-  public ClientEnumValue getEnumValue() {
-    return valuable.getEnumValue();
-  }
-
-  @Override
-  public ClientComplexValue getComplexValue() {
-    return valuable.getComplexValue();
-  }
-
-  @Override
-  public ClientCollectionValue<ClientValue> getCollectionValue() {
-    return valuable.getCollectionValue();
-  }
-
-  @Override
   public List<ClientAnnotation> getAnnotations() {
     return annotations;
   }
 
   @Override
   public String toString() {
-    return "ODataPropertyImpl{"
-        + "name=" + getName()
-        + ",valuable=" + valuable
-        + ", annotations=" + annotations
-        + '}';
+    return "ClientPropertyImpl{" + "name=" + name + ", value=" + value + ", annotations=" + annotations + '}';
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientValuableImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientValuableImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientValuableImpl.java
index 4a032ce..4b94be6 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientValuableImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientValuableImpl.java
@@ -25,9 +25,9 @@ import org.apache.olingo.client.api.domain.ClientPrimitiveValue;
 import org.apache.olingo.client.api.domain.ClientValuable;
 import org.apache.olingo.client.api.domain.ClientValue;
 
-public final class ClientValuableImpl implements ClientValuable {
+public class ClientValuableImpl implements ClientValuable {
 
-  private final ClientValue value;
+  protected final ClientValue value;
 
   public ClientValuableImpl(final ClientValue value) {
     this.value = value;
@@ -60,9 +60,7 @@ public final class ClientValuableImpl implements ClientValuable {
 
   @Override
   public ClientCollectionValue<ClientValue> getCollectionValue() {
-    return hasCollectionValue()
-        ? getValue().<ClientValue> asCollection()
-        : null;
+    return hasCollectionValue() ? getValue().<ClientValue> asCollection() : null;
   }
 
   @Override
@@ -72,9 +70,7 @@ public final class ClientValuableImpl implements ClientValuable {
 
   @Override
   public ClientComplexValue getComplexValue() {
-    return hasComplexValue()
-        ? getValue().asComplex()
-        : null;
+    return hasComplexValue() ? getValue().asComplex() : null;
   }
 
   @Override
@@ -84,9 +80,7 @@ public final class ClientValuableImpl implements ClientValuable {
 
   @Override
   public ClientEnumValue getEnumValue() {
-    return hasEnumValue()
-        ? getValue().asEnum()
-        : null;
+    return hasEnumValue() ? getValue().asEnum() : null;
   }
 
   @Override
@@ -99,9 +93,7 @@ public final class ClientValuableImpl implements ClientValuable {
     }
 
     ClientValuableImpl that = (ClientValuableImpl) o;
-
     return !(value != null ? !value.equals(that.value) : that.value != null);
-
   }
 
   @Override
@@ -111,8 +103,6 @@ public final class ClientValuableImpl implements ClientValuable {
 
   @Override
   public String toString() {
-    return "ClientValuableImpl{" +
-        "value=" + value +
-        '}';
+    return "ClientValuableImpl{" + "value=" + value + '}';
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java
index 33144ec..f9f29e7 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java
@@ -714,7 +714,7 @@ public class ODataBinderImpl implements ODataBinder {
       if (propertyType == null || propertyType.equals(EdmPrimitiveTypeKind.String.getFullQualifiedName().toString())) {
         typeInfo = new EdmTypeInfo.Builder().setTypeExpression(typeName.toString()).build();
       } else if(isPrimiteveType(typeName)) {
-        // Inheritance is not allowed for primitve types, so we use the type given by the EDM
+        // Inheritance is not allowed for primitive types, so we use the type given by the EDM.
         typeInfo = new EdmTypeInfo.Builder().setTypeExpression(typeName.toString()).build();
       } else {
         typeInfo = new EdmTypeInfo.Builder().setTypeExpression(propertyType).build();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractTest.java
index bc116a8..d03b6d9 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/AbstractTest.java
@@ -25,9 +25,7 @@ import org.junit.BeforeClass;
 
 public abstract class AbstractTest {
 
-  protected static ODataClient v4Client;
-
-  protected abstract ODataClient getClient();
+  protected static final ODataClient client = ODataClientFactory.getClient();
 
   @BeforeClass
   public static void setUp() {
@@ -38,11 +36,6 @@ public abstract class AbstractTest {
     XMLUnit.setCompareUnmatched(false);
   }
 
-  @BeforeClass
-  public static void setClientInstances() {
-    v4Client = ODataClientFactory.getClient();
-  }
-
   protected String getSuffix(final ContentType contentType) {
     return contentType.isCompatible(ContentType.APPLICATION_ATOM_SVC)
         || contentType.isCompatible(ContentType.APPLICATION_ATOM_XML)

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java
index 9d5346b..ba20144 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java
@@ -30,18 +30,12 @@ import javax.xml.transform.stream.StreamResult;
 import javax.xml.transform.stream.StreamSource;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.custommonkey.xmlunit.Diff;
 
 public class AtomTest extends JSONTest {
 
   @Override
-  protected ODataClient getClient() {
-    return v4Client;
-  }
-
-  @Override
   protected ContentType getODataPubFormat() {
     return ContentType.APPLICATION_ATOM_XML;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/lib/client-core/src/test/java/org/apache/olingo/client/core/EntitySetTest.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/EntitySetTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/EntitySetTest.java
index 199cd05..254e83f 100644
--- a/lib/client-core/src/test/java/org/apache/olingo/client/core/EntitySetTest.java
+++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/EntitySetTest.java
@@ -26,7 +26,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
 
-import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.data.ResWrap;
 import org.apache.olingo.client.api.domain.ClientEntity;
 import org.apache.olingo.client.api.domain.ClientEntitySet;
@@ -37,23 +36,18 @@ import org.junit.Test;
 
 public class EntitySetTest extends AbstractTest {
 
-  @Override
-  protected ODataClient getClient() {
-    return v4Client;
-  }
-
   private void read(final ContentType contentType) throws IOException, ODataDeserializerException {
     final InputStream input = getClass().getResourceAsStream("Customers." + getSuffix(contentType));
-    final ClientEntitySet entitySet = getClient().getBinder().getODataEntitySet(
-        getClient().getDeserializer(contentType).toEntitySet(input));
+    final ClientEntitySet entitySet = client.getBinder().getODataEntitySet(
+        client.getDeserializer(contentType).toEntitySet(input));
     assertNotNull(entitySet);
 
     assertEquals(2, entitySet.getEntities().size());
     assertNull(entitySet.getNext());
 
     final ClientEntitySet written =
-        getClient().getBinder().getODataEntitySet(new ResWrap<EntityCollection>((URI) null, null,
-            getClient().getBinder().getEntitySet(entitySet)));
+        client.getBinder().getODataEntitySet(new ResWrap<EntityCollection>((URI) null, null,
+            client.getBinder().getEntitySet(entitySet)));
     assertEquals(entitySet, written);
   }
 
@@ -69,8 +63,8 @@ public class EntitySetTest extends AbstractTest {
 
   private void ref(final ContentType contentType) throws ODataDeserializerException {
     final InputStream input = getClass().getResourceAsStream("collectionOfEntityReferences." + getSuffix(contentType));
-    final ClientEntitySet entitySet = getClient().getBinder().getODataEntitySet(
-        getClient().getDeserializer(contentType).toEntitySet(input));
+    final ClientEntitySet entitySet = client.getBinder().getODataEntitySet(
+        client.getDeserializer(contentType).toEntitySet(input));
     assertNotNull(entitySet);
 
     for (ClientEntity entity : entitySet.getEntities()) {
@@ -79,8 +73,8 @@ public class EntitySetTest extends AbstractTest {
     entitySet.setCount(entitySet.getEntities().size());
 
     final ClientEntitySet written =
-        getClient().getBinder().getODataEntitySet(new ResWrap<EntityCollection>((URI) null, null,
-            getClient().getBinder().getEntitySet(entitySet)));
+        client.getBinder().getODataEntitySet(new ResWrap<EntityCollection>((URI) null, null,
+            client.getBinder().getEntitySet(entitySet)));
     assertEquals(entitySet, written);
   }
 


[5/7] olingo-odata4 git commit: [OLINGO-852] less warnings + general clean-up

Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/Services.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/Services.java b/fit/src/main/java/org/apache/olingo/fit/Services.java
index 45f11a5..698938e 100644
--- a/fit/src/main/java/org/apache/olingo/fit/Services.java
+++ b/fit/src/main/java/org/apache/olingo/fit/Services.java
@@ -25,15 +25,22 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStreamWriter;
 import java.net.URI;
+import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.ConcurrentModificationException;
+import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.UUID;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import javax.mail.Header;
 import javax.mail.internet.MimeBodyPart;
 import javax.mail.internet.MimeMultipart;
 import javax.ws.rs.BadRequestException;
@@ -51,6 +58,8 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriInfo;
@@ -59,63 +68,140 @@ import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.cxf.interceptor.InInterceptors;
+import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.cxf.jaxrs.ext.multipart.Attachment;
 import org.apache.cxf.jaxrs.ext.multipart.Multipart;
 import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
 import org.apache.olingo.client.api.data.ResWrap;
+import org.apache.olingo.client.api.serialization.ODataDeserializer;
+import org.apache.olingo.client.api.serialization.ODataSerializer;
+import org.apache.olingo.client.core.serialization.AtomSerializer;
+import org.apache.olingo.client.core.serialization.JsonDeserializer;
+import org.apache.olingo.client.core.serialization.JsonSerializer;
+import org.apache.olingo.commons.api.data.ComplexValue;
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntityCollection;
 import org.apache.olingo.commons.api.data.Link;
 import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.data.ValueType;
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
+import org.apache.olingo.fit.metadata.EntityType;
 import org.apache.olingo.fit.metadata.Metadata;
+import org.apache.olingo.fit.metadata.NavigationProperty;
 import org.apache.olingo.fit.methods.PATCH;
 import org.apache.olingo.fit.rest.ResolvingReferencesInterceptor;
 import org.apache.olingo.fit.rest.XHTTPMethodInterceptor;
+import org.apache.olingo.fit.serializer.FITAtomDeserializer;
 import org.apache.olingo.fit.utils.AbstractUtilities;
 import org.apache.olingo.fit.utils.Accept;
 import org.apache.olingo.fit.utils.Commons;
 import org.apache.olingo.fit.utils.ConstantKey;
 import org.apache.olingo.fit.utils.Constants;
 import org.apache.olingo.fit.utils.FSManager;
+import org.apache.olingo.fit.utils.JSONUtilities;
 import org.apache.olingo.fit.utils.LinkInfo;
+import org.apache.olingo.fit.utils.XMLUtilities;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
 @Service
 @Path("/V40/Static.svc")
 @InInterceptors(classes = { XHTTPMethodInterceptor.class, ResolvingReferencesInterceptor.class })
-public class Services extends AbstractServices {
+public class Services {
 
   /**
-   * CR/LF.
+   * Logger.
    */
-  protected static final byte[] CRLF = { 13, 10 };
-
-  protected static final Pattern RELENTITY_SELECT_PATTERN = Pattern.compile("^.*\\(\\$select=.*\\)$");
+  protected static final Logger LOG = LoggerFactory.getLogger(Services.class);
 
-  protected static final Pattern CROSSJOIN_PATTERN = Pattern.compile(
+  private static final Pattern REQUEST_PATTERN = Pattern.compile("(.*) (http://.*) HTTP/.*");
+  private static final Pattern BATCH_REQUEST_REF_PATTERN = Pattern.compile("(.*) ([$]\\d+)(.*) HTTP/.*");
+  private static final Pattern REF_PATTERN = Pattern.compile("([$]\\d+)");
+  private static final Pattern RELENTITY_SELECT_PATTERN = Pattern.compile("^.*\\(\\$select=.*\\)$");
+  private static final Pattern CROSSJOIN_PATTERN = Pattern.compile(
       "^\\$crossjoin\\(.*\\)\\?\\$filter=\\([a-zA-Z/]+ eq [a-zA-Z/]+\\)$");
+  protected static final String BOUNDARY = "batch_243234_25424_ef_892u748";
+  protected static final String MULTIPART_MIXED = "multipart/mixed";
+  protected static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
 
   private final Map<String, String> providedAsync = new HashMap<String, String>();
 
+  protected final ODataDeserializer atomDeserializer = new FITAtomDeserializer();
+  protected final ODataDeserializer jsonDeserializer = new JsonDeserializer(true);
+  protected final ODataSerializer atomSerializer = new AtomSerializer(true);
+  protected final ODataSerializer jsonSerializer = new JsonSerializer(true, ContentType.JSON_FULL_METADATA);
+
+  protected final Metadata metadata;
+  protected final XMLUtilities xml;
+  protected final JSONUtilities json;
+
   public Services() throws IOException {
-    super(ODataServiceVersion.V40, Commons.getMetadata(ODataServiceVersion.V40));
+    this(Commons.getMetadata());
   }
 
   protected Services(final Metadata metadata) throws IOException {
-    super(ODataServiceVersion.V40, metadata);
+    this.metadata = metadata;
+    xml = new XMLUtilities(metadata);
+    json = new JSONUtilities(metadata);
+  }
+
+  /**
+   * Provide sample services.
+   *
+   * @param accept Accept header.
+   * @return OData services.
+   */
+  @GET
+  public Response getServices(@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept) {
+    try {
+      final Accept acceptType = Accept.parse(accept);
+
+      if (acceptType == Accept.ATOM) {
+        throw new UnsupportedMediaTypeException("Unsupported media type");
+      }
+
+      return xml.createResponse(
+          null,
+          FSManager.instance().readFile(Constants.get(ConstantKey.SERVICES), acceptType),
+          null, acceptType);
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  /**
+   * Provide sample getMetadata().
+   *
+   * @return getMetadata().
+   */
+  @GET
+  @Path("/$metadata")
+  @Produces(MediaType.APPLICATION_XML)
+  public Response getMetadata() {
+    return getMetadata(Constants.get(ConstantKey.METADATA));
+  }
+
+  protected Response getMetadata(final String filename) {
+    try {
+      return xml.createResponse(null, FSManager.instance().readRes(filename, Accept.XML), null, Accept.XML);
+    } catch (Exception e) {
+      return xml.createFaultResponse(Accept.XML.toString(), e);
+    }
   }
 
   @GET
   @Path("/redirect/{name}({id})")
-  public Response conformanceRedirect(
-      @Context final UriInfo uriInfo,
-      @PathParam("name") final String name,
-      @PathParam("id") final String id) {
+  public Response conformanceRedirect(@Context final UriInfo uriInfo) {
     return Response.temporaryRedirect(
         URI.create(uriInfo.getRequestUri().toASCIIString().replace("/redirect", ""))).build();
   }
@@ -128,7 +214,7 @@ public class Services extends AbstractServices {
 
     try {
       if (CROSSJOIN_PATTERN.matcher("$crossjoin(" + elements + ")?$filter=" + filter).matches()) {
-        final InputStream feed = FSManager.instance(version).readFile("crossjoin", Accept.JSON);
+        final InputStream feed = FSManager.instance().readFile("crossjoin", Accept.JSON);
 
         return xml.createResponse(feed, null, Accept.JSON_FULLMETA);
       } else {
@@ -141,9 +227,7 @@ public class Services extends AbstractServices {
 
   @GET
   @Path("/relatedEntitySelect/{path:.*}")
-  public Response relatedEntitySelect(
-      @PathParam("path") final String path,
-      @QueryParam("$expand") final String expand) {
+  public Response relatedEntitySelect(@QueryParam("$expand") final String expand) {
 
     if (RELENTITY_SELECT_PATTERN.matcher(expand).matches()) {
       return xml.createResponse(null, null, Accept.JSON_FULLMETA);
@@ -177,7 +261,6 @@ public class Services extends AbstractServices {
   @PUT
   @Path("/People(1)/Parent")
   public Response changeSingleValuedNavigationPropertyReference(
-      @Context final UriInfo uriInfo,
       @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
       @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
       final String content) {
@@ -196,39 +279,95 @@ public class Services extends AbstractServices {
   }
 
   @POST
-  @Path("/async/$batch")
-  public Response async(
-      @Context final UriInfo uriInfo,
+  @Path("/$batch")
+  @Consumes(MULTIPART_MIXED)
+  @Produces(APPLICATION_OCTET_STREAM + ";boundary=" + BOUNDARY)
+  public Response batch(
       @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
       final @Multipart MultipartBody attachment) {
+    try {
+      final boolean continueOnError = prefer.contains("odata.continue-on-error");
+      return xml.createBatchResponse(
+          exploreMultipart(attachment.getAllAttachments(), BOUNDARY, continueOnError));
+    } catch (IOException e) {
+      return xml.createFaultResponse(Accept.XML.toString(), e);
+    }
+  }
+
+  // ----------------------------------------------
+  // just for non nullable property test into PropertyTestITCase
+  // ----------------------------------------------
+  @PATCH
+  @Path("/Driver('2')")
+  public Response patchDriver() {
+    return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(), new Exception("Non nullable properties"));
+  }
+
+  @GET
+  @Path("/StoredPIs(1000)")
+  public Response getStoredPI(@Context final UriInfo uriInfo) {
+    final Entity entity = new Entity();
+    entity.setType("Microsoft.Test.OData.Services.ODataWCFService.StoredPI");
+    final Property id = new Property();
+    id.setType("Edm.Int32");
+    id.setName("StoredPIID");
+    id.setValue(ValueType.PRIMITIVE, 1000);
+    entity.getProperties().add(id);
+    final Link edit = new Link();
+    edit.setHref(uriInfo.getRequestUri().toASCIIString());
+    edit.setRel("edit");
+    edit.setTitle("StoredPI");
+    entity.setEditLink(edit);
+
+    final ByteArrayOutputStream content = new ByteArrayOutputStream();
+    final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
+    try {
+      jsonSerializer.write(writer, new ResWrap<Entity>((URI) null, null, entity));
+      return xml.createResponse(new ByteArrayInputStream(content.toByteArray()), null, Accept.JSON_FULLMETA);
+    } catch (Exception e) {
+      LOG.error("While creating StoredPI", e);
+      return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(), e);
+    }
+  }
+
+  @PATCH
+  @Path("/StoredPIs(1000)")
+  public Response patchStoredPI() {
+    // just for non nullable property test into PropertyTestITCase
+    return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(), new Exception("Non nullable properties"));
+  }
+
+  @POST
+  @Path("/async/$batch")
+  public Response async(@Context final UriInfo uriInfo) {
 
     try {
       final ByteArrayOutputStream bos = new ByteArrayOutputStream();
       bos.write("HTTP/1.1 200 Ok".getBytes());
-      bos.write(CRLF);
+      bos.write(Constants.CRLF);
       bos.write("OData-Version: 4.0".getBytes());
-      bos.write(CRLF);
+      bos.write(Constants.CRLF);
       bos.write(("Content-Type: " + ContentType.APPLICATION_OCTET_STREAM + ";boundary=" + BOUNDARY).getBytes());
-      bos.write(CRLF);
-      bos.write(CRLF);
+      bos.write(Constants.CRLF);
+      bos.write(Constants.CRLF);
 
       bos.write(("--" + BOUNDARY).getBytes());
-      bos.write(CRLF);
+      bos.write(Constants.CRLF);
       bos.write("Content-Type: application/http".getBytes());
-      bos.write(CRLF);
+      bos.write(Constants.CRLF);
       bos.write("Content-Transfer-Encoding: binary".getBytes());
-      bos.write(CRLF);
-      bos.write(CRLF);
+      bos.write(Constants.CRLF);
+      bos.write(Constants.CRLF);
 
       bos.write("HTTP/1.1 202 Accepted".getBytes());
-      bos.write(CRLF);
+      bos.write(Constants.CRLF);
       bos.write("Location: http://service-root/async-monitor".getBytes());
-      bos.write(CRLF);
+      bos.write(Constants.CRLF);
       bos.write("Retry-After: 10".getBytes());
-      bos.write(CRLF);
-      bos.write(CRLF);
+      bos.write(Constants.CRLF);
+      bos.write(Constants.CRLF);
       bos.write(("--" + BOUNDARY + "--").getBytes());
-      bos.write(CRLF);
+      bos.write(Constants.CRLF);
 
       final UUID uuid = UUID.randomUUID();
       providedAsync.put(uuid.toString(), bos.toString(Constants.ENCODING.toString()));
@@ -263,11 +402,13 @@ public class Services extends AbstractServices {
           ? Constants.get(ConstantKey.ENTITY)
           : Constants.get(ConstantKey.FEED));
 
-      final InputStream feed = FSManager.instance(version).readFile(path.toString(), acceptType);
+      final InputStream feed = FSManager.instance().readFile(path.toString(), acceptType);
 
       final StringBuilder builder = new StringBuilder();
-      builder.append("HTTP/1.1 200 Ok").append(new String(CRLF));
-      builder.append("Content-Type: ").append(accept).append(new String(CRLF)).append(new String(CRLF));
+      builder.append("HTTP/1.1 200 Ok").append(new String(Constants.CRLF));
+      builder.append("Content-Type: ").append(accept)
+          .append(new String(Constants.CRLF))
+          .append(new String(Constants.CRLF));
       builder.append(IOUtils.toString(feed));
       IOUtils.closeQuietly(feed);
 
@@ -281,15 +422,80 @@ public class Services extends AbstractServices {
     }
   }
 
-  @Override
-  protected void setInlineCount(final EntityCollection entitySet, final String count) {
+  private void setInlineCount(final EntityCollection entitySet, final String count) {
     if ("true".equals(count)) {
       entitySet.setCount(entitySet.getEntities().size());
     }
   }
 
-  @Override
-  public InputStream exploreMultipart(
+  private Response bodyPartRequest(final MimeBodyPart body, final Map<String, String> references) throws Exception {
+    @SuppressWarnings("unchecked")
+    final Enumeration<Header> en = body.getAllHeaders();
+
+    Header header = en.nextElement();
+    final String request =
+        header.getName() + (StringUtils.isNotBlank(header.getValue()) ? ":" + header.getValue() : "");
+
+    final Matcher matcher = REQUEST_PATTERN.matcher(request);
+    final Matcher matcherRef = BATCH_REQUEST_REF_PATTERN.matcher(request);
+
+    final MultivaluedMap<String, String> headers = new MultivaluedHashMap<String, String>();
+
+    while (en.hasMoreElements()) {
+      header = en.nextElement();
+      headers.putSingle(header.getName(), header.getValue());
+    }
+
+    final Response res;
+    final String url;
+    final String method;
+
+    if (matcher.find()) {
+      url = matcher.group(2);
+      method = matcher.group(1);
+    } else if (matcherRef.find()) {
+      url = references.get(matcherRef.group(2)) + matcherRef.group(3);
+      method = matcherRef.group(1);
+    } else {
+      url = null;
+      method = null;
+    }
+
+    if (url == null) {
+      res = null;
+    } else {
+      final WebClient client = WebClient.create(url, "odatajclient", "odatajclient", null);
+      client.headers(headers);
+
+      if ("DELETE".equals(method)) {
+        res = client.delete();
+      } else {
+        final InputStream is = body.getDataHandler().getInputStream();
+        String content = IOUtils.toString(is);
+        IOUtils.closeQuietly(is);
+
+        final Matcher refs = REF_PATTERN.matcher(content);
+
+        while (refs.find()) {
+          content = content.replace(refs.group(1), references.get(refs.group(1)));
+        }
+
+        if ("PATCH".equals(method) || "MERGE".equals(method)) {
+          client.header("X-HTTP-METHOD", method);
+          res = client.invoke("POST", IOUtils.toInputStream(content));
+        } else {
+          res = client.invoke(method, IOUtils.toInputStream(content));
+        }
+      }
+
+      // When updating to CXF 3.0.1, uncomment the following line, see CXF-5865
+      // client.close();
+    }
+
+    return res;
+  }
+
+  private InputStream exploreMultipart(
       final List<Attachment> attachments, final String boundary, final boolean continueOnError)
       throws IOException {
 
@@ -349,9 +555,10 @@ public class Services extends AbstractServices {
             goon = continueOnError;
           }
         } else {
-          addItemIntro(bos);
+          addItemIntro(bos, null);
 
-          res = bodyPartRequest(new MimeBodyPart(obj.getDataHandler().getInputStream()));
+          res = bodyPartRequest(new MimeBodyPart(obj.getDataHandler().getInputStream()),
+              Collections.<String, String> emptyMap());
 
           if (res.getStatus() >= 400) {
             goon = continueOnError;
@@ -374,121 +581,131 @@ public class Services extends AbstractServices {
     return new ByteArrayInputStream(bos.toByteArray());
   }
 
-  @GET
-  @Path("/People/{type:.*}")
-  public Response getPeople(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("type") final String type,
-      @QueryParam("$top") @DefaultValue(StringUtils.EMPTY) final String top,
-      @QueryParam("$skip") @DefaultValue(StringUtils.EMPTY) final String skip,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
-      @QueryParam("$count") @DefaultValue(StringUtils.EMPTY) final String count,
-      @QueryParam("$filter") @DefaultValue(StringUtils.EMPTY) final String filter,
-      @QueryParam("$search") @DefaultValue(StringUtils.EMPTY) final String search,
-      @QueryParam("$orderby") @DefaultValue(StringUtils.EMPTY) final String orderby,
-      @QueryParam("$skiptoken") @DefaultValue(StringUtils.EMPTY) final String skiptoken) {
+  private void addItemIntro(final ByteArrayOutputStream bos, final String contentId) throws IOException {
+    bos.write("Content-Type: application/http".getBytes());
+    bos.write(Constants.CRLF);
+    bos.write("Content-Transfer-Encoding: binary".getBytes());
+    bos.write(Constants.CRLF);
 
-    return StringUtils.isBlank(filter) && StringUtils.isBlank(search)
-        ? NumberUtils.isNumber(type)
-            ? super.getEntityInternal(
-                uriInfo.getRequestUri().toASCIIString(), accept, "People", type, format, null, null)
-            : super.getEntitySet(accept, "People", type)
-        : super.getEntitySet(uriInfo, accept, "People", top, skip, format, count, filter, orderby, skiptoken, type);
+    if (StringUtils.isNotBlank(contentId)) {
+      bos.write(("Content-ID: " + contentId).getBytes());
+      bos.write(Constants.CRLF);
+    }
+
+    bos.write(Constants.CRLF);
   }
 
-  @GET
-  @Path("/Boss")
-  public Response getSingletonBoss(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+  private void addChangesetItemIntro(
+      final ByteArrayOutputStream bos, final String contentId, final String cboundary) throws IOException {
+    bos.write(("--" + cboundary).getBytes());
+    bos.write(Constants.CRLF);
+    bos.write(("Content-ID: " + contentId).getBytes());
+    bos.write(Constants.CRLF);
+    addItemIntro(bos, null);
+  }
 
-    return getEntityInternal(
-        uriInfo.getRequestUri().toASCIIString(), accept, "Boss", StringUtils.EMPTY, format, null, null);
+  private void addSingleBatchResponse(
+      final Response response, final ByteArrayOutputStream bos) throws IOException {
+    addSingleBatchResponse(response, null, bos);
   }
 
-  @GET
-  @Path("/Company")
-  public Response getSingletonCompany(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+  private void addSingleBatchResponse(
+      final Response response, final String contentId, final ByteArrayOutputStream bos) throws IOException {
+    bos.write("HTTP/1.1 ".getBytes());
+    bos.write(String.valueOf(response.getStatusInfo().getStatusCode()).getBytes());
+    bos.write(" ".getBytes());
+    bos.write(response.getStatusInfo().getReasonPhrase().getBytes());
+    bos.write(Constants.CRLF);
 
-    return getEntityInternal(
-        uriInfo.getRequestUri().toASCIIString(), accept, "Company", StringUtils.EMPTY, format, null, null);
+    for (Map.Entry<String, List<Object>> header : response.getHeaders().entrySet()) {
+      final StringBuilder builder = new StringBuilder();
+      for (Object value : header.getValue()) {
+        if (builder.length() > 0) {
+          builder.append(", ");
+        }
+        builder.append(value.toString());
+      }
+      builder.insert(0, ": ").insert(0, header.getKey());
+      bos.write(builder.toString().getBytes());
+      bos.write(Constants.CRLF);
+    }
+
+    if (StringUtils.isNotBlank(contentId)) {
+      bos.write(("Content-ID: " + contentId).getBytes());
+      bos.write(Constants.CRLF);
+    }
+
+    bos.write(Constants.CRLF);
+
+    final Object entity = response.getEntity();
+    if (entity != null) {
+      bos.write(IOUtils.toByteArray((InputStream) entity));
+      bos.write(Constants.CRLF);
+    }
+
+    bos.write(Constants.CRLF);
   }
 
-  @PATCH
-  @Path("/Company")
-  @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
-  @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
-  public Response patchSingletonCompany(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
-      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
-      @HeaderParam("If-Match") @DefaultValue(StringUtils.EMPTY) final String ifMatch,
-      final String changes) {
+  protected void addErrorBatchResponse(final Exception e, final ByteArrayOutputStream bos)
+      throws IOException {
+    addErrorBatchResponse(e, null, bos);
+  }
 
-    return super.patchEntity(uriInfo, accept, contentType, prefer, ifMatch, "Company", StringUtils.EMPTY, changes);
+  protected void addErrorBatchResponse(final Exception e, final String contentId, final ByteArrayOutputStream bos)
+      throws IOException {
+    addSingleBatchResponse(xml.createFaultResponse(Accept.XML.toString(), e), contentId, bos);
   }
 
+  /**
+   * Retrieve entities from the given entity set and the given type.
+   *
+   * @param accept Accept header.
+   * @param name entity set.
+   * @param type entity type.
+   * @return entity set.
+   */
   @GET
-  @Path("/Customers")
-  public Response getCustomers(
-      @Context final UriInfo uriInfo,
+  @Path("/{name}/{type:[a-zA-Z].*}")
+  public Response getEntitySet(
       @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
-      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
-      @QueryParam("$deltatoken") @DefaultValue(StringUtils.EMPTY) final String deltatoken) {
+      @PathParam("name") final String name,
+      @PathParam("type") final String type) {
 
     try {
-      final Accept acceptType;
-      if (StringUtils.isNotBlank(format)) {
-        acceptType = Accept.valueOf(format.toUpperCase());
-      } else {
-        acceptType = Accept.parse(accept);
+      final Accept acceptType = Accept.parse(accept);
+      if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+        throw new UnsupportedMediaTypeException("Unsupported media type");
       }
 
-      final InputStream output;
-      if (StringUtils.isBlank(deltatoken)) {
-        final InputStream input = (InputStream) getEntitySet(
-            uriInfo, accept, "Customers", null, null, format, null, null, null, null).getEntity();
-        final EntityCollection entitySet = xml.readEntitySet(acceptType, input);
-
-        boolean trackChanges = prefer.contains("odata.track-changes");
-        if (trackChanges) {
-          entitySet.setDeltaLink(URI.create("Customers?$deltatoken=8015"));
-        }
+      final String basePath = name + File.separatorChar;
+      final StringBuilder path = new StringBuilder(name).
+          append(File.separatorChar).append(type).
+          append(File.separatorChar);
 
-        output = xml.writeEntitySet(acceptType, new ResWrap<EntityCollection>(
-            URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + "Customers"),
-            null,
-            entitySet));
-      } else {
-        output = FSManager.instance(version).readFile("delta", acceptType);
-      }
+      path.append(metadata.getEntitySet(name).isSingleton()
+          ? Constants.get(ConstantKey.ENTITY)
+              : Constants.get(ConstantKey.FEED));
 
-      final Response response = xml.createResponse(
-          null,
-          output,
-          null,
-          acceptType);
-      if (StringUtils.isNotBlank(prefer)) {
-        response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
-      }
-      return response;
+      final InputStream feed = FSManager.instance().readFile(path.toString(), acceptType);
+      return xml.createResponse(null, feed, Commons.getETag(basePath), acceptType);
     } catch (Exception e) {
       return xml.createFaultResponse(accept, e);
     }
   }
 
   @GET
-  @Path("/Company/Microsoft.Test.OData.Services.ODataWCFService.GetEmployeesCount{paren:[\\(\\)]*}")
-  public Response functionGetEmployeesCount(
+  @Path("/{name}/{type:[a-zA-Z].*}")
+  public Response getEntitySet(@Context final UriInfo uriInfo,
       @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+      @PathParam("name") final String name,
+      @QueryParam("$top") @DefaultValue(StringUtils.EMPTY) final String top,
+      @QueryParam("$skip") @DefaultValue(StringUtils.EMPTY) final String skip,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+      @QueryParam("$count") @DefaultValue(StringUtils.EMPTY) final String count,
+      @QueryParam("$filter") @DefaultValue(StringUtils.EMPTY) final String filter,
+      @QueryParam("$orderby") @DefaultValue(StringUtils.EMPTY) final String orderby,
+      @QueryParam("$skiptoken") @DefaultValue(StringUtils.EMPTY) final String skiptoken,
+      @PathParam("type") final String type) {
 
     try {
       final Accept acceptType;
@@ -498,111 +715,450 @@ public class Services extends AbstractServices {
         acceptType = Accept.parse(accept);
       }
 
-      final Property property = new Property();
-      property.setType("Edm.Int32");
-      property.setValue(ValueType.PRIMITIVE, 2);
-      final ResWrap<Property> container = new ResWrap<Property>(
-          URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + property.getType()), null,
-          property);
+      final String location = uriInfo.getRequestUri().toASCIIString();
+      try {
+        // search for function ...
+        final InputStream func = FSManager.instance().readFile(name, acceptType);
+        return xml.createResponse(location, func, null, acceptType);
+      } catch (NotFoundException e) {
+        if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+          throw new UnsupportedMediaTypeException("Unsupported media type");
+        }
 
-      return xml.createResponse(
-          null,
-          xml.writeProperty(acceptType, container),
-          null,
-          acceptType);
-    } catch (Exception e) {
-      return xml.createFaultResponse(accept, e);
-    }
-  }
+        // search for entitySet ...
+        final String basePath = name + File.separatorChar;
 
-  @POST
-  @Path("/Company/Microsoft.Test.OData.Services.ODataWCFService.IncreaseRevenue{paren:[\\(\\)]*}")
-  public Response actionIncreaseRevenue(
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
-      final String param) {
+        final StringBuilder builder = new StringBuilder();
+        builder.append(basePath);
 
-    try {
-      final Accept acceptType;
-      if (StringUtils.isNotBlank(format)) {
-        acceptType = Accept.valueOf(format.toUpperCase());
-      } else {
-        acceptType = Accept.parse(accept);
-      }
+        if (type != null) {
+          builder.append(type).append(File.separatorChar);
+        }
 
-      final Accept contentTypeValue = Accept.parse(contentType);
-      final Entity entry = xml.readEntity(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING));
+        if (StringUtils.isNotBlank(orderby)) {
+          builder.append(Constants.get(ConstantKey.ORDERBY)).append(File.separatorChar).
+          append(orderby).append(File.separatorChar);
+        }
 
-      return xml.createResponse(
-          null,
-          xml.writeProperty(acceptType, entry.getProperty("IncreaseValue")),
-          null,
-          acceptType);
+        if (StringUtils.isNotBlank(filter)) {
+          builder.append(Constants.get(ConstantKey.FILTER)).append(File.separatorChar).
+          append(filter.replaceAll("/", "."));
+        } else if (StringUtils.isNotBlank(skiptoken)) {
+          builder.append(Constants.get(ConstantKey.SKIP_TOKEN)).append(File.separatorChar).
+          append(skiptoken);
+        } else {
+          builder.append(metadata.getEntitySet(name).isSingleton()
+              ? Constants.get(ConstantKey.ENTITY)
+                  : Constants.get(ConstantKey.FEED));
+        }
+
+        final InputStream feed = FSManager.instance().readFile(builder.toString(), Accept.ATOM);
+
+        final ResWrap<EntityCollection> container = atomDeserializer.toEntitySet(feed);
+
+        setInlineCount(container.getPayload(), count);
+
+        final ByteArrayOutputStream content = new ByteArrayOutputStream();
+        final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
+
+        // -----------------------------------------------
+        // Evaluate $skip and $top
+        // -----------------------------------------------
+        List<Entity> entries = new ArrayList<Entity>(container.getPayload().getEntities());
+
+        if (StringUtils.isNotBlank(skip)) {
+          entries = entries.subList(Integer.valueOf(skip), entries.size());
+        }
+
+        if (StringUtils.isNotBlank(top)) {
+          entries = entries.subList(0, Integer.valueOf(top));
+        }
+
+        container.getPayload().getEntities().clear();
+        container.getPayload().getEntities().addAll(entries);
+        // -----------------------------------------------
+
+        if (acceptType == Accept.ATOM) {
+          atomSerializer.write(writer, container);
+        } else {
+          jsonSerializer.write(writer, container);
+        }
+        writer.flush();
+        writer.close();
+
+        return xml.createResponse(
+            location,
+            new ByteArrayInputStream(content.toByteArray()),
+            Commons.getETag(basePath),
+            acceptType);
+      }
     } catch (Exception e) {
       return xml.createFaultResponse(accept, e);
     }
   }
 
+  /**
+   * Retrieve entity set or function execution sample.
+   *
+   * @param accept Accept header.
+   * @param name entity set or function name.
+   * @param format format query option.
+   * @param count count query option.
+   * @param filter filter query option.
+   * @param orderby orderby query option.
+   * @param skiptoken skiptoken query option.
+   * @return entity set or function result.
+   */
   @GET
-  @Path("/Products({entityId})/Microsoft.Test.OData.Services.ODataWCFService.GetProductDetails({param:.*})")
-  public Response functionGetProductDetails(
+  @Path("/{name}")
+  public Response getEntitySet(
+      @Context final UriInfo uriInfo,
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("name") final String name,
+      @QueryParam("$top") @DefaultValue(StringUtils.EMPTY) final String top,
+      @QueryParam("$skip") @DefaultValue(StringUtils.EMPTY) final String skip,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+      @QueryParam("$count") @DefaultValue(StringUtils.EMPTY) final String count,
+      @QueryParam("$filter") @DefaultValue(StringUtils.EMPTY) final String filter,
+      @QueryParam("$orderby") @DefaultValue(StringUtils.EMPTY) final String orderby,
+      @QueryParam("$skiptoken") @DefaultValue(StringUtils.EMPTY) final String skiptoken) {
+
+    return getEntitySet(uriInfo, accept, name, top, skip, format, count, filter, orderby, skiptoken, null);
+  }
+
+  @GET
+  @Path("/Person({entityId})")
+  public Response getPerson(
+      @Context final UriInfo uriInfo,
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("entityId") final String entityId,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+    final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+    final Response internal = getEntityInternal(
+        uriInfo.getRequestUri().toASCIIString(), accept, "Person", entityId, format, null, null);
+    if (internal.getStatus() == 200) {
+      InputStream entity = (InputStream) internal.getEntity();
+      try {
+        if (utils.getKey() == Accept.JSON_FULLMETA || utils.getKey() == Accept.ATOM) {
+          entity = utils.getValue().addOperation(entity, "Sack", "#DefaultContainer.Sack",
+              uriInfo.getAbsolutePath().toASCIIString()
+              + "/Microsoft.Test.OData.Services.AstoriaDefaultService.SpecialEmployee/Sack");
+        }
+
+        return utils.getValue().createResponse(
+            uriInfo.getRequestUri().toASCIIString(),
+            entity,
+            internal.getHeaderString("ETag"),
+            utils.getKey());
+      } catch (Exception e) {
+        LOG.error("Error retrieving entity", e);
+        return xml.createFaultResponse(accept, e);
+      }
+    } else {
+      return internal;
+    }
+  }
+
+  @GET
+  @Path("/Product({entityId})")
+  public Response getProduct(
+      @Context final UriInfo uriInfo,
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("entityId") final String entityId,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+    final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+    final Response internal = getEntityInternal(
+        uriInfo.getRequestUri().toASCIIString(), accept, "Product", entityId, format, null, null);
+    if (internal.getStatus() == 200) {
+      InputStream entity = (InputStream) internal.getEntity();
+      try {
+        if (utils.getKey() == Accept.JSON_FULLMETA || utils.getKey() == Accept.ATOM) {
+          entity = utils.getValue().addOperation(entity,
+              "ChangeProductDimensions", "#DefaultContainer.ChangeProductDimensions",
+              uriInfo.getAbsolutePath().toASCIIString() + "/ChangeProductDimensions");
+        }
+
+        return utils.getValue().createResponse(
+            uriInfo.getRequestUri().toASCIIString(),
+            entity,
+            internal.getHeaderString("ETag"),
+            utils.getKey());
+      } catch (Exception e) {
+        LOG.error("Error retrieving entity", e);
+        return xml.createFaultResponse(accept, e);
+      }
+    } else {
+      return internal;
+    }
+  }
+
+  @GET
+  @Path("/ComputerDetail({entityId})")
+  public Response getComputerDetail(
+      @Context final UriInfo uriInfo,
       @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
       @PathParam("entityId") final String entityId,
       @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
 
+    final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+    final Response internal = getEntityInternal(
+        uriInfo.getRequestUri().toASCIIString(), accept, "ComputerDetail", entityId, format, null, null);
+    if (internal.getStatus() == 200) {
+      InputStream entity = (InputStream) internal.getEntity();
+      try {
+        if (utils.getKey() == Accept.JSON_FULLMETA || utils.getKey() == Accept.ATOM) {
+          entity = utils.getValue().addOperation(entity,
+              "ResetComputerDetailsSpecifications", "#DefaultContainer.ResetComputerDetailsSpecifications",
+              uriInfo.getAbsolutePath().toASCIIString() + "/ResetComputerDetailsSpecifications");
+        }
+
+        return utils.getValue().createResponse(
+            uriInfo.getRequestUri().toASCIIString(),
+            entity,
+            internal.getHeaderString("ETag"),
+            utils.getKey());
+      } catch (Exception e) {
+        LOG.error("Error retrieving entity", e);
+        return xml.createFaultResponse(accept, e);
+      }
+    } else {
+      return internal;
+    }
+  }
+
+  /**
+   * Retrieve entity sample.
+   *
+   * @param accept Accept header.
+   * @param entitySetName Entity set name.
+   * @param entityId entity id.
+   * @param format format query option.
+   * @param expand expand query option.
+   * @param select select query option.
+   * @return entity.
+   */
+  @GET
+  @Path("/{entitySetName}({entityId})")
+  public Response getEntity(
+      @Context final UriInfo uriInfo,
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("entitySetName") final String entitySetName,
+      @PathParam("entityId") final String entityId,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+      @QueryParam("$expand") @DefaultValue(StringUtils.EMPTY) final String expand,
+      @QueryParam("$select") @DefaultValue(StringUtils.EMPTY) final String select) {
+
+    return getEntityInternal(
+        uriInfo.getRequestUri().toASCIIString(), accept, entitySetName, entityId, format, expand, select);
+  }
+
+  protected Response getEntityInternal(
+      final String location,
+      final String accept,
+      final String entitySetName,
+      final String entityId,
+      final String format,
+      final String expand,
+      final String select) {
+
     try {
-      final Accept acceptType;
-      if (StringUtils.isNotBlank(format)) {
-        acceptType = Accept.valueOf(format.toUpperCase());
-      } else {
-        acceptType = Accept.parse(accept);
+      final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+      if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
+        throw new UnsupportedMediaTypeException("Unsupported media type");
       }
 
-      final Entity entry = new Entity();
-      entry.setType("Microsoft.Test.OData.Services.ODataWCFService.ProductDetail");
-      final Property productId = new Property();
-      productId.setName("ProductID");
-      productId.setType("Edm.Int32");
-      productId.setValue(ValueType.PRIMITIVE, Integer.valueOf(entityId));
-      entry.getProperties().add(productId);
-      final Property productDetailId = new Property();
-      productDetailId.setName("ProductDetailID");
-      productDetailId.setType("Edm.Int32");
-      productDetailId.setValue(ValueType.PRIMITIVE, 2);
-      entry.getProperties().add(productDetailId);
+      final Map.Entry<String, InputStream> entityInfo =
+          utils.getValue().readEntity(entitySetName, entityId, Accept.ATOM);
 
-      final Link link = new Link();
-      link.setRel("edit");
-      link.setHref(URI.create(
-          Constants.get(ConstantKey.DEFAULT_SERVICE_URL)
-              + "ProductDetails(ProductID=6,ProductDetailID=1)").toASCIIString());
-      entry.setEditLink(link);
+      final InputStream entity = entityInfo.getValue();
 
-      final EntityCollection feed = new EntityCollection();
-      feed.getEntities().add(entry);
+      ResWrap<Entity> container = atomDeserializer.toEntity(entity);
+      if (container.getContextURL() == null) {
+        container = new ResWrap<Entity>(URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX)
+            + entitySetName + Constants.get(ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)),
+            container.getMetadataETag(), container.getPayload());
+      }
+      final Entity entry = container.getPayload();
 
-      final ResWrap<EntityCollection> container = new ResWrap<EntityCollection>(
-          URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + "ProductDetail"), null,
-          feed);
+      if ((this instanceof KeyAsSegment)) {
+        final Link editLink = new Link();
+        editLink.setRel("edit");
+        editLink.setTitle(entitySetName);
+        editLink.setHref(Constants.get(ConstantKey.DEFAULT_SERVICE_URL) + entitySetName + "/" + entityId);
+
+        entry.setEditLink(editLink);
+      }
+
+      if (StringUtils.isNotBlank(select)) {
+        final List<String> properties = Arrays.asList(select.split(","));
+        final Set<Property> toBeRemoved = new HashSet<Property>();
+
+        for (Property property : entry.getProperties()) {
+          if (!properties.contains(property.getName())) {
+            toBeRemoved.add(property);
+          }
+        }
+
+        entry.getProperties().removeAll(toBeRemoved);
+
+        final Set<Link> linkToBeRemoved = new HashSet<Link>();
+
+        for (Link link : entry.getNavigationLinks()) {
+          if (!properties.contains(link.getTitle().replaceAll("@.*$", "")) && !properties.contains(link.getTitle())) {
+            linkToBeRemoved.add(link);
+          }
+        }
+
+        entry.getNavigationLinks().removeAll(linkToBeRemoved);
+      }
+
+      String tempExpand = expand;
+      if (StringUtils.isNotBlank(tempExpand)) {
+        tempExpand = StringUtils.substringBefore(tempExpand, "(");
+        final List<String> links = Arrays.asList(tempExpand.split(","));
+
+        final Map<Link, Link> replace = new HashMap<Link, Link>();
+
+        for (Link link : entry.getNavigationLinks()) {
+          if (links.contains(link.getTitle())) {
+            // expand link
+            final Link rep = new Link();
+            rep.setHref(link.getHref());
+            rep.setRel(link.getRel());
+            rep.setTitle(link.getTitle());
+            rep.setType(link.getType());
+            if (link.getType().equals(Constants.get(ConstantKey.ATOM_LINK_ENTRY))) {
+              // inline entry
+              final Entity inline = atomDeserializer.toEntity(
+                  xml.expandEntity(entitySetName, entityId, link.getTitle())).getPayload();
+              rep.setInlineEntity(inline);
+            } else if (link.getType().equals(Constants.get(ConstantKey.ATOM_LINK_FEED))) {
+              // inline feed
+              final EntityCollection inline = atomDeserializer.toEntitySet(
+                  xml.expandEntity(entitySetName, entityId, link.getTitle())).getPayload();
+              rep.setInlineEntitySet(inline);
+            }
+            replace.put(link, rep);
+          }
+        }
+
+        for (Map.Entry<Link, Link> link : replace.entrySet()) {
+          entry.getNavigationLinks().remove(link.getKey());
+          entry.getNavigationLinks().add(link.getValue());
+        }
+      }
 
       return xml.createResponse(
-          null,
-          xml.writeEntitySet(acceptType, container),
-          null,
-          acceptType);
+          location,
+          xml.writeEntity(utils.getKey(), container),
+          Commons.getETag(entityInfo.getKey()),
+          utils.getKey());
     } catch (Exception e) {
+      LOG.error("Error retrieving entity", e);
       return xml.createFaultResponse(accept, e);
     }
   }
 
-  @POST
-  @Path("/Products({entityId})/Microsoft.Test.OData.Services.ODataWCFService.AddAccessRight{paren:[\\(\\)]*}")
-  public Response actionAddAccessRight(
+  @GET
+  @Path("/{entitySetName}({entityId})/$value")
+  public Response getMediaEntity(
+      @Context final UriInfo uriInfo,
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("entitySetName") final String entitySetName,
+      @PathParam("entityId") final String entityId) {
+
+    try {
+      if (!accept.contains("*/*") && !accept.contains("application/octet-stream")) {
+        throw new UnsupportedMediaTypeException("Unsupported media type");
+      }
+
+      final AbstractUtilities utils = getUtilities(null);
+      final Map.Entry<String, InputStream> entityInfo = utils.readMediaEntity(entitySetName, entityId);
+      return utils.createResponse(
+          uriInfo.getRequestUri().toASCIIString(),
+          entityInfo.getValue(),
+          Commons.getETag(entityInfo.getKey()),
+          null);
+
+    } catch (Exception e) {
+      LOG.error("Error retrieving entity", e);
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  @GET
+  @Path("/People/{type:.*}")
+  public Response getPeople(
+      @Context final UriInfo uriInfo,
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("type") final String type,
+      @QueryParam("$top") @DefaultValue(StringUtils.EMPTY) final String top,
+      @QueryParam("$skip") @DefaultValue(StringUtils.EMPTY) final String skip,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+      @QueryParam("$count") @DefaultValue(StringUtils.EMPTY) final String count,
+      @QueryParam("$filter") @DefaultValue(StringUtils.EMPTY) final String filter,
+      @QueryParam("$search") @DefaultValue(StringUtils.EMPTY) final String search,
+      @QueryParam("$orderby") @DefaultValue(StringUtils.EMPTY) final String orderby,
+      @QueryParam("$skiptoken") @DefaultValue(StringUtils.EMPTY) final String skiptoken) {
+
+    return StringUtils.isBlank(filter) && StringUtils.isBlank(search) ?
+        NumberUtils.isNumber(type) ?
+            getEntityInternal(uriInfo.getRequestUri().toASCIIString(), accept, "People", type, format, null, null) :
+            getEntitySet(accept, "People", type) :
+        getEntitySet(uriInfo, accept, "People", top, skip, format, count, filter, orderby, skiptoken, type);
+  }
+
+  @GET
+  @Path("/Boss")
+  public Response getSingletonBoss(
+      @Context final UriInfo uriInfo,
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+    return getEntityInternal(
+        uriInfo.getRequestUri().toASCIIString(), accept, "Boss", StringUtils.EMPTY, format, null, null);
+  }
+
+  @GET
+  @Path("/Company")
+  public Response getSingletonCompany(
+      @Context final UriInfo uriInfo,
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+    return getEntityInternal(
+        uriInfo.getRequestUri().toASCIIString(), accept, "Company", StringUtils.EMPTY, format, null, null);
+  }
+
+  @PATCH
+  @Path("/Company")
+  @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+  @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+  public Response patchSingletonCompany(
+      @Context final UriInfo uriInfo,
       @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
       @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
+      @HeaderParam("If-Match") @DefaultValue(StringUtils.EMPTY) final String ifMatch,
+      final String changes) {
+
+    return patchEntityInternal(uriInfo, accept, contentType, prefer, ifMatch, "Company", StringUtils.EMPTY, changes);
+  }
+
+  @GET
+  @Path("/Customers")
+  public Response getCustomers(
+      @Context final UriInfo uriInfo,
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
       @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
-      final String param) {
+      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
+      @QueryParam("$deltatoken") @DefaultValue(StringUtils.EMPTY) final String deltatoken) {
 
     try {
       final Accept acceptType;
@@ -612,236 +1168,1448 @@ public class Services extends AbstractServices {
         acceptType = Accept.parse(accept);
       }
 
-      final Accept contentTypeValue = Accept.parse(contentType);
-      final Entity entry = xml.readEntity(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING));
-
-      assert 1 == entry.getProperties().size();
-      assert entry.getProperty("accessRight") != null;
+      final InputStream output;
+      if (StringUtils.isBlank(deltatoken)) {
+        final InputStream input = (InputStream) getEntitySet(
+            uriInfo, accept, "Customers", null, null, format, null, null, null, null).getEntity();
+        final EntityCollection entitySet = xml.readEntitySet(acceptType, input);
 
-      final Property property = entry.getProperty("accessRight");
-      property.setType("Microsoft.Test.OData.Services.ODataWCFService.AccessLevel");
+        boolean trackChanges = prefer.contains("odata.track-changes");
+        if (trackChanges) {
+          entitySet.setDeltaLink(URI.create("Customers?$deltatoken=8015"));
+        }
 
-      final ResWrap<Property> result = new ResWrap<Property>(
-          URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + property.getType()),
-          null, property);
+        output = xml.writeEntitySet(acceptType, new ResWrap<EntityCollection>(
+            URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + "Customers"),
+            null,
+            entitySet));
+      } else {
+        output = FSManager.instance().readFile("delta", acceptType);
+      }
 
-      return xml.createResponse(
+      final Response response = xml.createResponse(
           null,
-          xml.writeProperty(acceptType, result),
+          output,
           null,
           acceptType);
+      if (StringUtils.isNotBlank(prefer)) {
+        response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
+      }
+      return response;
     } catch (Exception e) {
       return xml.createFaultResponse(accept, e);
     }
   }
 
   @POST
-  @Path("/Customers({personId})/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress{paren:[\\(\\)]*}")
-  public Response actionResetAddress(
+  @Path("/{entitySetName}")
+  @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+  @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM })
+  public Response postNewEntity(
       @Context final UriInfo uriInfo,
       @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("personId") final String personId,
+      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
+      @PathParam("entitySetName") final String entitySetName,
+      final String entity) {
+
+    try {
+      final Accept acceptType = Accept.parse(accept);
+      if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+        throw new UnsupportedMediaTypeException("Unsupported media type");
+      }
+
+      final ResWrap<Entity> container;
+
+      final org.apache.olingo.fit.metadata.EntitySet entitySet = metadata.getEntitySet(entitySetName);
+
+      final Entity entry;
+      final String entityKey;
+      if (xml.isMediaContent(entitySetName)) {
+        entry = new Entity();
+        entry.setMediaContentType(ContentType.APPLICATION_OCTET_STREAM.toContentTypeString());
+        entry.setType(entitySet.getType());
+
+        entityKey = xml.getDefaultEntryKey(entitySetName, entry);
+
+        xml.addMediaEntityValue(entitySetName, entityKey, IOUtils.toInputStream(entity, Constants.ENCODING));
+
+        final Pair<String, EdmPrimitiveTypeKind> id = Commons.getMediaContent().get(entitySetName);
+        if (id != null) {
+          final Property prop = new Property();
+          prop.setName(id.getKey());
+          prop.setType(id.getValue().toString());
+          prop.setValue(ValueType.PRIMITIVE,
+              id.getValue() == EdmPrimitiveTypeKind.Int32
+              ? Integer.parseInt(entityKey)
+                  : id.getValue() == EdmPrimitiveTypeKind.Guid
+                  ? UUID.fromString(entityKey)
+                      : entityKey);
+          entry.getProperties().add(prop);
+        }
+
+        final Link editLink = new Link();
+        editLink.setHref(Commons.getEntityURI(entitySetName, entityKey));
+        editLink.setRel("edit");
+        editLink.setTitle(entitySetName);
+        entry.setEditLink(editLink);
+
+        entry.setMediaContentSource(URI.create(editLink.getHref() + "/$value"));
+
+        container = new ResWrap<Entity>((URI) null, null, entry);
+      } else {
+        final Accept contentTypeValue = Accept.parse(contentType);
+        if (Accept.ATOM == contentTypeValue) {
+          container = atomDeserializer.toEntity(IOUtils.toInputStream(entity, Constants.ENCODING));
+        } else {
+          container = jsonDeserializer.toEntity(IOUtils.toInputStream(entity, Constants.ENCODING));
+        }
+        entry = container.getPayload();
+        updateInlineEntities(entry);
+
+        entityKey = xml.getDefaultEntryKey(entitySetName, entry);
+      }
+
+      normalizeAtomEntry(entry, entitySetName, entityKey);
+
+      final ByteArrayOutputStream content = new ByteArrayOutputStream();
+      final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
+      atomSerializer.write(writer, container);
+      writer.flush();
+      writer.close();
+
+      final InputStream serialization =
+          xml.addOrReplaceEntity(entityKey, entitySetName, new ByteArrayInputStream(content.toByteArray()), entry);
+
+      ResWrap<Entity> result = atomDeserializer.toEntity(serialization);
+      result = new ResWrap<Entity>(
+          URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX)
+              + entitySetName + Constants.get(ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)),
+              null, result.getPayload());
+
+      final String path = Commons.getEntityBasePath(entitySetName, entityKey);
+      FSManager.instance().putInMemory(result, path + Constants.get(ConstantKey.ENTITY));
+
+      final String location;
+
+      if ((this instanceof KeyAsSegment)) {
+        location = uriInfo.getRequestUri().toASCIIString() + "/" + entityKey;
+
+        final Link editLink = new Link();
+        editLink.setRel("edit");
+        editLink.setTitle(entitySetName);
+        editLink.setHref(location);
+
+        result.getPayload().setEditLink(editLink);
+      } else {
+        location = uriInfo.getRequestUri().toASCIIString() + "(" + entityKey + ")";
+      }
+
+      final Response response;
+      if ("return-no-content".equalsIgnoreCase(prefer)) {
+        response = xml.createResponse(
+            location,
+            null,
+            null,
+            acceptType,
+            Response.Status.NO_CONTENT);
+      } else {
+        response = xml.createResponse(
+            location,
+            xml.writeEntity(acceptType, result),
+            null,
+            acceptType,
+            Response.Status.CREATED);
+      }
+
+      if (StringUtils.isNotBlank(prefer)) {
+        response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
+      }
+
+      return response;
+    } catch (Exception e) {
+      LOG.error("While creating new entity", e);
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  private void updateInlineEntities(final Entity entity) {
+    final String type = entity.getType();
+    EntityType entityType;
+    Map<String, NavigationProperty> navProperties = Collections.emptyMap();
+    if (type != null && type.length() > 0) {
+      entityType = metadata.getEntityOrComplexType(type);
+      navProperties = entityType.getNavigationPropertyMap();
+    }
+
+    for (Property property : entity.getProperties()) {
+      if (navProperties.containsKey(property.getName())) {
+        Link alink = new Link();
+        alink.setTitle(property.getName());
+        alink.getAnnotations().addAll(property.getAnnotations());
+
+        alink.setType(navProperties.get(property.getName()).isEntitySet()
+            ? Constants.get(ConstantKey.ATOM_LINK_FEED)
+                : Constants.get(ConstantKey.ATOM_LINK_ENTRY));
+
+        alink.setRel(Constants.get(ConstantKey.ATOM_LINK_REL) + property.getName());
+
+        if (property.isCollection()) {
+          EntityCollection inline = new EntityCollection();
+          for (Object value : property.asCollection()) {
+            Entity inlineEntity = new Entity();
+            inlineEntity.setType(navProperties.get(property.getName()).getType());
+            for (Property prop : ((ComplexValue) value).getValue()) {
+              inlineEntity.getProperties().add(prop);
+            }
+            inline.getEntities().add(inlineEntity);
+          }
+          alink.setInlineEntitySet(inline);
+        } else if (property.isComplex()) {
+          Entity inline = new Entity();
+          inline.setType(navProperties.get(property.getName()).getType());
+          for (Property prop : property.asComplex().getValue()) {
+            inline.getProperties().add(prop);
+          }
+          alink.setInlineEntity(inline);
+
+        } else {
+          throw new IllegalStateException("Invalid navigation property " + property);
+        }
+        entity.getNavigationLinks().add(alink);
+      }
+    }
+  }
+
+  private void normalizeAtomEntry(final Entity entry, final String entitySetName, final String entityKey) {
+    final org.apache.olingo.fit.metadata.EntitySet entitySet = metadata.getEntitySet(entitySetName);
+    final EntityType entityType = metadata.getEntityOrComplexType(entitySet.getType());
+    for (Map.Entry<String, org.apache.olingo.fit.metadata.Property> property : entityType.getPropertyMap().entrySet()) {
+      if (entry.getProperty(property.getKey()) == null && property.getValue().isNullable()) {
+        final Property prop = new Property();
+        prop.setName(property.getKey());
+        prop.setValue(ValueType.PRIMITIVE, null);
+        entry.getProperties().add(prop);
+      }
+    }
+
+    for (Map.Entry<String, NavigationProperty> property : entityType.getNavigationPropertyMap().entrySet()) {
+      boolean found = false;
+      for (Link link : entry.getNavigationLinks()) {
+        if (link.getTitle().equals(property.getKey())) {
+          found = true;
+        }
+      }
+
+      if (!found) {
+        final Link link = new Link();
+        link.setTitle(property.getKey());
+        link.setType(property.getValue().isEntitySet()
+            ? Constants.get(ConstantKey.ATOM_LINK_FEED)
+                : Constants.get(ConstantKey.ATOM_LINK_ENTRY));
+        link.setRel(Constants.get(ConstantKey.ATOM_LINK_REL) + property.getKey());
+        link.setHref(entitySetName + "(" + entityKey + ")/" + property.getKey());
+        entry.getNavigationLinks().add(link);
+      }
+    }
+  }
+
+  @GET
+  @Path("/Company/Microsoft.Test.OData.Services.ODataWCFService.GetEmployeesCount{paren:[\\(\\)]*}")
+  public Response functionGetEmployeesCount(
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+    try {
+      final Accept acceptType;
+      if (StringUtils.isNotBlank(format)) {
+        acceptType = Accept.valueOf(format.toUpperCase());
+      } else {
+        acceptType = Accept.parse(accept);
+      }
+
+      final Property property = new Property();
+      property.setType("Edm.Int32");
+      property.setValue(ValueType.PRIMITIVE, 2);
+      final ResWrap<Property> container = new ResWrap<Property>(
+          URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + property.getType()), null,
+          property);
+
+      return xml.createResponse(
+          null,
+          xml.writeProperty(acceptType, container),
+          null,
+          acceptType);
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  @POST
+  @Path("/Person({entityId})/{type:.*}/Sack")
+  public Response actionSack(
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("entityId") final String entityId,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+    final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+    if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
+      throw new UnsupportedMediaTypeException("Unsupported media type");
+    }
+
+    try {
+      final Map.Entry<String, InputStream> entityInfo = xml.readEntity("Person", entityId, Accept.ATOM);
+
+      final InputStream entity = entityInfo.getValue();
+      final ResWrap<Entity> container = atomDeserializer.toEntity(entity);
+
+      container.getPayload().getProperty("Salary").setValue(ValueType.PRIMITIVE, 0);
+      container.getPayload().getProperty("Title").setValue(ValueType.PRIMITIVE, "[Sacked]");
+
+      final FSManager fsManager = FSManager.instance();
+      fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
+          fsManager.getAbsolutePath(Commons.getEntityBasePath("Person", entityId) + Constants.get(
+              ConstantKey.ENTITY), Accept.ATOM));
+
+      return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  @POST
+  @Path("/Person/{type:.*}/IncreaseSalaries")
+  public Response actionIncreaseSalaries(
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("type") final String type,
+      final String body) {
+
+    final String name = "Person";
+    try {
+      final Accept acceptType = Accept.parse(accept);
+      if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+        throw new UnsupportedMediaTypeException("Unsupported media type");
+      }
+
+      final JsonNode tree = new ObjectMapper().readTree(body);
+      if (!tree.has("n")) {
+        throw new Exception("Missing parameter: n");
+      }
+      final int n = tree.get("n").asInt();
+
+      final StringBuilder path = new StringBuilder(name).
+          append(File.separatorChar).append(type).
+          append(File.separatorChar);
+
+      path.append(metadata.getEntitySet(name).isSingleton()
+          ? Constants.get(ConstantKey.ENTITY)
+              : Constants.get(ConstantKey.FEED));
+
+      final InputStream feed = FSManager.instance().readFile(path.toString(), acceptType);
+
+      final ByteArrayOutputStream copy = new ByteArrayOutputStream();
+      IOUtils.copy(feed, copy);
+      IOUtils.closeQuietly(feed);
+
+      String newContent = new String(copy.toByteArray(), "UTF-8");
+      final Pattern salary = Pattern.compile(acceptType == Accept.ATOM
+          ? "\\<d:Salary m:type=\"Edm.Int32\"\\>(-?\\d+)\\</d:Salary\\>"
+              : "\"Salary\":(-?\\d+),");
+      final Matcher salaryMatcher = salary.matcher(newContent);
+      while (salaryMatcher.find()) {
+        final Long newSalary = Long.valueOf(salaryMatcher.group(1)) + n;
+        newContent = newContent.
+            replaceAll("\"Salary\":" + salaryMatcher.group(1) + ",",
+                "\"Salary\":" + newSalary + ",").
+                replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>" + salaryMatcher.group(1) + "</d:Salary\\>",
+                    "<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
+      }
+
+      FSManager.instance().putInMemory(IOUtils.toInputStream(newContent, Constants.ENCODING),
+          FSManager.instance().getAbsolutePath(path.toString(), acceptType));
+
+      return xml.createResponse(null, null, null, acceptType, Response.Status.NO_CONTENT);
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  @POST
+  @Path("/Product({entityId})/ChangeProductDimensions")
+  public Response actionChangeProductDimensions(
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("entityId") final String entityId,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+      final String argument) {
+
+    final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+    if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
+      throw new UnsupportedMediaTypeException("Unsupported media type");
+    }
+
+    try {
+      final Map.Entry<String, InputStream> entityInfo = xml.readEntity("Product", entityId, Accept.ATOM);
+
+      final InputStream entity = entityInfo.getValue();
+      final ResWrap<Entity> container = atomDeserializer.toEntity(entity);
+
+      final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING));
+
+      final Property property = param.getProperty("dimensions");
+      container.getPayload().getProperty("Dimensions").setValue(property.getValueType(), property.getValue());
+
+      final FSManager fsManager = FSManager.instance();
+      fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
+          fsManager.getAbsolutePath(Commons.getEntityBasePath("Product", entityId) + Constants.get(
+              ConstantKey.ENTITY), Accept.ATOM));
+
+      return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  @POST
+  @Path("/ComputerDetail({entityId})/ResetComputerDetailsSpecifications")
+  public Response actionResetComputerDetailsSpecifications(
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("entityId") final String entityId,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+      final String argument) {
+
+    final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+    if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
+      throw new UnsupportedMediaTypeException("Unsupported media type");
+    }
+
+    try {
+      final Map.Entry<String, InputStream> entityInfo = xml.readEntity("ComputerDetail", entityId, Accept.ATOM);
+
+      final InputStream entity = entityInfo.getValue();
+      final ResWrap<Entity> container = atomDeserializer.toEntity(entity);
+
+      final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING));
+
+      Property property = param.getProperty("specifications");
+      container.getPayload().getProperty("SpecificationsBag").setValue(property.getValueType(), property.getValue());
+      property = param.getProperty("purchaseTime");
+      container.getPayload().getProperty("PurchaseDate").setValue(property.getValueType(), property.getValue());
+
+      final FSManager fsManager = FSManager.instance();
+      fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
+          fsManager.getAbsolutePath(Commons.getEntityBasePath("ComputerDetail", entityId) + Constants.get(
+              ConstantKey.ENTITY), Accept.ATOM));
+
+      return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  @POST
+  @Path("/Company/Microsoft.Test.OData.Services.ODataWCFService.IncreaseRevenue{paren:[\\(\\)]*}")
+  public Response actionIncreaseRevenue(
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
       @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
       @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
       final String param) {
 
     try {
+      final Accept acceptType;
+      if (StringUtils.isNotBlank(format)) {
+        acceptType = Accept.valueOf(format.toUpperCase());
+      } else {
+        acceptType = Accept.parse(accept);
+      }
+
       final Accept contentTypeValue = Accept.parse(contentType);
       final Entity entry = xml.readEntity(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING));
 
-      assert 2 == entry.getProperties().size();
-      assert entry.getProperty("addresses") != null;
-      assert entry.getProperty("index") != null;
+      return xml.createResponse(
+          null,
+          xml.writeProperty(acceptType, entry.getProperty("IncreaseValue")),
+          null,
+          acceptType);
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  @GET
+  @Path("/Products({entityId})/Microsoft.Test.OData.Services.ODataWCFService.GetProductDetails({param:.*})")
+  public Response functionGetProductDetails(
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("entityId") final String entityId,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+    try {
+      final Accept acceptType;
+      if (StringUtils.isNotBlank(format)) {
+        acceptType = Accept.valueOf(format.toUpperCase());
+      } else {
+        acceptType = Accept.parse(accept);
+      }
+
+      final Entity entry = new Entity();
+      entry.setType("Microsoft.Test.OData.Services.ODataWCFService.ProductDetail");
+      final Property productId = new Property();
+      productId.setName("ProductID");
+      productId.setType("Edm.Int32");
+      productId.setValue(ValueType.PRIMITIVE, Integer.valueOf(entityId));
+      entry.getProperties().add(productId);
+      final Property productDetailId = new Property();
+      productDetailId.setName("ProductDetailID");
+      productDetailId.setType("Edm.Int32");
+      productDetailId.setValue(ValueType.PRIMITIVE, 2);
+      entry.getProperties().add(productDetailId);
+
+      final Link link = new Link();
+      link.setRel("edit");
+      link.setHref(URI.create(
+          Constants.get(ConstantKey.DEFAULT_SERVICE_URL)
+              + "ProductDetails(ProductID=6,ProductDetailID=1)").toASCIIString());
+      entry.setEditLink(link);
+
+      final EntityCollection feed = new EntityCollection();
+      feed.getEntities().add(entry);
+
+      final ResWrap<EntityCollection> container = new ResWrap<EntityCollection>(
+          URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + "ProductDetail"), null,
+          feed);
+
+      return xml.createResponse(
+          null,
+          xml.writeEntitySet(acceptType, container),
+          null,
+          acceptType);
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  @POST
+  @Path("/Products({entityId})/Microsoft.Test.OData.Services.ODataWCFService.AddAccessRight{paren:[\\(\\)]*}")
+  public Response actionAddAccessRight(
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+      final String param) {
+
+    try {
+      final Accept acceptType;
+      if (StringUtils.isNotBlank(format)) {
+        acceptType = Accept.valueOf(format.toUpperCase());
+      } else {
+        acceptType = Accept.parse(accept);
+      }
+
+      final Accept contentTypeValue = Accept.parse(contentType);
+      final Entity entry = xml.readEntity(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING));
+
+      assert 1 == entry.getProperties().size();
+      assert entry.getProperty("accessRight") != null;
+
+      final Property property = entry.getProperty("accessRight");
+      property.setType("Microsoft.Test.OData.Services.ODataWCFService.AccessLevel");
+
+      final ResWrap<Property> result = new ResWrap<Property>(
+          URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + property.getType()),
+          null, property);
+
+      return xml.createResponse(
+          null,
+          xml.writeProperty(acceptType, result),
+          null,
+          acceptType);
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  @POST
+  @Path("/Customers({personId})/Microsoft.Test.OData.Services.ODataWCFService.ResetAddress{paren:[\\(\\)]*}")
+  public Response actionResetAddress(
+      @Context final UriInfo uriInfo,
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("personId") final String personId,
+      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+      final String param) {
+
+    try {
+      final Accept contentTypeValue = Accept.parse(contentType);
+      final Entity entry = xml.readEntity(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING));
+
+      assert 2 == entry.getProperties().size();
+      assert entry.getProperty("addresses") != null;
+      assert entry.getProperty("index") != null;
+
+      return getEntityInternal(
+          uriInfo.getRequestUri().toASCIIString(), accept, "Customers", personId, format, null, null);
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  @GET
+  @Path("/ProductDetails(ProductID={productId},ProductDetailID={productDetailId})"
+      + "/Microsoft.Test.OData.Services.ODataWCFService.GetRelatedProduct{paren:[\\(\\)]*}")
+  public Response functionGetRelatedProduct(
+      @Context final UriInfo uriInfo,
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("productId") final String productId,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+    return getEntityInternal(
+        uriInfo.getRequestUri().toASCIIString(), accept, "Products", productId, format, null, null);
+  }
+
+  @POST
+  @Path("/Accounts({entityId})/Microsoft.Test.OData.Services.ODataWCFService.RefreshDefaultPI{paren:[\\(\\)]*}")
+  public Response actionRefreshDefaultPI(
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+      @PathParam("entityId") final String entityId,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
+      final String param) {
+
+    try {
+      final Accept contentTypeValue = Accept.parse(contentType);
+      final Entity entry = xml.readEntity(contentTypeValue, IOUtils.toInputStream(param, Constants.ENCODING));
+
+      assert 1 == entry.getProperties().size();
+      assert entry.getProperty("newDate") != null;
+
+      return functionGetDefaultPI(accept, entityId, format);
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  @GET
+  @Path("/Accounts({entityId})/Microsoft.Test.OData.Services.ODataWCFService.GetDefaultPI{paren:[\\(\\)]*}")
+  public Response functionGetDefaultPI(
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("entityId") final String entityId,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+    return getContainedEntity(accept, entityId, "MyPaymentInstruments", entityId + "901", format);
+  }
+
+  @GET
+  @Path("/Accounts({entityId})/Microsoft.Test.OData.Services.ODataWCFService.GetAccountInfo{paren:[\\(\\)]*}")
+  public Response functionGetAccountInfo(
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("entityId") final String entityId,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+    return getPath(accept, "Accounts", entityId, "AccountInfo", format);
+  }
+
+  @GET
+  @Path("/Accounts({entityId})/MyGiftCard/Microsoft.Test.OData.Services.ODataWCFService.GetActualAmount({param:.*})")
+  public Response functionGetActualAmount(
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+    try {
+      final Accept acceptType;
+      if (StringUtils.isNotBlank(format)) {
+        acceptType = Accept.valueOf(format.toUpperCase());
+      } else {
+        acceptType = Accept.parse(accept);
+      }
+
+      final Property property = new Property();
+      property.setType("Edm.Double");
+      property.setValue(ValueType.PRIMITIVE, 41.79);
+
+      final ResWrap<Property> container = new ResWrap<Property>((URI) null, null, property);
+
+      return xml.createResponse(
+          null,
+          xml.writeProperty(acceptType, container),
+          null,
+          acceptType);
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  /**
+   * Retrieve entity reference sample.
+   *
+   * @param accept Accept header.
+   * @param path path.
+   * @param format format query option.
+   * @return entity reference or feed of entity reference.
+   */
+  @GET
+  @Path("/{path:.*}/$ref")
+  public Response getEntityReference(
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @PathParam("path") final String path,
+      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
+
+    try {
+      final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
+
+      if (utils.getKey() == Accept.TEXT) {
+        throw new UnsupportedMediaTypeException("Unsupported media type");
+      }
+
+      final String filename = Base64.encodeBase64String(path.getBytes("UTF-8"));
+
+      return utils.getValue().createResponse(
+          FSManager.instance().readFile(Constants.get(ConstantKey.REF)
+              + File.separatorChar + filename, utils.getKey()),
+          null,
+          utils.getKey());
+    } catch (Exception e) {
+      LOG.error("Error retrieving entity", e);
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  @POST
+  @Path("/People")
+  @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+  @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM })
+  public Response postPeople(
+      @Context final UriInfo uriInfo,
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
+      final String entity) {
+
+    if ("{\"@odata.type\":\"#Microsoft.Test.OData.Services.ODataWCFService.Person\"}".equals(entity)) {
+      return xml.createFaultResponse(accept, new BadRequestException());
+    }
+
+    return postNewEntity(uriInfo, accept, contentType, prefer, "People", entity);
+  }
+
+  private Response patchEntityInternal(final UriInfo uriInfo,
+      final String accept, final String contentType, final String prefer, final String ifMatch,
+      final String entitySetName, final String entityId, final String changes) {
+
+    try {
+      final Accept acceptType = Accept.parse(accept);
+
+      if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+        throw new UnsupportedMediaTypeException("Unsupported media type");
+      }
+
+      final Map.Entry<String, InputStream> entityInfo = xml.readEntity(entitySetName, entityId, Accept.ATOM);
+
+      final String etag = Commons.getETag(entityInfo.getKey());
+      if (StringUtils.isNotBlank(ifMatch) && !ifMatch.equals(etag)) {
+        throw new ConcurrentModificationException("Concurrent modification");
+      }
+
+      final Accept contentTypeValue = Accept.parse(contentType);
+
+      final Entity entryChanges;
+
+      if (contentTypeValue == Accept.XML || contentTypeValue == Accept.TEXT) {
+        throw new UnsupportedMediaTypeException("Unsupported media type");
+      } else if (contentTypeValue == Accept.ATOM) {
+        entryChanges = atomDeserializer.toEntity(
+            IOUtils.toInputStream(changes, Constants.ENCODING)).getPayload();
+      } else {
+        final ResWrap<Entity> jcont = jsonDeserializer.toEntity(IOUtils.toInputStream(changes, Constants.ENCODING));
+        entryChanges = jcont.getPayload();
+      }
+
+      final ResWrap<Entity> container = atomDeserializer.toEntity(entityInfo.getValue());
+
+      for (Property property : entryChanges.getProperties()) {
+        final Property _property = container.getPayload().getProperty(property.getName());
+        if (_property == null) {
+          container.getPayload().getProperties().add(property);
+        } else {
+          _property.setValue(property.getValueType(), property.getValue());
+        }
+      }
+
+      for (Link link : entryChanges.getNavigationLinks()) {
+        container.getPayload().getNavigationLinks().add(link);
+      }
+
+      final ByteArrayOutputStream content = new ByteArrayOutputStream();
+      final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
+      atomSerializer.write(writer, container);
+      writer.flush();
+      writer.close();
+
+      final InputStream res = xml.addOrReplaceEntity(
+          entityId, entitySetName, new ByteArrayInputStream(content.toByteArray()), container.getPayload());
+
+      final ResWrap<Entity> cres = atomDeserializer.toEntity(res);
+
+      normalizeAtomEntry(cres.getPayload(), entitySetName, entityId);
+
+      final String path = Commons.getEntityBasePath(entitySetName, entityId);
+      FSManager.instance().putInMemory(
+          cres, path + File.separatorChar + Constants.get(ConstantKey.ENTITY));
+
+      final Response response;
+      if ("return-content".equalsIgnoreCase(prefer)) {
+        response = xml.createResponse(
+            uriInfo.getRequestUri().toASCIIString(),
+            xml.readEntity(entitySetName, entityId, acceptType).getValue(),
+            null, acceptType, Response.Status.OK);
+      } else {
+        res.close();
+        response = xml.createResponse(
+            uriInfo.getRequestUri().toASCIIString(),
+            null,
+            null,
+            acceptType, Response.Status.NO_CONTENT);
+      }
+
+      if (StringUtils.isNotBlank(prefer)) {
+        response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
+      }
+
+      return response;
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  @PATCH
+  @Path("/{entitySetName}({entityId})")
+  @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+  @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+  public Response patchEntity(
+      @Context final UriInfo uriInfo,
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
+      @HeaderParam("If-Match") @DefaultValue(StringUtils.EMPTY) final String ifMatch,
+      @PathParam("entitySetName") final String entitySetName,
+      @PathParam("entityId") final String entityId,
+      final String changes) {
+
+    final Response response =
+        getEntityInternal(uriInfo.getRequestUri().toASCIIString(),
+            accept, entitySetName, entityId, accept, StringUtils.EMPTY, StringUtils.EMPTY);
+    return response.getStatus() >= 400 ?
+        postNewEntity(uriInfo, accept, contentType, prefer, entitySetName, changes) :
+        patchEntityInternal(uriInfo, accept, contentType, prefer, ifMatch, entitySetName, entityId, changes);
+  }
+
+  private Response replaceEntity(final UriInfo uriInfo,
+      final String accept, final String prefer,
+      final String entitySetName, final String entityId, final String entity) {
+
+    try {
+      final Accept acceptType = Accept.parse(accept);
+
+      if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
+        throw new UnsupportedMediaTypeException("Unsupported media type");
+      }
+
+      final InputStream res = getUtilities(acceptType).addOrReplaceEntity(entityId, entitySetName,
+          IOUtils.toInputStream(entity, Constants.ENCODING),
+          xml.readEntity(acceptType, IOUtils.toInputStream(entity, Constants.ENCODING)));
+
+      final ResWrap<Entity> cres;
+      if (acceptType == Accept.ATOM) {
+        cres = atomDeserializer.toEntity(res);
+      } else {
+        cres = jsonDeserializer.toEntity(res);
+      }
+
+      final String path = Commons.getEntityBasePath(entitySetName, entityId);
+      FSManager.instance().putInMemory(
+          cres, path + File.separatorChar + Constants.get(ConstantKey.ENTITY));
+
+      final Response response;
+      if ("return-content".equalsIgnoreCase(prefer)) {
+        response = xml.createResponse(
+            uriInfo.getRequestUri().toASCIIString(),
+            xml.readEntity(entitySetName, entityId, acceptType).getValue(),
+            null,
+            acceptType,
+            Response.Status.OK);
+      } else {
+        res.close();
+        response = xml.createResponse(
+            uriInfo.getRequestUri().toASCIIString(),
+            null,
+            null,
+            acceptType,
+            Response.Status.NO_CONTENT);
+      }
+
+      if (StringUtils.isNotBlank(prefer)) {
+        response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
+      }
+
+      return response;
+    } catch (Exception e) {
+      return xml.createFaultResponse(accept, e);
+    }
+  }
+
+  @PUT
+  @Path("/{entitySetName}({entityId})")
+  @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+  @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
+  public Response replaceEntity(
+      @Context final UriInfo uriInfo,
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
+      @PathParam("entitySetName") final String entitySetName,
+      @PathParam("entityId") final String entityId,
+      final String entity) {
+
+    try {
+      getEntityInternal(uriInfo.getRequestUri().toASCIIString(),
+          accept, entitySetName, entityId, accept, StringUtils.EMPTY, StringUtils.EMPTY);
+      return replaceEntity(uriInfo, accept, prefer, entitySetName, entityId, entity);
+    } catch (NotFoundException e) {
+      return postNewEntity(uriInfo, accept, contentType, prefer, entitySetName, entityId);
+    }
+  }
+
+  private StringBuilder containedPath(final String entityId, final String containedEntitySetName) {
+    return new StringBuilder("Accounts").append(File.separatorChar).
+        append(entityId).append(File.separatorChar).
+        appen

<TRUNCATED>

[6/7] olingo-odata4 git commit: [OLINGO-852] less warnings + general clean-up

Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java b/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
deleted file mode 100644
index c287e5b..0000000
--- a/fit/src/main/java/org/apache/olingo/fit/AbstractServices.java
+++ /dev/null
@@ -1,1947 +0,0 @@
-/*
- * 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.fit;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.net.URI;
-import java.util.AbstractMap;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.ConcurrentModificationException;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.mail.Header;
-import javax.mail.internet.MimeBodyPart;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.HeaderParam;
-import javax.ws.rs.NotFoundException;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedHashMap;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.cxf.jaxrs.client.WebClient;
-import org.apache.cxf.jaxrs.ext.multipart.Attachment;
-import org.apache.cxf.jaxrs.ext.multipart.Multipart;
-import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
-import org.apache.olingo.client.api.data.ResWrap;
-import org.apache.olingo.client.api.serialization.ODataDeserializer;
-import org.apache.olingo.client.api.serialization.ODataSerializer;
-import org.apache.olingo.client.core.serialization.AtomSerializer;
-import org.apache.olingo.client.core.serialization.JsonDeserializer;
-import org.apache.olingo.client.core.serialization.JsonSerializer;
-import org.apache.olingo.commons.api.data.ComplexValue;
-import org.apache.olingo.commons.api.data.Entity;
-import org.apache.olingo.commons.api.data.EntityCollection;
-import org.apache.olingo.commons.api.data.Link;
-import org.apache.olingo.commons.api.data.Property;
-import org.apache.olingo.commons.api.data.ValueType;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
-import org.apache.olingo.commons.api.format.ContentType;
-import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
-import org.apache.olingo.fit.metadata.EntityType;
-import org.apache.olingo.fit.metadata.Metadata;
-import org.apache.olingo.fit.metadata.NavigationProperty;
-import org.apache.olingo.fit.methods.PATCH;
-import org.apache.olingo.fit.serializer.FITAtomDeserializer;
-import org.apache.olingo.fit.utils.AbstractUtilities;
-import org.apache.olingo.fit.utils.Accept;
-import org.apache.olingo.fit.utils.Commons;
-import org.apache.olingo.fit.utils.ConstantKey;
-import org.apache.olingo.fit.utils.Constants;
-import org.apache.olingo.fit.utils.FSManager;
-import org.apache.olingo.fit.utils.JSONUtilities;
-import org.apache.olingo.fit.utils.LinkInfo;
-import org.apache.olingo.fit.utils.XMLUtilities;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-public abstract class AbstractServices {
-
-  /**
-   * Logger.
-   */
-  protected static final Logger LOG = LoggerFactory.getLogger(AbstractServices.class);
-
-  private static final Pattern REQUEST_PATTERN = Pattern.compile("(.*) (http://.*) HTTP/.*");
-
-  private static final Pattern BATCH_REQUEST_REF_PATTERN = Pattern.compile("(.*) ([$]\\d+)(.*) HTTP/.*");
-
-  private static final Pattern REF_PATTERN = Pattern.compile("([$]\\d+)");
-
-  protected static final String BOUNDARY = "batch_243234_25424_ef_892u748";
-
-  protected static final String MULTIPART_MIXED = "multipart/mixed";
-
-  protected static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
-
-  protected final ODataServiceVersion version;
-
-  protected final Metadata metadata;
-
-  protected final ODataDeserializer atomDeserializer;
-
-  protected final ODataDeserializer jsonDeserializer;
-
-  protected final ODataSerializer atomSerializer;
-
-  protected final ODataSerializer jsonSerializer;
-
-  protected final XMLUtilities xml;
-
-  protected final JSONUtilities json;
-
-  public AbstractServices(final ODataServiceVersion version, final Metadata metadata) throws IOException {
-    this.version = version;
-    this.metadata = metadata;
-
-    atomDeserializer = new FITAtomDeserializer();
-    jsonDeserializer = new JsonDeserializer(true);
-    atomSerializer = new AtomSerializer(true);
-    jsonSerializer = new JsonSerializer(true, ContentType.JSON_FULL_METADATA);
-
-    xml = new XMLUtilities(metadata);
-    json = new JSONUtilities(metadata);
-  }
-
-  /**
-   * Provide sample services.
-   *
-   * @param accept Accept header.
-   * @return OData services.
-   */
-  @GET
-  public Response getSevices(@HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept) {
-    try {
-      final Accept acceptType = Accept.parse(accept);
-
-      if (acceptType == Accept.ATOM) {
-        throw new UnsupportedMediaTypeException("Unsupported media type");
-      }
-
-      return xml.createResponse(
-          null,
-          FSManager.instance(version).readFile(Constants.get(ConstantKey.SERVICES), acceptType),
-          null, acceptType);
-    } catch (Exception e) {
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  /**
-   * Provide sample getMetadata().
-   *
-   * @return getMetadata().
-   */
-  @GET
-  @Path("/$metadata")
-  @Produces(MediaType.APPLICATION_XML)
-  public Response getMetadata() {
-    return getMetadata(Constants.get(ConstantKey.METADATA));
-  }
-
-  protected Response getMetadata(final String filename) {
-    try {
-      return xml.createResponse(null, FSManager.instance(version).readRes(filename, Accept.XML), null, Accept.XML);
-    } catch (Exception e) {
-      return xml.createFaultResponse(Accept.XML.toString(), e);
-    }
-  }
-
-  @POST
-  @Path("/$batch")
-  @Consumes(MULTIPART_MIXED)
-  @Produces(APPLICATION_OCTET_STREAM + ";boundary=" + BOUNDARY)
-  public Response batch(
-      @HeaderParam("Authorization") @DefaultValue(StringUtils.EMPTY) final String authorization,
-      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
-      final @Multipart MultipartBody attachment) {
-    try {
-      final boolean continueOnError = prefer.contains("odata.continue-on-error");
-      return xml.createBatchResponse(
-          exploreMultipart(attachment.getAllAttachments(), BOUNDARY, continueOnError));
-    } catch (IOException e) {
-      return xml.createFaultResponse(Accept.XML.toString(), e);
-    }
-  }
-
-  // ----------------------------------------------
-  // just for non nullable property test into PropertyTestITCase
-  // ----------------------------------------------
-  @PATCH
-  @Path("/Driver('2')")
-  public Response patchDriver() {
-    return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(), new Exception("Non nullable properties"));
-  }
-
-  @GET
-  @Path("/StoredPIs(1000)")
-  public Response getStoredPI(@Context final UriInfo uriInfo) {
-    final Entity entity = new Entity();
-    entity.setType("Microsoft.Test.OData.Services.ODataWCFService.StoredPI");
-    final Property id = new Property();
-    id.setType("Edm.Int32");
-    id.setName("StoredPIID");
-    id.setValue(ValueType.PRIMITIVE, 1000);
-    entity.getProperties().add(id);
-    final Link edit = new Link();
-    edit.setHref(uriInfo.getRequestUri().toASCIIString());
-    edit.setRel("edit");
-    edit.setTitle("StoredPI");
-    entity.setEditLink(edit);
-
-    final ByteArrayOutputStream content = new ByteArrayOutputStream();
-    final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
-    try {
-      jsonSerializer.write(writer, new ResWrap<Entity>((URI) null, null, entity));
-      return xml.createResponse(new ByteArrayInputStream(content.toByteArray()), null, Accept.JSON_FULLMETA);
-    } catch (Exception e) {
-      LOG.error("While creating StoredPI", e);
-      return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(), e);
-    }
-  }
-
-  @PATCH
-  @Path("/StoredPIs(1000)")
-  public Response patchStoredPI() {
-    // just for non nullable property test into PropertyTestITCase
-    return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(), new Exception("Non nullable properties"));
-  }
-
-  // ----------------------------------------------
-
-  protected Response bodyPartRequest(final MimeBodyPart body) throws Exception {
-    return bodyPartRequest(body, Collections.<String, String> emptyMap());
-  }
-
-  protected Response bodyPartRequest(final MimeBodyPart body, final Map<String, String> references) throws Exception {
-    @SuppressWarnings("unchecked")
-    final Enumeration<Header> en = body.getAllHeaders();
-
-    Header header = en.nextElement();
-    final String request =
-        header.getName() + (StringUtils.isNotBlank(header.getValue()) ? ":" + header.getValue() : "");
-
-    final Matcher matcher = REQUEST_PATTERN.matcher(request);
-    final Matcher matcherRef = BATCH_REQUEST_REF_PATTERN.matcher(request);
-
-    final MultivaluedMap<String, String> headers = new MultivaluedHashMap<String, String>();
-
-    while (en.hasMoreElements()) {
-      header = en.nextElement();
-      headers.putSingle(header.getName(), header.getValue());
-    }
-
-    final Response res;
-    final String url;
-    final String method;
-
-    if (matcher.find()) {
-      url = matcher.group(2);
-      method = matcher.group(1);
-    } else if (matcherRef.find()) {
-      url = references.get(matcherRef.group(2)) + matcherRef.group(3);
-      method = matcherRef.group(1);
-    } else {
-      url = null;
-      method = null;
-    }
-
-    if (url == null) {
-      res = null;
-    } else {
-      final WebClient client = WebClient.create(url, "odatajclient", "odatajclient", null);
-      client.headers(headers);
-
-      if ("DELETE".equals(method)) {
-        res = client.delete();
-      } else {
-        final InputStream is = body.getDataHandler().getInputStream();
-        String content = IOUtils.toString(is);
-        IOUtils.closeQuietly(is);
-
-        final Matcher refs = REF_PATTERN.matcher(content);
-
-        while (refs.find()) {
-          content = content.replace(refs.group(1), references.get(refs.group(1)));
-        }
-
-        if ("PATCH".equals(method) || "MERGE".equals(method)) {
-          client.header("X-HTTP-METHOD", method);
-          res = client.invoke("POST", IOUtils.toInputStream(content));
-        } else {
-          res = client.invoke(method, IOUtils.toInputStream(content));
-        }
-      }
-
-      // When updating to CXF 3.0.1, uncomment the following line, see CXF-5865
-      // client.close();
-    }
-
-    return res;
-  }
-
-  protected abstract InputStream exploreMultipart(
-      final List<Attachment> attachments, final String boundary, final boolean continueOnError)
-          throws IOException;
-
-  protected void addItemIntro(final ByteArrayOutputStream bos) throws IOException {
-    addItemIntro(bos, null);
-  }
-
-  protected void addItemIntro(final ByteArrayOutputStream bos, final String contentId) throws IOException {
-    bos.write("Content-Type: application/http".getBytes());
-    bos.write(Constants.CRLF);
-    bos.write("Content-Transfer-Encoding: binary".getBytes());
-    bos.write(Constants.CRLF);
-
-    if (StringUtils.isNotBlank(contentId)) {
-      bos.write(("Content-ID: " + contentId).getBytes());
-      bos.write(Constants.CRLF);
-    }
-
-    bos.write(Constants.CRLF);
-  }
-
-  protected void addChangesetItemIntro(
-      final ByteArrayOutputStream bos, final String contentId, final String cboundary) throws IOException {
-    bos.write(("--" + cboundary).getBytes());
-    bos.write(Constants.CRLF);
-    bos.write(("Content-ID: " + contentId).getBytes());
-    bos.write(Constants.CRLF);
-    addItemIntro(bos);
-  }
-
-  protected void addSingleBatchResponse(
-      final Response response, final ByteArrayOutputStream bos) throws IOException {
-    addSingleBatchResponse(response, null, bos);
-  }
-
-  protected void addSingleBatchResponse(
-      final Response response, final String contentId, final ByteArrayOutputStream bos) throws IOException {
-    bos.write("HTTP/1.1 ".getBytes());
-    bos.write(String.valueOf(response.getStatusInfo().getStatusCode()).getBytes());
-    bos.write(" ".getBytes());
-    bos.write(response.getStatusInfo().getReasonPhrase().getBytes());
-    bos.write(Constants.CRLF);
-
-    for (Map.Entry<String, List<Object>> header : response.getHeaders().entrySet()) {
-      final StringBuilder builder = new StringBuilder();
-      for (Object value : header.getValue()) {
-        if (builder.length() > 0) {
-          builder.append(", ");
-        }
-        builder.append(value.toString());
-      }
-      builder.insert(0, ": ").insert(0, header.getKey());
-      bos.write(builder.toString().getBytes());
-      bos.write(Constants.CRLF);
-    }
-
-    if (StringUtils.isNotBlank(contentId)) {
-      bos.write(("Content-ID: " + contentId).getBytes());
-      bos.write(Constants.CRLF);
-    }
-
-    bos.write(Constants.CRLF);
-
-    final Object entity = response.getEntity();
-    if (entity != null) {
-      bos.write(IOUtils.toByteArray((InputStream) entity));
-      bos.write(Constants.CRLF);
-    }
-
-    bos.write(Constants.CRLF);
-  }
-
-  protected void addErrorBatchResponse(final Exception e, final ByteArrayOutputStream bos)
-      throws IOException {
-    addErrorBatchResponse(e, null, bos);
-  }
-
-  protected void addErrorBatchResponse(final Exception e, final String contentId, final ByteArrayOutputStream bos)
-      throws IOException {
-    addSingleBatchResponse(xml.createFaultResponse(Accept.XML.toString(), e), contentId, bos);
-  }
-
-  @PATCH
-  @Path("/{entitySetName}({entityId})")
-  @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
-  @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
-  public Response patchEntity(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
-      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
-      @HeaderParam("If-Match") @DefaultValue(StringUtils.EMPTY) final String ifMatch,
-      @PathParam("entitySetName") final String entitySetName,
-      @PathParam("entityId") final String entityId,
-      final String changes) {
-
-    try {
-      final Accept acceptType = Accept.parse(accept);
-
-      if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
-        throw new UnsupportedMediaTypeException("Unsupported media type");
-      }
-
-      final Map.Entry<String, InputStream> entityInfo = xml.readEntity(entitySetName, entityId, Accept.ATOM);
-
-      final String etag = Commons.getETag(entityInfo.getKey());
-      if (StringUtils.isNotBlank(ifMatch) && !ifMatch.equals(etag)) {
-        throw new ConcurrentModificationException("Concurrent modification");
-      }
-
-      final Accept contentTypeValue = Accept.parse(contentType);
-
-      final Entity entryChanges;
-
-      if (contentTypeValue == Accept.XML || contentTypeValue == Accept.TEXT) {
-        throw new UnsupportedMediaTypeException("Unsupported media type");
-      } else if (contentTypeValue == Accept.ATOM) {
-        entryChanges = atomDeserializer.toEntity(
-            IOUtils.toInputStream(changes, Constants.ENCODING)).getPayload();
-      } else {
-        final ResWrap<Entity> jcont = jsonDeserializer.toEntity(IOUtils.toInputStream(changes, Constants.ENCODING));
-        entryChanges = jcont.getPayload();
-      }
-
-      final ResWrap<Entity> container = atomDeserializer.toEntity(entityInfo.getValue());
-
-      for (Property property : entryChanges.getProperties()) {
-        final Property _property = container.getPayload().getProperty(property.getName());
-        if (_property == null) {
-          container.getPayload().getProperties().add(property);
-        } else {
-          _property.setValue(property.getValueType(), property.getValue());
-        }
-      }
-
-      for (Link link : entryChanges.getNavigationLinks()) {
-        container.getPayload().getNavigationLinks().add(link);
-      }
-
-      final ByteArrayOutputStream content = new ByteArrayOutputStream();
-      final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
-      atomSerializer.write(writer, container);
-      writer.flush();
-      writer.close();
-
-      final InputStream res = xml.addOrReplaceEntity(
-          entityId, entitySetName, new ByteArrayInputStream(content.toByteArray()), container.getPayload());
-
-      final ResWrap<Entity> cres = atomDeserializer.toEntity(res);
-
-      normalizeAtomEntry(cres.getPayload(), entitySetName, entityId);
-
-      final String path = Commons.getEntityBasePath(entitySetName, entityId);
-      FSManager.instance(version).putInMemory(
-          cres, path + File.separatorChar + Constants.get(ConstantKey.ENTITY));
-
-      final Response response;
-      if ("return-content".equalsIgnoreCase(prefer)) {
-        response = xml.createResponse(
-            uriInfo.getRequestUri().toASCIIString(),
-            xml.readEntity(entitySetName, entityId, acceptType).getValue(),
-            null, acceptType, Response.Status.OK);
-      } else {
-        res.close();
-        response = xml.createResponse(
-            uriInfo.getRequestUri().toASCIIString(),
-            null,
-            null,
-            acceptType, Response.Status.NO_CONTENT);
-      }
-
-      if (StringUtils.isNotBlank(prefer)) {
-        response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
-      }
-
-      return response;
-    } catch (Exception e) {
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  @PUT
-  @Path("/{entitySetName}({entityId})")
-  @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
-  @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
-  public Response replaceEntity(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
-      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
-      @PathParam("entitySetName") final String entitySetName,
-      @PathParam("entityId") final String entityId,
-      final String entity) {
-
-    try {
-      final Accept acceptType = Accept.parse(accept);
-
-      if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
-        throw new UnsupportedMediaTypeException("Unsupported media type");
-      }
-
-      final InputStream res = getUtilities(acceptType).addOrReplaceEntity(entityId, entitySetName,
-          IOUtils.toInputStream(entity, Constants.ENCODING),
-          xml.readEntity(acceptType, IOUtils.toInputStream(entity, Constants.ENCODING)));
-
-      final ResWrap<Entity> cres;
-      if (acceptType == Accept.ATOM) {
-        cres = atomDeserializer.toEntity(res);
-      } else {
-        cres = jsonDeserializer.toEntity(res);
-      }
-
-      final String path = Commons.getEntityBasePath(entitySetName, entityId);
-      FSManager.instance(version).putInMemory(
-          cres, path + File.separatorChar + Constants.get(ConstantKey.ENTITY));
-
-      final Response response;
-      if ("return-content".equalsIgnoreCase(prefer)) {
-        response = xml.createResponse(
-            uriInfo.getRequestUri().toASCIIString(),
-            xml.readEntity(entitySetName, entityId, acceptType).getValue(),
-            null,
-            acceptType,
-            Response.Status.OK);
-      } else {
-        res.close();
-        response = xml.createResponse(
-            uriInfo.getRequestUri().toASCIIString(),
-            null,
-            null,
-            acceptType,
-            Response.Status.NO_CONTENT);
-      }
-
-      if (StringUtils.isNotBlank(prefer)) {
-        response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
-      }
-
-      return response;
-    } catch (Exception e) {
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  @POST
-  @Path("/{entitySetName}")
-  @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
-  @Consumes({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM })
-  public Response postNewEntity(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
-      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
-      @PathParam("entitySetName") final String entitySetName,
-      final String entity) {
-
-    try {
-      final Accept acceptType = Accept.parse(accept);
-      if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
-        throw new UnsupportedMediaTypeException("Unsupported media type");
-      }
-
-      final ResWrap<Entity> container;
-
-      final org.apache.olingo.fit.metadata.EntitySet entitySet = metadata.getEntitySet(entitySetName);
-
-      final Entity entry;
-      final String entityKey;
-      if (xml.isMediaContent(entitySetName)) {
-        entry = new Entity();
-        entry.setMediaContentType(ContentType.APPLICATION_OCTET_STREAM.toContentTypeString());
-        entry.setType(entitySet.getType());
-
-        entityKey = xml.getDefaultEntryKey(entitySetName, entry);
-
-        xml.addMediaEntityValue(entitySetName, entityKey, IOUtils.toInputStream(entity, Constants.ENCODING));
-
-        final Pair<String, EdmPrimitiveTypeKind> id = Commons.getMediaContent().get(entitySetName);
-        if (id != null) {
-          final Property prop = new Property();
-          prop.setName(id.getKey());
-          prop.setType(id.getValue().toString());
-          prop.setValue(ValueType.PRIMITIVE,
-              id.getValue() == EdmPrimitiveTypeKind.Int32
-              ? Integer.parseInt(entityKey)
-                  : id.getValue() == EdmPrimitiveTypeKind.Guid
-                  ? UUID.fromString(entityKey)
-                      : entityKey);
-          entry.getProperties().add(prop);
-        }
-
-        final Link editLink = new Link();
-        editLink.setHref(Commons.getEntityURI(entitySetName, entityKey));
-        editLink.setRel("edit");
-        editLink.setTitle(entitySetName);
-        entry.setEditLink(editLink);
-
-        entry.setMediaContentSource(URI.create(editLink.getHref() + "/$value"));
-
-        container = new ResWrap<Entity>((URI) null, null, entry);
-      } else {
-        final Accept contentTypeValue = Accept.parse(contentType);
-        if (Accept.ATOM == contentTypeValue) {
-          container = atomDeserializer.toEntity(IOUtils.toInputStream(entity, Constants.ENCODING));
-        } else {
-          container = jsonDeserializer.toEntity(IOUtils.toInputStream(entity, Constants.ENCODING));
-        }
-        entry = container.getPayload();
-        updateInlineEntities(entry);
-
-        entityKey = xml.getDefaultEntryKey(entitySetName, entry);
-      }
-
-      normalizeAtomEntry(entry, entitySetName, entityKey);
-
-      final ByteArrayOutputStream content = new ByteArrayOutputStream();
-      final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
-      atomSerializer.write(writer, container);
-      writer.flush();
-      writer.close();
-
-      final InputStream serialization =
-          xml.addOrReplaceEntity(entityKey, entitySetName, new ByteArrayInputStream(content.toByteArray()), entry);
-
-      ResWrap<Entity> result = atomDeserializer.toEntity(serialization);
-      result = new ResWrap<Entity>(
-          URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX)
-              + entitySetName + Constants.get(ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)),
-              null, result.getPayload());
-
-      final String path = Commons.getEntityBasePath(entitySetName, entityKey);
-      FSManager.instance(version).putInMemory(result, path + Constants.get(ConstantKey.ENTITY));
-
-      final String location;
-
-      if ((this instanceof KeyAsSegment)) {
-        location = uriInfo.getRequestUri().toASCIIString() + "/" + entityKey;
-
-        final Link editLink = new Link();
-        editLink.setRel("edit");
-        editLink.setTitle(entitySetName);
-        editLink.setHref(location);
-
-        result.getPayload().setEditLink(editLink);
-      } else {
-        location = uriInfo.getRequestUri().toASCIIString() + "(" + entityKey + ")";
-      }
-
-      final Response response;
-      if ("return-no-content".equalsIgnoreCase(prefer)) {
-        response = xml.createResponse(
-            location,
-            null,
-            null,
-            acceptType,
-            Response.Status.NO_CONTENT);
-      } else {
-        response = xml.createResponse(
-            location,
-            xml.writeEntity(acceptType, result),
-            null,
-            acceptType,
-            Response.Status.CREATED);
-      }
-
-      if (StringUtils.isNotBlank(prefer)) {
-        response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
-      }
-
-      return response;
-    } catch (Exception e) {
-      LOG.error("While creating new entity", e);
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  @POST
-  @Path("/Person({entityId})/{type:.*}/Sack")
-  public Response actionSack(
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("entityId") final String entityId,
-      @PathParam("type") final String type,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
-
-    final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
-
-    if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
-      throw new UnsupportedMediaTypeException("Unsupported media type");
-    }
-
-    try {
-      final Map.Entry<String, InputStream> entityInfo = xml.readEntity("Person", entityId, Accept.ATOM);
-
-      final InputStream entity = entityInfo.getValue();
-      final ResWrap<Entity> container = atomDeserializer.toEntity(entity);
-
-      container.getPayload().getProperty("Salary").setValue(ValueType.PRIMITIVE, 0);
-      container.getPayload().getProperty("Title").setValue(ValueType.PRIMITIVE, "[Sacked]");
-
-      final FSManager fsManager = FSManager.instance(version);
-      fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
-          fsManager.getAbsolutePath(Commons.getEntityBasePath("Person", entityId) + Constants.get(
-              ConstantKey.ENTITY), Accept.ATOM));
-
-      return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
-    } catch (Exception e) {
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  @POST
-  @Path("/Person/{type:.*}/IncreaseSalaries")
-  public Response actionIncreaseSalaries(
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("type") final String type,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
-      final String body) {
-
-    final String name = "Person";
-    try {
-      final Accept acceptType = Accept.parse(accept);
-      if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
-        throw new UnsupportedMediaTypeException("Unsupported media type");
-      }
-
-      final JsonNode tree = new ObjectMapper().readTree(body);
-      if (!tree.has("n")) {
-        throw new Exception("Missing parameter: n");
-      }
-      final int n = tree.get("n").asInt();
-
-      final StringBuilder path = new StringBuilder(name).
-          append(File.separatorChar).append(type).
-          append(File.separatorChar);
-
-      path.append(metadata.getEntitySet(name).isSingleton()
-          ? Constants.get(ConstantKey.ENTITY)
-              : Constants.get(ConstantKey.FEED));
-
-      final InputStream feed = FSManager.instance(version).readFile(path.toString(), acceptType);
-
-      final ByteArrayOutputStream copy = new ByteArrayOutputStream();
-      IOUtils.copy(feed, copy);
-      IOUtils.closeQuietly(feed);
-
-      String newContent = new String(copy.toByteArray(), "UTF-8");
-      final Pattern salary = Pattern.compile(acceptType == Accept.ATOM
-          ? "\\<d:Salary m:type=\"Edm.Int32\"\\>(-?\\d+)\\</d:Salary\\>"
-              : "\"Salary\":(-?\\d+),");
-      final Matcher salaryMatcher = salary.matcher(newContent);
-      while (salaryMatcher.find()) {
-        final Long newSalary = Long.valueOf(salaryMatcher.group(1)) + n;
-        newContent = newContent.
-            replaceAll("\"Salary\":" + salaryMatcher.group(1) + ",",
-                "\"Salary\":" + newSalary + ",").
-                replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>" + salaryMatcher.group(1) + "</d:Salary\\>",
-                    "<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
-      }
-
-      FSManager.instance(version).putInMemory(IOUtils.toInputStream(newContent, Constants.ENCODING),
-          FSManager.instance(version).getAbsolutePath(path.toString(), acceptType));
-
-      return xml.createResponse(null, null, null, acceptType, Response.Status.NO_CONTENT);
-    } catch (Exception e) {
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  @POST
-  @Path("/Product({entityId})/ChangeProductDimensions")
-  public Response actionChangeProductDimensions(
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("entityId") final String entityId,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
-      final String argument) {
-
-    final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
-
-    if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
-      throw new UnsupportedMediaTypeException("Unsupported media type");
-    }
-
-    try {
-      final Map.Entry<String, InputStream> entityInfo = xml.readEntity("Product", entityId, Accept.ATOM);
-
-      final InputStream entity = entityInfo.getValue();
-      final ResWrap<Entity> container = atomDeserializer.toEntity(entity);
-
-      final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING));
-
-      final Property property = param.getProperty("dimensions");
-      container.getPayload().getProperty("Dimensions").setValue(property.getValueType(), property.getValue());
-
-      final FSManager fsManager = FSManager.instance(version);
-      fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
-          fsManager.getAbsolutePath(Commons.getEntityBasePath("Product", entityId) + Constants.get(
-              ConstantKey.ENTITY), Accept.ATOM));
-
-      return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
-    } catch (Exception e) {
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  @POST
-  @Path("/ComputerDetail({entityId})/ResetComputerDetailsSpecifications")
-  public Response actionResetComputerDetailsSpecifications(
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("entityId") final String entityId,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
-      final String argument) {
-
-    final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
-
-    if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
-      throw new UnsupportedMediaTypeException("Unsupported media type");
-    }
-
-    try {
-      final Map.Entry<String, InputStream> entityInfo = xml.readEntity("ComputerDetail", entityId, Accept.ATOM);
-
-      final InputStream entity = entityInfo.getValue();
-      final ResWrap<Entity> container = atomDeserializer.toEntity(entity);
-
-      final Entity param = xml.readEntity(utils.getKey(), IOUtils.toInputStream(argument, Constants.ENCODING));
-
-      Property property = param.getProperty("specifications");
-      container.getPayload().getProperty("SpecificationsBag").setValue(property.getValueType(), property.getValue());
-      property = param.getProperty("purchaseTime");
-      container.getPayload().getProperty("PurchaseDate").setValue(property.getValueType(), property.getValue());
-
-      final FSManager fsManager = FSManager.instance(version);
-      fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
-          fsManager.getAbsolutePath(Commons.getEntityBasePath("ComputerDetail", entityId) + Constants.get(
-              ConstantKey.ENTITY), Accept.ATOM));
-
-      return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
-    } catch (Exception e) {
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  /**
-   * Retrieve entities from the given entity set and the given type.
-   *
-   * @param accept Accept header.
-   * @param name entity set.
-   * @param type entity type.
-   * @return entity set.
-   */
-  @GET
-  @Path("/{name}/{type:[a-zA-Z].*}")
-  public Response getEntitySet(
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("name") final String name,
-      @PathParam("type") final String type) {
-
-    try {
-      final Accept acceptType = Accept.parse(accept);
-      if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
-        throw new UnsupportedMediaTypeException("Unsupported media type");
-      }
-
-      final String basePath = name + File.separatorChar;
-      final StringBuilder path = new StringBuilder(name).
-          append(File.separatorChar).append(type).
-          append(File.separatorChar);
-
-      path.append(metadata.getEntitySet(name).isSingleton()
-          ? Constants.get(ConstantKey.ENTITY)
-              : Constants.get(ConstantKey.FEED));
-
-      final InputStream feed = FSManager.instance(version).readFile(path.toString(), acceptType);
-      return xml.createResponse(null, feed, Commons.getETag(basePath), acceptType);
-    } catch (Exception e) {
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  @GET
-  @Path("/{name}/{type:[a-zA-Z].*}")
-  public Response getEntitySet(@Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("name") final String name,
-      @QueryParam("$top") @DefaultValue(StringUtils.EMPTY) final String top,
-      @QueryParam("$skip") @DefaultValue(StringUtils.EMPTY) final String skip,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
-      @QueryParam("$count") @DefaultValue(StringUtils.EMPTY) final String count,
-      @QueryParam("$filter") @DefaultValue(StringUtils.EMPTY) final String filter,
-      @QueryParam("$orderby") @DefaultValue(StringUtils.EMPTY) final String orderby,
-      @QueryParam("$skiptoken") @DefaultValue(StringUtils.EMPTY) final String skiptoken,
-      @PathParam("type") final String type) {
-
-    try {
-      final Accept acceptType;
-      if (StringUtils.isNotBlank(format)) {
-        acceptType = Accept.valueOf(format.toUpperCase());
-      } else {
-        acceptType = Accept.parse(accept);
-      }
-
-      final String location = uriInfo.getRequestUri().toASCIIString();
-      try {
-        // search for function ...
-        final InputStream func = FSManager.instance(version).readFile(name, acceptType);
-        return xml.createResponse(location, func, null, acceptType);
-      } catch (NotFoundException e) {
-        if (acceptType == Accept.XML || acceptType == Accept.TEXT) {
-          throw new UnsupportedMediaTypeException("Unsupported media type");
-        }
-
-        // search for entitySet ...
-        final String basePath = name + File.separatorChar;
-
-        final StringBuilder builder = new StringBuilder();
-        builder.append(basePath);
-
-        if (type != null) {
-          builder.append(type).append(File.separatorChar);
-        }
-
-        if (StringUtils.isNotBlank(orderby)) {
-          builder.append(Constants.get(ConstantKey.ORDERBY)).append(File.separatorChar).
-          append(orderby).append(File.separatorChar);
-        }
-
-        if (StringUtils.isNotBlank(filter)) {
-          builder.append(Constants.get(ConstantKey.FILTER)).append(File.separatorChar).
-          append(filter.replaceAll("/", "."));
-        } else if (StringUtils.isNotBlank(skiptoken)) {
-          builder.append(Constants.get(ConstantKey.SKIP_TOKEN)).append(File.separatorChar).
-          append(skiptoken);
-        } else {
-          builder.append(metadata.getEntitySet(name).isSingleton()
-              ? Constants.get(ConstantKey.ENTITY)
-                  : Constants.get(ConstantKey.FEED));
-        }
-
-        final InputStream feed = FSManager.instance(version).readFile(builder.toString(), Accept.ATOM);
-
-        final ResWrap<EntityCollection> container = atomDeserializer.toEntitySet(feed);
-
-        setInlineCount(container.getPayload(), count);
-
-        final ByteArrayOutputStream content = new ByteArrayOutputStream();
-        final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
-
-        // -----------------------------------------------
-        // Evaluate $skip and $top
-        // -----------------------------------------------
-        List<Entity> entries = new ArrayList<Entity>(container.getPayload().getEntities());
-
-        if (StringUtils.isNotBlank(skip)) {
-          entries = entries.subList(Integer.valueOf(skip), entries.size());
-        }
-
-        if (StringUtils.isNotBlank(top)) {
-          entries = entries.subList(0, Integer.valueOf(top));
-        }
-
-        container.getPayload().getEntities().clear();
-        container.getPayload().getEntities().addAll(entries);
-        // -----------------------------------------------
-
-        if (acceptType == Accept.ATOM) {
-          atomSerializer.write(writer, container);
-        } else {
-          jsonSerializer.write(writer, container);
-        }
-        writer.flush();
-        writer.close();
-
-        return xml.createResponse(
-            location,
-            new ByteArrayInputStream(content.toByteArray()),
-            Commons.getETag(basePath),
-            acceptType);
-      }
-    } catch (Exception e) {
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  /**
-   * Retrieve entity set or function execution sample.
-   *
-   * @param accept Accept header.
-   * @param name entity set or function name.
-   * @param format format query option.
-   * @param count count query option.
-   * @param filter filter query option.
-   * @param orderby orderby query option.
-   * @param skiptoken skiptoken query option.
-   * @return entity set or function result.
-   */
-  @GET
-  @Path("/{name}")
-  public Response getEntitySet(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("name") final String name,
-      @QueryParam("$top") @DefaultValue(StringUtils.EMPTY) final String top,
-      @QueryParam("$skip") @DefaultValue(StringUtils.EMPTY) final String skip,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
-      @QueryParam("$count") @DefaultValue(StringUtils.EMPTY) final String count,
-      @QueryParam("$filter") @DefaultValue(StringUtils.EMPTY) final String filter,
-      @QueryParam("$orderby") @DefaultValue(StringUtils.EMPTY) final String orderby,
-      @QueryParam("$skiptoken") @DefaultValue(StringUtils.EMPTY) final String skiptoken) {
-
-    return getEntitySet(uriInfo, accept, name, top, skip, format, count, filter, orderby, skiptoken, null);
-  }
-
-  protected abstract void setInlineCount(final EntityCollection feed, final String count);
-
-  @GET
-  @Path("/Person({entityId})")
-  public Response getPerson(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("entityId") final String entityId,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
-
-    final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
-
-    final Response internal = getEntityInternal(
-        uriInfo.getRequestUri().toASCIIString(), accept, "Person", entityId, format, null, null);
-    if (internal.getStatus() == 200) {
-      InputStream entity = (InputStream) internal.getEntity();
-      try {
-        if (utils.getKey() == Accept.JSON_FULLMETA || utils.getKey() == Accept.ATOM) {
-          entity = utils.getValue().addOperation(entity, "Sack", "#DefaultContainer.Sack",
-              uriInfo.getAbsolutePath().toASCIIString()
-              + "/Microsoft.Test.OData.Services.AstoriaDefaultService.SpecialEmployee/Sack");
-        }
-
-        return utils.getValue().createResponse(
-            uriInfo.getRequestUri().toASCIIString(),
-            entity,
-            internal.getHeaderString("ETag"),
-            utils.getKey());
-      } catch (Exception e) {
-        LOG.error("Error retrieving entity", e);
-        return xml.createFaultResponse(accept, e);
-      }
-    } else {
-      return internal;
-    }
-  }
-
-  @GET
-  @Path("/Product({entityId})")
-  public Response getProduct(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("entityId") final String entityId,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
-
-    final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
-
-    final Response internal = getEntityInternal(
-        uriInfo.getRequestUri().toASCIIString(), accept, "Product", entityId, format, null, null);
-    if (internal.getStatus() == 200) {
-      InputStream entity = (InputStream) internal.getEntity();
-      try {
-        if (utils.getKey() == Accept.JSON_FULLMETA || utils.getKey() == Accept.ATOM) {
-          entity = utils.getValue().addOperation(entity,
-              "ChangeProductDimensions", "#DefaultContainer.ChangeProductDimensions",
-              uriInfo.getAbsolutePath().toASCIIString() + "/ChangeProductDimensions");
-        }
-
-        return utils.getValue().createResponse(
-            uriInfo.getRequestUri().toASCIIString(),
-            entity,
-            internal.getHeaderString("ETag"),
-            utils.getKey());
-      } catch (Exception e) {
-        LOG.error("Error retrieving entity", e);
-        return xml.createFaultResponse(accept, e);
-      }
-    } else {
-      return internal;
-    }
-  }
-
-  @GET
-  @Path("/ComputerDetail({entityId})")
-  public Response getComputerDetail(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("entityId") final String entityId,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
-
-    final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
-
-    final Response internal = getEntityInternal(
-        uriInfo.getRequestUri().toASCIIString(), accept, "ComputerDetail", entityId, format, null, null);
-    if (internal.getStatus() == 200) {
-      InputStream entity = (InputStream) internal.getEntity();
-      try {
-        if (utils.getKey() == Accept.JSON_FULLMETA || utils.getKey() == Accept.ATOM) {
-          entity = utils.getValue().addOperation(entity,
-              "ResetComputerDetailsSpecifications", "#DefaultContainer.ResetComputerDetailsSpecifications",
-              uriInfo.getAbsolutePath().toASCIIString() + "/ResetComputerDetailsSpecifications");
-        }
-
-        return utils.getValue().createResponse(
-            uriInfo.getRequestUri().toASCIIString(),
-            entity,
-            internal.getHeaderString("ETag"),
-            utils.getKey());
-      } catch (Exception e) {
-        LOG.error("Error retrieving entity", e);
-        return xml.createFaultResponse(accept, e);
-      }
-    } else {
-      return internal;
-    }
-  }
-
-  /**
-   * Retrieve entity sample.
-   *
-   * @param accept Accept header.
-   * @param entitySetName Entity set name.
-   * @param entityId entity id.
-   * @param format format query option.
-   * @param expand expand query option.
-   * @param select select query option.
-   * @return entity.
-   */
-  @GET
-  @Path("/{entitySetName}({entityId})")
-  public Response getEntity(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("entitySetName") final String entitySetName,
-      @PathParam("entityId") final String entityId,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
-      @QueryParam("$expand") @DefaultValue(StringUtils.EMPTY) final String expand,
-      @QueryParam("$select") @DefaultValue(StringUtils.EMPTY) final String select) {
-
-    return getEntityInternal(
-        uriInfo.getRequestUri().toASCIIString(), accept, entitySetName, entityId, format, expand, select);
-  }
-
-  protected Response getEntityInternal(
-      final String location,
-      final String accept,
-      final String entitySetName,
-      final String entityId,
-      final String format,
-      final String expand,
-      final String select) {
-
-    try {
-      final Map.Entry<Accept, AbstractUtilities> utils = getUtilities(accept, format);
-
-      if (utils.getKey() == Accept.XML || utils.getKey() == Accept.TEXT) {
-        throw new UnsupportedMediaTypeException("Unsupported media type");
-      }
-
-      final Map.Entry<String, InputStream> entityInfo =
-          utils.getValue().readEntity(entitySetName, entityId, Accept.ATOM);
-
-      final InputStream entity = entityInfo.getValue();
-
-      ResWrap<Entity> container = atomDeserializer.toEntity(entity);
-      if (container.getContextURL() == null) {
-        container = new ResWrap<Entity>(URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX)
-            + entitySetName + Constants.get(ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)),
-            container.getMetadataETag(), container.getPayload());
-      }
-      final Entity entry = container.getPayload();
-
-      if ((this instanceof KeyAsSegment)) {
-        final Link editLink = new Link();
-        editLink.setRel("edit");
-        editLink.setTitle(entitySetName);
-        editLink.setHref(Constants.get(ConstantKey.DEFAULT_SERVICE_URL) + entitySetName + "/" + entityId);
-
-        entry.setEditLink(editLink);
-      }
-
-      if (StringUtils.isNotBlank(select)) {
-        final List<String> properties = Arrays.asList(select.split(","));
-        final Set<Property> toBeRemoved = new HashSet<Property>();
-
-        for (Property property : entry.getProperties()) {
-          if (!properties.contains(property.getName())) {
-            toBeRemoved.add(property);
-          }
-        }
-
-        entry.getProperties().removeAll(toBeRemoved);
-
-        final Set<Link> linkToBeRemoved = new HashSet<Link>();
-
-        for (Link link : entry.getNavigationLinks()) {
-          if (!properties.contains(link.getTitle().replaceAll("@.*$", "")) && !properties.contains(link.getTitle())) {
-            linkToBeRemoved.add(link);
-          }
-        }
-
-        entry.getNavigationLinks().removeAll(linkToBeRemoved);
-      }
-
-      String tempExpand = expand;
-      if (StringUtils.isNotBlank(tempExpand)) {
-        tempExpand = StringUtils.substringBefore(tempExpand, "(");
-        final List<String> links = Arrays.asList(tempExpand.split(","));
-
-        final Map<Link, Link> replace = new HashMap<Link, Link>();
-
-        for (Link link : entry.getNavigationLinks()) {
-          if (links.contains(link.getTitle())) {
-            // expand link
-            final Link rep = new Link();
-            rep.setHref(link.getHref());
-            rep.setRel(link.getRel());
-            rep.setTitle(link.getTitle());
-            rep.setType(link.getType());
-            if (link.getType().equals(Constants.get(ConstantKey.ATOM_LINK_ENTRY))) {
-              // inline entry
-              final Entity inline = atomDeserializer.toEntity(
-                  xml.expandEntity(entitySetName, entityId, link.getTitle())).getPayload();
-              rep.setInlineEntity(inline);
-            } else if (link.getType().equals(Constants.get(ConstantKey.ATOM_LINK_FEED))) {
-              // inline feed
-              final EntityCollection inline = atomDeserializer.toEntitySet(
-                  xml.expandEntity(entitySetName, entityId, link.getTitle())).getPayload();
-              rep.setInlineEntitySet(inline);
-            }
-            replace.put(link, rep);
-          }
-        }
-
-        for (Map.Entry<Link, Link> link : replace.entrySet()) {
-          entry.getNavigationLinks().remove(link.getKey());
-          entry.getNavigationLinks().add(link.getValue());
-        }
-      }
-
-      return xml.createResponse(
-          location,
-          xml.writeEntity(utils.getKey(), container),
-          Commons.getETag(entityInfo.getKey()),
-          utils.getKey());
-    } catch (Exception e) {
-      LOG.error("Error retrieving entity", e);
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  @GET
-  @Path("/{entitySetName}({entityId})/$value")
-  public Response getMediaEntity(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("entitySetName") final String entitySetName,
-      @PathParam("entityId") final String entityId) {
-
-    try {
-      if (!accept.contains("*/*") && !accept.contains("application/octet-stream")) {
-        throw new UnsupportedMediaTypeException("Unsupported media type");
-      }
-
-      final AbstractUtilities utils = getUtilities(null);
-      final Map.Entry<String, InputStream> entityInfo = utils.readMediaEntity(entitySetName, entityId);
-      return utils.createResponse(
-          uriInfo.getRequestUri().toASCIIString(),
-          entityInfo.getValue(),
-          Commons.getETag(entityInfo.getKey()),
-          null);
-
-    } catch (Exception e) {
-      LOG.error("Error retrieving entity", e);
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  @DELETE
-  @Path("/{entitySetName}({entityId})")
-  public Response removeEntity(
-      @PathParam("entitySetName") final String entitySetName,
-      @PathParam("entityId") final String entityId) {
-
-    try {
-      final String basePath = entitySetName + File.separatorChar + Commons.getEntityKey(entityId);
-
-      FSManager.instance(version).deleteEntity(basePath);
-
-      return xml.createResponse(null, null, null, null, Response.Status.NO_CONTENT);
-    } catch (Exception e) {
-      return xml.createFaultResponse(Accept.XML.toString(), e);
-    }
-  }
-
-  private Response replaceProperty(
-      final String location,
-      final String accept,
-      final String contentType,
-      final String prefer,
-      final String entitySetName,
-      final String entityId,
-      final String path,
-      final String format,
-      final String changes,
-      final boolean justValue) {
-
-    // if the given path is not about any link then search for property
-    LOG.info("Retrieve property {}", path);
-
-    try {
-      final FSManager fsManager = FSManager.instance(version);
-      final String basePath = Commons.getEntityBasePath(entitySetName, entityId);
-
-      final ResWrap<Entity> container = xml.readContainerEntity(Accept.ATOM,
-          fsManager.readFile(basePath + Constants.get(ConstantKey.ENTITY), Accept.ATOM));
-
-      final Entity entry = container.getPayload();
-
-      Property toBeReplaced = null;
-      for (String element : path.split("/")) {
-        if (toBeReplaced == null) {
-          toBeReplaced = entry.getProperty(element.trim());
-        } else {
-          List<Property> value = toBeReplaced.asComplex().getValue();
-          for (Property field : value) {
-            if (field.getName().equalsIgnoreCase(element)) {
-              toBeReplaced = field;
-            }
-          }
-        }
-      }
-
-      if (toBeReplaced == null) {
-        throw new NotFoundException();
-      }
-
-      if (justValue) {
-        // just for primitive values
-        toBeReplaced.setValue(ValueType.PRIMITIVE, changes);
-      } else {
-        final Property pchanges = xml.readProperty(
-            Accept.parse(contentType),
-            IOUtils.toInputStream(changes, Constants.ENCODING));
-
-        toBeReplaced.setValue(pchanges.getValueType(), pchanges.getValue());
-      }
-
-      fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
-          fsManager.getAbsolutePath(basePath + Constants.get(ConstantKey.ENTITY), Accept.ATOM));
-
-      final Response response;
-      if ("return-content".equalsIgnoreCase(prefer)) {
-        response = getEntityInternal(location, accept, entitySetName, entityId, format, null, null);
-      } else {
-        Accept acceptType = null;
-        if (StringUtils.isNotBlank(format)) {
-          acceptType = Accept.valueOf(format.toUpperCase());
-        } else if (StringUtils.isNotBlank(accept)) {
-          acceptType = Accept.parse(accept, null);
-        }
-
-        response = xml.createResponse(null, null, null, acceptType, Response.Status.NO_CONTENT);
-      }
-
-      if (StringUtils.isNotBlank(prefer)) {
-        response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
-      }
-
-      return response;
-    } catch (Exception e) {
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  private Response deletePropertyValue(
-      final String accept,
-      final String prefer,
-      final String entitySetName,
-      final String entityId,
-      final String path,
-      final String format) {
-    try {
-      Accept acceptType = null;
-      if (StringUtils.isNotBlank(format)) {
-        acceptType = Accept.valueOf(format.toUpperCase());
-      } else if (StringUtils.isNotBlank(accept)) {
-        acceptType = Accept.parse(accept, null);
-      }
-
-      // if the given path is not about any link then search for property
-      LOG.info("Retrieve property {}", path);
-
-      final AbstractUtilities utils = getUtilities(acceptType);
-
-      final InputStream changed = utils.deleteProperty(
-          entitySetName,
-          entityId,
-          Arrays.asList(path.split("/")),
-          acceptType);
-
-      final Response response;
-      if ("return-content".equalsIgnoreCase(prefer)) {
-        response = xml.createResponse(null, changed, null, acceptType, Response.Status.OK);
-      } else {
-        changed.close();
-        response = xml.createResponse(null, null, null, acceptType, Response.Status.NO_CONTENT);
-      }
-
-      if (StringUtils.isNotBlank(prefer)) {
-        response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
-      }
-
-      return response;
-
-    } catch (Exception e) {
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  /**
-   * Replace property value.
-   *
-   * @param accept
-   * @param entitySetName
-   * @param entityId
-   * @param path
-   * @param format
-   * @param changes
-   * @return response
-   */
-  @PUT
-  @Path("/{entitySetName}({entityId})/{path:.*}/$value")
-  public Response replacePropertyValue(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
-      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
-      @PathParam("entitySetName") final String entitySetName,
-      @PathParam("entityId") final String entityId,
-      @PathParam("path") final String path,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
-      final String changes) {
-
-    return replaceProperty(uriInfo.getRequestUri().toASCIIString(),
-        accept, contentType, prefer, entitySetName, entityId, path, format, changes, true);
-  }
-
-  /**
-   * Replace property.
-   *
-   * @param accept
-   * @param entitySetName
-   * @param entityId
-   * @param path
-   * @param format
-   * @param changes
-   * @return response
-   */
-  @PATCH
-  @Path("/{entitySetName}({entityId})/{path:.*}")
-  public Response patchProperty(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
-      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
-      @PathParam("entitySetName") final String entitySetName,
-      @PathParam("entityId") final String entityId,
-      @PathParam("path") final String path,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
-      final String changes) {
-
-    return replaceProperty(uriInfo.getRequestUri().toASCIIString(),
-        accept, contentType, prefer, entitySetName, entityId, path, format, changes, false);
-  }
-
-  @PUT
-  @Produces({ MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON })
-  @Consumes({ MediaType.WILDCARD, MediaType.APPLICATION_OCTET_STREAM })
-  @Path("/{entitySetName}({entityId})/$value")
-  public Response replaceMediaEntity(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
-      @PathParam("entitySetName") final String entitySetName,
-      @PathParam("entityId") final String entityId,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
-      final String value) {
-    try {
-
-      final AbstractUtilities utils = getUtilities(null);
-
-      final InputStream res = utils.putMediaInMemory(
-          entitySetName, entityId, IOUtils.toInputStream(value, Constants.ENCODING));
-
-      final String location = uriInfo.getRequestUri().toASCIIString().replace("/$value", "");
-
-      final Response response;
-      if ("return-content".equalsIgnoreCase(prefer)) {
-        response = xml.createResponse(location, res, null, null, Response.Status.OK);
-      } else {
-        res.close();
-        response = xml.createResponse(location, null, null, null, Response.Status.NO_CONTENT);
-      }
-
-      if (StringUtils.isNotBlank(prefer)) {
-        response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
-      }
-
-      return response;
-
-    } catch (Exception e) {
-      LOG.error("Error retrieving entity", e);
-      return xml.createFaultResponse(Accept.JSON.toString(), e);
-    }
-  }
-
-  /**
-   * Replace property.
-   *
-   * @param accept
-   * @param entitySetName
-   * @param entityId
-   * @param path
-   * @param format
-   * @param changes
-   * @return response
-   */
-  @PUT
-  @Path("/{entitySetName}({entityId})/{path:.*}")
-  public Response replaceProperty(
-      @Context final UriInfo uriInfo,
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
-      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
-      @PathParam("entitySetName") final String entitySetName,
-      @PathParam("entityId") final String entityId,
-      @PathParam("path") final String path,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
-      final String changes) {
-
-    if (xml.isMediaContent(entitySetName + "/" + path)) {
-      return replaceMediaProperty(prefer, entitySetName, entityId, path, changes);
-    } else {
-      return replaceProperty(uriInfo.getRequestUri().toASCIIString(),
-          accept, contentType, prefer, entitySetName, entityId, path, format, changes, false);
-    }
-  }
-
-  private Response replaceMediaProperty(
-      final String prefer,
-      final String entitySetName,
-      final String entityId,
-      final String path,
-      final String value) {
-
-    try {
-      final AbstractUtilities utils = getUtilities(null);
-
-      InputStream res = utils.putMediaInMemory(
-          entitySetName, entityId, path, IOUtils.toInputStream(value, Constants.ENCODING));
-
-      final Response response;
-      if ("return-content".equalsIgnoreCase(prefer)) {
-        response = xml.createResponse(null, res, null, null, Response.Status.OK);
-      } else {
-        res.close();
-        response = xml.createResponse(null, null, null, null, Response.Status.NO_CONTENT);
-      }
-
-      if (StringUtils.isNotBlank(prefer)) {
-        response.getHeaders().put("Preference-Applied", Collections.<Object> singletonList(prefer));
-      }
-
-      return response;
-    } catch (Exception e) {
-      LOG.error("Error retrieving entity", e);
-      return xml.createFaultResponse(Accept.JSON.toString(), e);
-    }
-  }
-
-  /**
-   * Nullify property value.
-   *
-   * @param accept
-   * @param entitySetName
-   * @param entityId
-   * @param path
-   * @param format
-   * @return response
-   */
-  @DELETE
-  @Path("/{entitySetName}({entityId})/{path:.*}/$value")
-  public Response deleteProperty(
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
-      @PathParam("entitySetName") final String entitySetName,
-      @PathParam("entityId") final String entityId,
-      @PathParam("path") final String path,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
-    return deletePropertyValue(accept, prefer, entitySetName, entityId, path, format);
-  }
-
-  /**
-   * Retrieve property sample.
-   *
-   * @param accept Accept header.
-   * @param entitySetName Entity set name.
-   * @param entityId entity id.
-   * @param path path.
-   * @param format format query option.
-   * @return property.
-   */
-  @GET
-  @Path("/{entitySetName}({entityId})/{path:.*}/$value")
-  public Response getPathValue(
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("entitySetName") final String entitySetName,
-      @PathParam("entityId") final String entityId,
-      @PathParam("path") final String path,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
-
-    try {
-      Accept acceptType = null;
-      if (StringUtils.isNotBlank(format)) {
-        acceptType = Accept.valueOf(format.toUpperCase());
-      } else if (StringUtils.isNotBlank(accept)) {
-        acceptType = Accept.parse(accept, null);
-      }
-
-      return navigateProperty(acceptType, entitySetName, entityId, path, true);
-    } catch (Exception e) {
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  /**
-   * Retrieve property sample.
-   *
-   * @param accept Accept header.
-   * @param entitySetName Entity set name.
-   * @param entityId entity id.
-   * @param path path.
-   * @param format format query option.
-   * @return property.
-   */
-  @GET
-  @Path("/{entitySetName}({entityId})/{path:.*}")
-  public Response getPath(
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("entitySetName") final String entitySetName,
-      @PathParam("entityId") final String entityId,
-      @PathParam("path") final String path,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format) {
-
-    // default utilities
-    final AbstractUtilities utils = xml;
-
-    try {
-      if (utils.isMediaContent(entitySetName + "/" + path)) {
-        return navigateStreamedEntity(entitySetName, entityId, path);
-      } else {
-        Accept acceptType = null;
-        if (StringUtils.isNotBlank(format)) {
-          acceptType = Accept.valueOf(format.toUpperCase());
-        } else if (StringUtils.isNotBlank(accept)) {
-          acceptType = Accept.parse(accept, null);
-        }
-
-        try {
-          final LinkInfo linkInfo = xml.readLinks(entitySetName, entityId, path, Accept.XML);
-          final Map.Entry<String, List<String>> links = xml.extractLinkURIs(linkInfo.getLinks());
-          final InputStream stream = xml.readEntities(links.getValue(), path, links.getKey(), linkInfo.isFeed());
-
-          final ByteArrayOutputStream content = new ByteArrayOutputStream();
-          final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
-
-          final ResWrap<?> container = linkInfo.isFeed() ? atomDeserializer.toEntitySet(stream) : atomDeserializer.
-              toEntity(stream);
-          if (acceptType == Accept.ATOM) {
-            atomSerializer.write(writer, container);
-          } else {
-            jsonSerializer.write(writer, container);
-          }
-          writer.flush();
-          writer.close();
-
-          final String basePath = Commons.getEntityBasePath(entitySetName, entityId);
-
-          return xml.createResponse(
-              null,
-              new ByteArrayInputStream(content.toByteArray()),
-              Commons.getETag(basePath),
-              acceptType);
-
-        } catch (NotFoundException e) {
-          // if the given path is not about any link then search for property
-          return navigateProperty(acceptType, entitySetName, entityId, path, false);
-        }
-      }
-    } catch (Exception e) {
-      return utils.createFaultResponse(accept, e);
-    }
-  }
-
-  private Response navigateStreamedEntity(
-      final String entitySetName,
-      final String entityId,
-      final String path) throws Exception {
-
-    final AbstractUtilities utils = getUtilities(null);
-    final Map.Entry<String, InputStream> entityInfo = utils.readMediaEntity(entitySetName, entityId, path);
-    return utils.createResponse(null, entityInfo.getValue(), Commons.getETag(entityInfo.getKey()), null);
-  }
-
-  private Response navigateProperty(
-      final Accept acceptType,
-      final String entitySetName,
-      final String entityId,
-      final String path,
-      final boolean searchForValue) throws Exception {
-
-    if ((searchForValue && acceptType != null && acceptType != Accept.TEXT) || acceptType == Accept.ATOM) {
-      throw new UnsupportedMediaTypeException("Unsupported media type " + acceptType);
-    }
-
-    final AbstractUtilities utils = getUtilities(acceptType);
-
-    final Map.Entry<String, InputStream> entityInfo = utils.readEntity(entitySetName, entityId, Accept.ATOM);
-
-    final InputStream entity = entityInfo.getValue();
-
-    final ResWrap<Entity> entryContainer = atomDeserializer.toEntity(entity);
-
-    final String[] pathElems = StringUtils.split(path, "/");
-    Property property = entryContainer.getPayload().getProperty(pathElems[0]);
-    if (pathElems.length > 1 && property.isComplex()) {
-      for (Property sub : property.asComplex().getValue()) {
-        if (pathElems[1].equals(sub.getName())) {
-          property = sub;
-          if (pathElems.length > 2 && property.isComplex()) {
-            for (Property subsub : property.asComplex().getValue()) {
-              if (pathElems[2].equals(subsub.getName())) {
-                property = subsub;
-              }
-            }
-          }
-        }
-      }
-    }
-
-    final ResWrap<Property> container = new ResWrap<Property>(
-        URI.create(Constants.get(ConstantKey.ODATA_METADATA_PREFIX) + entitySetName + "(" + entityId + ")/" + path),
-        entryContainer.getMetadataETag(),
-        property);
-
-    return xml.createResponse(null,
-        searchForValue ? IOUtils.toInputStream(
-            container.getPayload().isNull() ? StringUtils.EMPTY : stringValue(container.getPayload()),
-                Constants.ENCODING) : utils.writeProperty(acceptType, container),
-                Commons.getETag(Commons.getEntityBasePath(entitySetName, entityId)),
-                acceptType);
-  }
-
-  private String stringValue(final Property property) {
-    EdmPrimitiveTypeKind kind = EdmPrimitiveTypeKind.valueOfFQN(property.getType());
-    try {
-      return EdmPrimitiveTypeFactory.getInstance(kind)
-          .valueToString(property.asPrimitive(), null, null,
-              org.apache.olingo.commons.api.Constants.DEFAULT_PRECISION,
-              org.apache.olingo.commons.api.Constants.DEFAULT_SCALE, null);
-    } catch (final EdmPrimitiveTypeException e) {
-      return property.asPrimitive().toString();
-    }
-  }
-
-  /**
-   * Count sample.
-   *
-   * @param accept Accept header.
-   * @param entitySetName entity set name.
-   * @return count.
-   */
-  @GET
-  @Path("/{entitySetName}/$count")
-  public Response count(
-      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
-      @PathParam("entitySetName") final String entitySetName) {
-    try {
-      final Accept acceptType = Accept.parse(accept, Accept.TEXT);
-
-      if (acceptType != Accept.TEXT) {
-        throw new UnsupportedMediaTypeException("Unsupported type " + accept);
-      }
-
-      int count = xml.countAllElements(entitySetName);
-
-      final Response.ResponseBuilder builder = Response.ok();
-      builder.entity(count);
-
-      return builder.build();
-    } catch (Exception e) {
-      return xml.createFaultResponse(accept, e);
-    }
-  }
-
-  public Map.Entry<Accept, AbstractUtilities> getUtilities(final String accept, final String format) {
-    Accept acceptType;
-    if (StringUtils.isNotBlank(format)) {
-      try {
-        acceptType = Accept.valueOf(format.toUpperCase());
-      } catch (Exception e) {
-        acceptType = Accept.parse(format);
-      }
-    } else {
-      acceptType = Accept.parse(accept);
-    }
-
-    return new AbstractMap.SimpleEntry<Accept, AbstractUtilities>(acceptType, getUtilities(acceptType));
-  }
-
-  protected AbstractUtilities getUtilities(final Accept accept) {
-    final AbstractUtilities utils;
-    if (accept == Accept.XML || accept == Accept.TEXT || accept == Accept.ATOM) {
-      utils = xml;
-    } else {
-      utils = json;
-    }
-
-    return utils;
-  }
-
-  protected void updateInlineEntities(final Entity entity) {
-    final String type = entity.getType();
-    EntityType entityType;
-    Map<String, NavigationProperty> navProperties = Collections.emptyMap();
-    if (type != null && type.length() > 0) {
-      entityType = metadata.getEntityOrComplexType(type);
-      navProperties = entityType.getNavigationPropertyMap();
-    }
-
-    for (Property property : entity.getProperties()) {
-      if (navProperties.containsKey(property.getName())) {
-        Link alink = new Link();
-        alink.setTitle(property.getName());
-        alink.getAnnotations().addAll(property.getAnnotations());
-
-        alink.setType(navProperties.get(property.getName()).isEntitySet()
-            ? Constants.get(ConstantKey.ATOM_LINK_FEED)
-                : Constants.get(ConstantKey.ATOM_LINK_ENTRY));
-
-        alink.setRel(Constants.get(ConstantKey.ATOM_LINK_REL) + property.getName());
-
-        if (property.isCollection()) {
-          EntityCollection inline = new EntityCollection();
-          for (Object value : property.asCollection()) {
-            Entity inlineEntity = new Entity();
-            inlineEntity.setType(navProperties.get(property.getName()).getType());
-            for (Property prop : ((ComplexValue) value).getValue()) {
-              inlineEntity.getProperties().add(prop);
-            }
-            inline.getEntities().add(inlineEntity);
-          }
-          alink.setInlineEntitySet(inline);
-        } else if (property.isComplex()) {
-          Entity inline = new Entity();
-          inline.setType(navProperties.get(property.getName()).getType());
-          for (Property prop : property.asComplex().getValue()) {
-            inline.getProperties().add(prop);
-          }
-          alink.setInlineEntity(inline);
-
-        } else {
-          throw new IllegalStateException("Invalid navigation property " + property);
-        }
-        entity.getNavigationLinks().add(alink);
-      }
-    }
-  }
-
-  protected void normalizeAtomEntry(final Entity entry, final String entitySetName, final String entityKey) {
-    final org.apache.olingo.fit.metadata.EntitySet entitySet = metadata.getEntitySet(entitySetName);
-    final EntityType entityType = metadata.getEntityOrComplexType(entitySet.getType());
-    for (Map.Entry<String, org.apache.olingo.fit.metadata.Property> property : entityType.getPropertyMap().entrySet()) {
-      if (entry.getProperty(property.getKey()) == null && property.getValue().isNullable()) {
-        final Property prop = new Property();
-        prop.setName(property.getKey());
-        prop.setValue(ValueType.PRIMITIVE, null);
-        entry.getProperties().add(prop);
-      }
-    }
-
-    for (Map.Entry<String, NavigationProperty> property : entityType.getNavigationPropertyMap().entrySet()) {
-      boolean found = false;
-      for (Link link : entry.getNavigationLinks()) {
-        if (link.getTitle().equals(property.getKey())) {
-          found = true;
-        }
-      }
-
-      if (!found) {
-        final Link link = new Link();
-        link.setTitle(property.getKey());
-        link.setType(property.getValue().isEntitySet()
-            ? Constants.get(ConstantKey.ATOM_LINK_FEED)
-                : Constants.get(ConstantKey.ATOM_LINK_ENTRY));
-        link.setRel(Constants.get(ConstantKey.ATOM_LINK_REL) + property.getKey());
-        link.setHref(entitySetName + "(" + entityKey + ")/" + property.getKey());
-        entry.getNavigationLinks().add(link);
-      }
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/Demo.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/Demo.java b/fit/src/main/java/org/apache/olingo/fit/Demo.java
index c591f01..697b7c9 100644
--- a/fit/src/main/java/org/apache/olingo/fit/Demo.java
+++ b/fit/src/main/java/org/apache/olingo/fit/Demo.java
@@ -40,7 +40,6 @@ import javax.ws.rs.core.UriInfo;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.apache.olingo.fit.metadata.Metadata;
 import org.apache.olingo.fit.methods.PATCH;
 import org.apache.olingo.fit.utils.Accept;
@@ -54,7 +53,7 @@ import org.springframework.stereotype.Service;
 public class Demo extends Services {
 
   public Demo() throws IOException {
-    super(new Metadata(FSManager.instance(ODataServiceVersion.V40).
+    super(new Metadata(FSManager.instance().
         readRes("demo" + StringUtils.capitalize(Constants.get(ConstantKey.METADATA)), Accept.XML)));
   }
 
@@ -166,9 +165,8 @@ public class Demo extends Services {
       @HeaderParam("Prefer") @DefaultValue(StringUtils.EMPTY) final String prefer,
       @PathParam("entitySetName") final String entitySetName,
       @PathParam("entityId") final String entityId,
-      @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) final String format,
       final String value) {
 
-    return super.replaceMediaEntity(uriInfo, prefer, entitySetName, entityId, format, value);
+    return super.replaceMediaEntity(uriInfo, prefer, entitySetName, entityId, value);
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5d7c1287/fit/src/main/java/org/apache/olingo/fit/OpenType.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/OpenType.java b/fit/src/main/java/org/apache/olingo/fit/OpenType.java
index e65c5bf..a15128e 100644
--- a/fit/src/main/java/org/apache/olingo/fit/OpenType.java
+++ b/fit/src/main/java/org/apache/olingo/fit/OpenType.java
@@ -40,7 +40,6 @@ import javax.ws.rs.core.UriInfo;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.apache.olingo.fit.metadata.Metadata;
 import org.apache.olingo.fit.utils.Accept;
 import org.apache.olingo.fit.utils.ConstantKey;
@@ -53,8 +52,8 @@ import org.springframework.stereotype.Service;
 public class OpenType extends Services {
 
   public OpenType() throws IOException {
-    super(new Metadata(FSManager.instance(ODataServiceVersion.V40).
-        readRes("openType" + StringUtils.capitalize(Constants.get(ConstantKey.METADATA)), Accept.XML)));
+    super(new Metadata(FSManager.instance()
+        .readRes("openType" + StringUtils.capitalize(Constants.get(ConstantKey.METADATA)), Accept.XML)));
   }
 
   private Response replaceServiceName(final Response response) {


[2/7] olingo-odata4 git commit: [OLINGO-834] better alias support in URI parser

Posted by ch...@apache.org.
[OLINGO-834] better alias support in URI parser

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


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

Branch: refs/heads/master
Commit: 110c7b0e5afa1f9f717d95ca48bd5c695821db06
Parents: b317b90
Author: Klaus Straubinger <kl...@sap.com>
Authored: Thu Feb 4 12:24:38 2016 +0100
Committer: Christian Amend <ch...@sap.com>
Committed: Thu Feb 4 12:38:10 2016 +0100

----------------------------------------------------------------------
 .../uri/queryoption/SystemQueryOptionKind.java  |  22 +-
 .../apache/olingo/server/core/ODataHandler.java |   4 +-
 .../server/core/ODataHttpHandlerImpl.java       |  19 +-
 .../olingo/server/core/uri/UriInfoImpl.java     |  37 +-
 .../server/core/uri/parser/ExpandParser.java    |  30 +-
 .../core/uri/parser/ExpressionParser.java       |  85 ++-
 .../server/core/uri/parser/FilterParser.java    |   6 +-
 .../server/core/uri/parser/OrderByParser.java   |   6 +-
 .../olingo/server/core/uri/parser/Parser.java   | 354 +++++++------
 .../server/core/uri/parser/ParserHelper.java    | 168 ++++--
 .../core/uri/parser/ResourcePathParser.java     |  38 +-
 .../server/core/uri/parser/SelectParser.java    |  12 +-
 .../server/core/uri/parser/UriTokenizer.java    |  12 +-
 .../uri/queryoption/expression/AliasImpl.java   |   9 +-
 .../uri/validator/UriValidationException.java   |   4 +-
 .../server/core/uri/validator/UriValidator.java | 513 +++++--------------
 .../server-core-exceptions-i18n.properties      |   1 +
 .../olingo/server/core/uri/UriInfoImplTest.java |  50 +-
 .../core/uri/parser/ExpressionParserTest.java   |   2 +-
 .../core/uri/parser/UriTokenizerTest.java       |   3 +
 .../olingo/server/tecsvc/data/DataProvider.java |  12 +-
 .../SystemQueryOptionsRuntimeException.java     |   3 +-
 .../tecsvc/provider/ContainerProvider.java      |   6 +-
 .../core/uri/parser/TestFullResourcePath.java   | 112 ++--
 .../core/uri/queryoption/QueryOptionTest.java   |   4 +-
 .../queryoption/expression/ExpressionTest.java  |   6 +-
 .../core/uri/testutil/FilterValidator.java      |  51 +-
 .../core/uri/validator/UriValidatorTest.java    |  68 +--
 28 files changed, 797 insertions(+), 840 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/SystemQueryOptionKind.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/SystemQueryOptionKind.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/SystemQueryOptionKind.java
index f0c907b..d5d60a1 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/SystemQueryOptionKind.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/SystemQueryOptionKind.java
@@ -18,10 +18,10 @@
  */
 package org.apache.olingo.server.api.uri.queryoption;
 
+
 /**
  * Defines the supported system query options.
  */
-
 public enum SystemQueryOptionKind {
 
   /**
@@ -84,12 +84,30 @@ public enum SystemQueryOptionKind {
    */
   LEVELS("$levels");
 
-  private String syntax;
+  private final String syntax;
 
   SystemQueryOptionKind(final String syntax) {
     this.syntax = syntax;
   }
 
+  /**
+   * Converts the URI syntax to an enumeration value.
+   * @param option option in the syntax used in the URI
+   * @return system query option kind representing the given option
+   *         (or <code>null</code> if the option does not represent a system query option)
+   */
+  public static SystemQueryOptionKind get(final String option) {
+    for (final SystemQueryOptionKind kind : values()) {
+      if (kind.syntax.equals(option)) {
+        return kind;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * @return URI syntax for this system query option
+   */
   @Override
   public String toString() {
     return syntax;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
index 96b419c..3baaac7 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
@@ -160,6 +160,7 @@ public class ODataHandler {
 
   public void handleException(final ODataRequest request, final ODataResponse response,
       final ODataServerError serverError, final Exception exception) {
+    final int measurementHandle = debugger.startRuntimeMeasurement("ODataHandler", "handleException");
     lastThrownException = exception;
     ErrorProcessor exceptionProcessor;
     try {
@@ -176,8 +177,9 @@ public class ODataHandler {
     } catch (final ContentNegotiatorException e) {
       requestedContentType = ContentType.JSON;
     }
-    final int measurementHandle = debugger.startRuntimeMeasurement("ErrorProcessor", "processError");
+    final int measurementError = debugger.startRuntimeMeasurement("ErrorProcessor", "processError");
     exceptionProcessor.processError(request, response, serverError, requestedContentType);
+    debugger.stopRuntimeMeasurement(measurementError);
     debugger.stopRuntimeMeasurement(measurementHandle);
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
index 55c1194..61581c0 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
@@ -24,7 +24,7 @@ import java.nio.channels.Channel;
 import java.nio.channels.Channels;
 import java.nio.channels.ReadableByteChannel;
 import java.nio.channels.WritableByteChannel;
-import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -191,8 +191,12 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
       odRequest.setBody(httpRequest.getInputStream());
       odRequest.setProtocol(httpRequest.getProtocol());
       odRequest.setMethod(extractMethod(httpRequest));
+      int innerHandle = debugger.startRuntimeMeasurement("ODataHttpHandlerImpl", "copyHeaders");
       copyHeaders(odRequest, httpRequest);
+      debugger.stopRuntimeMeasurement(innerHandle);
+      innerHandle = debugger.startRuntimeMeasurement("ODataHttpHandlerImpl", "fillUriInformation");
       fillUriInformation(odRequest, httpRequest, split);
+      debugger.stopRuntimeMeasurement(innerHandle);
 
       return odRequest;
     } catch (final IOException e) {
@@ -273,14 +277,11 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
     odRequest.setRawServiceResolutionUri(rawServiceResolutionUri);
   }
 
-  static void copyHeaders(final ODataRequest odRequest, final HttpServletRequest req) {
-    for (Enumeration<?> headerNames = req.getHeaderNames(); headerNames.hasMoreElements();) {
-      String headerName = (String) headerNames.nextElement();
-      List<String> headerValues = new ArrayList<String>();
-      for (Enumeration<?> headers = req.getHeaders(headerName); headers.hasMoreElements();) {
-        String value = (String) headers.nextElement();
-        headerValues.add(value);
-      }
+  static void copyHeaders(ODataRequest odRequest, final HttpServletRequest req) {
+    for (final Enumeration<?> headerNames = req.getHeaderNames(); headerNames.hasMoreElements();) {
+      final String headerName = (String) headerNames.nextElement();
+      @SuppressWarnings("unchecked") // getHeaders() says it returns an Enumeration of String.
+      final List<String> headerValues = Collections.list(req.getHeaders(headerName));
       odRequest.addHeader(headerName, headerValues);
     }
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriInfoImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriInfoImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriInfoImpl.java
index e6fe057..7183bde 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriInfoImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriInfoImpl.java
@@ -20,6 +20,7 @@ package org.apache.olingo.server.core.uri;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.EnumMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -64,7 +65,7 @@ public class UriInfoImpl implements UriInfo {
   private List<UriResource> pathParts = new ArrayList<UriResource>();
 
   private Map<SystemQueryOptionKind, SystemQueryOption> systemQueryOptions =
-      new HashMap<SystemQueryOptionKind, SystemQueryOption>();
+      new EnumMap<SystemQueryOptionKind, SystemQueryOption>(SystemQueryOptionKind.class);
   private Map<String, AliasQueryOption> aliases = new HashMap<String, AliasQueryOption>();
   private List<CustomQueryOption> customQueryOptions = new ArrayList<CustomQueryOption>();
 
@@ -155,15 +156,13 @@ public class UriInfoImpl implements UriInfo {
     return Collections.unmodifiableList(pathParts);
   }
 
-  public UriInfoImpl setQueryOptions(final List<QueryOption> list) {
-    for (final QueryOption item : list) {
-      if (item instanceof SystemQueryOption) {
-        setSystemQueryOption((SystemQueryOption) item);
-      } else if (item instanceof AliasQueryOption) {
-        addAlias((AliasQueryOption) item);
-      } else if (item instanceof CustomQueryOption) {
-        addCustomQueryOption((CustomQueryOption) item);
-      }
+  public UriInfoImpl setQueryOption(final QueryOption option) {
+    if (option instanceof SystemQueryOption) {
+      setSystemQueryOption((SystemQueryOption) option);
+    } else if (option instanceof AliasQueryOption) {
+      addAlias((AliasQueryOption) option);
+    } else if (option instanceof CustomQueryOption) {
+      addCustomQueryOption((CustomQueryOption) option);
     }
     return this;
   }
@@ -263,18 +262,22 @@ public class UriInfoImpl implements UriInfo {
   }
 
   public UriInfoImpl addAlias(final AliasQueryOption alias) {
-    aliases.put(alias.getName(), alias);
+    if (aliases.containsKey(alias.getName())) {
+      throw new ODataRuntimeException("Alias " + alias.getName() + " is already there.");
+    } else {
+      aliases.put(alias.getName(), alias);
+    }
     return this;
   }
 
   @Override
   public String getValueForAlias(final String alias) {
-    final AliasQueryOption aliasQueryOption = getAlias(alias);
+    final AliasQueryOption aliasQueryOption = aliases.get(alias);
     return aliasQueryOption == null ? null : aliasQueryOption.getText();
   }
 
-  public AliasQueryOption getAlias(final String key) {
-    return aliases.get(key);
+  public Map<String, AliasQueryOption> getAliasMap() {
+    return Collections.unmodifiableMap(aliases);
   }
 
   @Override
@@ -282,8 +285,10 @@ public class UriInfoImpl implements UriInfo {
     return Collections.unmodifiableList(new ArrayList<AliasQueryOption>(aliases.values()));
   }
 
-  public UriInfoImpl addCustomQueryOption(final CustomQueryOption item) {
-    customQueryOptions.add(item);
+  public UriInfoImpl addCustomQueryOption(final CustomQueryOption option) {
+    if (option.getName() != null && !option.getName().isEmpty()) {
+      customQueryOptions.add(option);
+    }
     return this;
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
index d8209d8..03750a5 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
@@ -18,6 +18,8 @@
  */
 package org.apache.olingo.server.core.uri.parser;
 
+import java.util.Map;
+
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
@@ -30,6 +32,7 @@ import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.uri.UriInfoKind;
 import org.apache.olingo.server.api.uri.UriResourceNavigation;
 import org.apache.olingo.server.api.uri.UriResourcePartTyped;
+import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
 import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
 import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
 import org.apache.olingo.server.api.uri.queryoption.LevelsExpandOption;
@@ -53,10 +56,12 @@ public class ExpandParser {
 
   private final Edm edm;
   private final OData odata;
+  private final Map<String, AliasQueryOption> aliases;
 
-  public ExpandParser(final Edm edm, final OData odata) {
+  public ExpandParser(final Edm edm, final OData odata, final Map<String, AliasQueryOption> aliases) {
     this.edm = edm;
     this.odata = odata;
+    this.aliases = aliases;
   }
 
   public ExpandOption parse(UriTokenizer tokenizer, final EdmStructuredType referencedType)
@@ -92,7 +97,7 @@ public class ExpandParser {
         ParserHelper.requireNext(tokenizer, TokenKind.SLASH);
       }
 
-      UriInfoImpl resource = parseExpandPath(tokenizer, referencedType);
+      UriInfoImpl resource = parseExpandPath(tokenizer, referencedType, item);
 
       UriResourcePartTyped lastPart = (UriResourcePartTyped) resource.getLastResourcePart();
 
@@ -156,8 +161,8 @@ public class ExpandParser {
     return null;
   }
 
-  private UriInfoImpl parseExpandPath(UriTokenizer tokenizer, final EdmStructuredType referencedType)
-      throws UriParserException {
+  private UriInfoImpl parseExpandPath(UriTokenizer tokenizer, final EdmStructuredType referencedType,
+      ExpandItemImpl item) throws UriParserException {
     UriInfoImpl resource = new UriInfoImpl().setKind(UriInfoKind.resource);
 
     EdmStructuredType type = referencedType;
@@ -181,10 +186,13 @@ public class ExpandParser {
 
     final EdmNavigationProperty navigationProperty = type.getNavigationProperty(name);
     if (navigationProperty == null) {
-      // TODO: could also have been star after complex property (and maybe type cast)
-      throw new UriParserSemanticException(
-          "Navigation Property '" + name + "' not found in type '" + type.getFullQualifiedName() + "'.",
-          UriParserSemanticException.MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE, type.getName(), name);
+      if (tokenizer.next(TokenKind.STAR)) {
+        item.setIsStar(true);
+      } else {
+        throw new UriParserSemanticException(
+            "Navigation Property '" + name + "' not found in type '" + type.getFullQualifiedName() + "'.",
+            UriParserSemanticException.MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE, type.getName(), name);
+      }
     } else {
       resource.addResourcePart(new UriResourceNavigationPropertyImpl(navigationProperty));
     }
@@ -209,11 +217,11 @@ public class ExpandParser {
 
         } else if (!forRef && !forCount && tokenizer.next(TokenKind.EXPAND)) {
           ParserHelper.requireNext(tokenizer, TokenKind.EQ);
-          systemQueryOption = new ExpandParser(edm, odata).parse(tokenizer, referencedType);
+          systemQueryOption = new ExpandParser(edm, odata, aliases).parse(tokenizer, referencedType);
 
         } else if (tokenizer.next(TokenKind.FILTER)) {
           ParserHelper.requireNext(tokenizer, TokenKind.EQ);
-          systemQueryOption = new FilterParser(edm, odata).parse(tokenizer, referencedType, null);
+          systemQueryOption = new FilterParser(edm, odata).parse(tokenizer, referencedType, null, aliases);
 
         } else if (!forRef && !forCount && tokenizer.next(TokenKind.LEVELS)) {
           ParserHelper.requireNext(tokenizer, TokenKind.EQ);
@@ -221,7 +229,7 @@ public class ExpandParser {
 
         } else if (!forCount && tokenizer.next(TokenKind.ORDERBY)) {
           ParserHelper.requireNext(tokenizer, TokenKind.EQ);
-          systemQueryOption = new OrderByParser(edm, odata).parse(tokenizer, referencedType, null);
+          systemQueryOption = new OrderByParser(edm, odata).parse(tokenizer, referencedType, null, aliases);
 
         } else if (tokenizer.next(TokenKind.SEARCH)) {
           ParserHelper.requireNext(tokenizer, TokenKind.EQ);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java
index 1cf279e..a0ec676 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java
@@ -24,7 +24,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Deque;
-import java.util.HashMap;
+import java.util.EnumMap;
 import java.util.List;
 import java.util.Map;
 
@@ -53,6 +53,7 @@ import org.apache.olingo.server.api.uri.UriResourceFunction;
 import org.apache.olingo.server.api.uri.UriResourceLambdaVariable;
 import org.apache.olingo.server.api.uri.UriResourceNavigation;
 import org.apache.olingo.server.api.uri.UriResourcePartTyped;
+import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
 import org.apache.olingo.server.api.uri.queryoption.expression.Alias;
 import org.apache.olingo.server.api.uri.queryoption.expression.Binary;
 import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
@@ -96,7 +97,7 @@ import org.apache.olingo.server.core.uri.validator.UriValidationException;
 public class ExpressionParser {
   private static final Map<TokenKind, BinaryOperatorKind> tokenToBinaryOperator;
   static {
-    Map<TokenKind, BinaryOperatorKind> temp = new HashMap<TokenKind, BinaryOperatorKind>();
+    Map<TokenKind, BinaryOperatorKind> temp = new EnumMap<TokenKind, BinaryOperatorKind>(TokenKind.class);
     temp.put(TokenKind.OrOperator, BinaryOperatorKind.OR);
     temp.put(TokenKind.AndOperator, BinaryOperatorKind.AND);
 
@@ -121,7 +122,7 @@ public class ExpressionParser {
   // 'cast' and 'isof' are handled specially.
   private static final Map<TokenKind, MethodKind> tokenToMethod;
   static {
-    Map<TokenKind, MethodKind> temp = new HashMap<TokenKind, MethodKind>();
+    Map<TokenKind, MethodKind> temp = new EnumMap<TokenKind, MethodKind>(TokenKind.class);
     temp.put(TokenKind.CeilingMethod, MethodKind.CEILING);
     temp.put(TokenKind.ConcatMethod, MethodKind.CONCAT);
     temp.put(TokenKind.ContainsMethod, MethodKind.CONTAINS);
@@ -163,6 +164,7 @@ public class ExpressionParser {
   private Deque<UriResourceLambdaVariable> lambdaVariables = new ArrayDeque<UriResourceLambdaVariable>();
   private EdmType referringType;
   private Collection<String> crossjoinEntitySetNames;
+  private Map<String, AliasQueryOption> aliases;
 
   public ExpressionParser(final Edm edm, final OData odata) {
     this.edm = edm;
@@ -170,12 +172,13 @@ public class ExpressionParser {
   }
 
   public Expression parse(UriTokenizer tokenizer, final EdmType referringType,
-      final Collection<String> crossjoinEntitySetNames)
+      final Collection<String> crossjoinEntitySetNames, final Map<String, AliasQueryOption> aliases)
       throws UriParserException, UriValidationException {
     // Initialize tokenizer.
     this.tokenizer = tokenizer;
     this.referringType = referringType;
     this.crossjoinEntitySetNames = crossjoinEntitySetNames;
+    this.aliases = aliases;
 
     return parseExpression();
   }
@@ -339,7 +342,14 @@ public class ExpressionParser {
     }
 
     if (tokenizer.next(TokenKind.ParameterAliasName)) {
-      return new AliasImpl(tokenizer.getText());
+      final String name = tokenizer.getText();
+      if (aliases.containsKey(name)) {
+        return new AliasImpl(name,
+            ParserHelper.parseAliasValue(name, null, true, true, edm, referringType, aliases));
+      } else {
+        throw new UriValidationException("Alias '" + name + "' not found.",
+            UriValidationException.MessageKeys.MISSING_ALIAS, name);
+      }
     }
 
     if (tokenizer.next(TokenKind.jsonArrayOrObject)) {
@@ -360,7 +370,8 @@ public class ExpressionParser {
       return parsePrimitive(nextPrimitive);
     }
 
-    final TokenKind nextMethod = nextMethod();
+    final TokenKind nextMethod =
+        ParserHelper.next(tokenizer, tokenToMethod.keySet().toArray(new TokenKind[tokenToMethod.size()]));
     if (nextMethod != null) {
       return parseMethod(nextMethod);
     }
@@ -630,7 +641,7 @@ public class ExpressionParser {
     } else {
       ParserHelper.requireNext(tokenizer, TokenKind.OPEN);
       final List<UriParameter> keyPredicates =
-          ParserHelper.parseKeyPredicate(tokenizer, entitySet.getEntityType(), null);
+          ParserHelper.parseKeyPredicate(tokenizer, entitySet.getEntityType(), null, edm, referringType, aliases);
       resource = new UriResourceEntitySetImpl(entitySet).setKeyPredicates(keyPredicates);
     }
     uriInfo.addResourcePart(resource);
@@ -777,7 +788,8 @@ public class ExpressionParser {
       final UriResourceNavigationPropertyImpl navigationResource =
           new UriResourceNavigationPropertyImpl((EdmNavigationProperty) property);
       navigationResource.setKeyPredicates(
-          ParserHelper.parseNavigationKeyPredicate(tokenizer, (EdmNavigationProperty) property));
+          ParserHelper.parseNavigationKeyPredicate(tokenizer, (EdmNavigationProperty) property,
+              edm, referringType, aliases));
       uriInfo.addResourcePart(navigationResource);
 
       if (navigationResource.isCollection()) {
@@ -830,13 +842,16 @@ public class ExpressionParser {
       if (lastResource instanceof UriResourceNavigation) {
         ((UriResourceNavigationPropertyImpl) lastResource).setKeyPredicates(
               ParserHelper.parseNavigationKeyPredicate(tokenizer,
-                  ((UriResourceNavigationPropertyImpl) lastResource).getProperty()));
+                  ((UriResourceNavigationPropertyImpl) lastResource).getProperty(), edm, referringType, aliases));
       } else if (lastResource instanceof UriResourceFunction
           && ((UriResourceFunction) lastResource).getType() instanceof EdmEntityType) {
         ((UriResourceFunctionImpl) lastResource).setKeyPredicates(
             ParserHelper.parseKeyPredicate(tokenizer,
                 (EdmEntityType) ((UriResourceFunction) lastResource).getType(),
-                null));
+                null,
+                edm,
+                referringType,
+                aliases));
       } else {
         throw new UriParserSemanticException("Unknown or wrong resource type.",
             UriParserSemanticException.MessageKeys.NOT_IMPLEMENTED, lastResource.toString());
@@ -911,18 +926,21 @@ public class ExpressionParser {
   private void parseFunction(final FullQualifiedName fullQualifiedName, UriInfoImpl uriInfo,
       final EdmType lastType, final boolean lastIsCollection) throws UriParserException, UriValidationException {
 
-    final List<UriParameter> parameters = ParserHelper.parseFunctionParameters(tokenizer, edm, referringType, true);
+    final List<UriParameter> parameters =
+        ParserHelper.parseFunctionParameters(tokenizer, edm, referringType, true, aliases);
     final List<String> parameterNames = ParserHelper.getParameterNames(parameters);
     final EdmFunction boundFunction = edm.getBoundFunction(fullQualifiedName,
         lastType.getFullQualifiedName(), lastIsCollection, parameterNames);
 
     if (boundFunction != null) {
+      ParserHelper.validateFunctionParameters(boundFunction, parameters, edm, referringType, aliases);
       parseFunctionRest(uriInfo, boundFunction, parameters);
       return;
     }
 
     final EdmFunction unboundFunction = edm.getUnboundFunction(fullQualifiedName, parameterNames);
     if (unboundFunction != null) {
+      ParserHelper.validateFunctionParameters(unboundFunction, parameters, edm, referringType, aliases);
       parseFunctionRest(uriInfo, unboundFunction, parameters);
       return;
     }
@@ -934,7 +952,8 @@ public class ExpressionParser {
   private void parseBoundFunction(final FullQualifiedName fullQualifiedName, UriInfoImpl uriInfo,
       final UriResourcePartTyped lastResource) throws UriParserException, UriValidationException {
     final EdmType type = lastResource.getType();
-    final List<UriParameter> parameters = ParserHelper.parseFunctionParameters(tokenizer, edm, referringType, true);
+    final List<UriParameter> parameters =
+        ParserHelper.parseFunctionParameters(tokenizer, edm, referringType, true, aliases);
     final List<String> parameterNames = ParserHelper.getParameterNames(parameters);
     final EdmFunction boundFunction = edm.getBoundFunction(fullQualifiedName,
         type.getFullQualifiedName(), lastResource.isCollection(), parameterNames);
@@ -942,6 +961,7 @@ public class ExpressionParser {
       throw new UriParserSemanticException("Bound function '" + fullQualifiedName + "' not found.",
           UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND, fullQualifiedName.getFullQualifiedNameAsString());
     }
+    ParserHelper.validateFunctionParameters(boundFunction, parameters, edm, referringType, aliases);
     parseFunctionRest(uriInfo, boundFunction, parameters);
   }
 
@@ -1010,40 +1030,6 @@ public class ExpressionParser {
     }
   }
 
-  private TokenKind nextMethod() {
-    return ParserHelper.next(tokenizer,
-        TokenKind.CeilingMethod,
-        TokenKind.ConcatMethod,
-        TokenKind.ContainsMethod,
-        TokenKind.DateMethod,
-        TokenKind.DayMethod,
-        TokenKind.EndswithMethod,
-        TokenKind.FloorMethod,
-        TokenKind.FractionalsecondsMethod,
-        TokenKind.GeoDistanceMethod,
-        TokenKind.GeoIntersectsMethod,
-        TokenKind.GeoLengthMethod,
-        TokenKind.HourMethod,
-        TokenKind.IndexofMethod,
-        TokenKind.LengthMethod,
-        TokenKind.MaxdatetimeMethod,
-        TokenKind.MindatetimeMethod,
-        TokenKind.MinuteMethod,
-        TokenKind.MonthMethod,
-        TokenKind.NowMethod,
-        TokenKind.RoundMethod,
-        TokenKind.SecondMethod,
-        TokenKind.StartswithMethod,
-        TokenKind.SubstringMethod,
-        TokenKind.TimeMethod,
-        TokenKind.TolowerMethod,
-        TokenKind.TotaloffsetminutesMethod,
-        TokenKind.TotalsecondsMethod,
-        TokenKind.ToupperMethod,
-        TokenKind.TrimMethod,
-        TokenKind.YearMethod);
-  }
-
   protected static EdmType getType(final Expression expression) throws UriParserException {
     EdmType type;
     if (expression instanceof Literal) {
@@ -1060,11 +1046,12 @@ public class ExpressionParser {
       type = ((BinaryImpl) expression).getType();
     } else if (expression instanceof Method) {
       type = ((MethodImpl) expression).getType();
+    } else if (expression instanceof Alias) {
+      final AliasQueryOption alias = ((AliasImpl) expression).getAlias();
+      type = alias == null || alias.getValue() == null ? null : getType(alias.getValue());
     } else if (expression instanceof LambdaRef) {
       throw new UriParserSemanticException("Type determination not implemented.",
           UriParserSemanticException.MessageKeys.NOT_IMPLEMENTED, expression.toString());
-    } else if (expression instanceof Alias) {
-      type = null; // The alias would have to be available already parsed.
     } else {
       throw new UriParserSemanticException("Unknown expression type.",
           UriParserSemanticException.MessageKeys.NOT_IMPLEMENTED, expression.toString());
@@ -1142,7 +1129,7 @@ public class ExpressionParser {
 
   private Enumeration createEnumExpression(final String primitiveValueLiteral) throws UriParserException {
     final EdmEnumType enumType = getEnumType(primitiveValueLiteral);
-    // TODO: Can the Enumeration interface be changed to handle the value as a whole?
+    // The Enumeration interface could be extended to handle the value as a whole, in line with the primitive type.
     try {
       return new EnumerationImpl(enumType,
           Arrays.asList(enumType.fromUriLiteral(primitiveValueLiteral).split(",")));

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java
index dd73009..f20b029 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java
@@ -19,11 +19,13 @@
 package org.apache.olingo.server.core.uri.parser;
 
 import java.util.Collection;
+import java.util.Map;
 
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
 import org.apache.olingo.server.api.uri.queryoption.FilterOption;
 import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
 import org.apache.olingo.server.core.uri.queryoption.FilterOptionImpl;
@@ -40,10 +42,10 @@ public class FilterParser {
   }
 
   public FilterOption parse(UriTokenizer tokenizer, final EdmType referencedType,
-      final Collection<String> crossjoinEntitySetNames)
+      final Collection<String> crossjoinEntitySetNames, final Map<String, AliasQueryOption> aliases)
       throws UriParserException, UriValidationException {
     final Expression filterExpression = new ExpressionParser(edm, odata)
-        .parse(tokenizer, referencedType, crossjoinEntitySetNames);
+        .parse(tokenizer, referencedType, crossjoinEntitySetNames, aliases);
     final EdmType type = ExpressionParser.getType(filterExpression);
     if (type == null || type.equals(odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Boolean))) {
       return new FilterOptionImpl().setExpression(filterExpression);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java
index 5ea8cb7..b008ed6 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java
@@ -19,10 +19,12 @@
 package org.apache.olingo.server.core.uri.parser;
 
 import java.util.Collection;
+import java.util.Map;
 
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmStructuredType;
 import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
 import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
 import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
 import org.apache.olingo.server.core.uri.parser.UriTokenizer.TokenKind;
@@ -41,12 +43,12 @@ public class OrderByParser {
   }
 
   public OrderByOption parse(UriTokenizer tokenizer, final EdmStructuredType referencedType,
-      final Collection<String> crossjoinEntitySetNames)
+      final Collection<String> crossjoinEntitySetNames, final Map<String, AliasQueryOption> aliases)
       throws UriParserException, UriValidationException {
     OrderByOptionImpl orderByOption = new OrderByOptionImpl();
     do {
       final Expression orderByExpression = new ExpressionParser(edm, odata)
-          .parse(tokenizer, referencedType, crossjoinEntitySetNames);
+          .parse(tokenizer, referencedType, crossjoinEntitySetNames, aliases);
       OrderByItemImpl item = new OrderByItemImpl();
       item.setExpression(orderByExpression);
       if (tokenizer.next(TokenKind.AscSuffix)) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
index 586cb10..e1313c1 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
@@ -20,8 +20,10 @@ package org.apache.olingo.server.core.uri.parser;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.commons.api.edm.EdmStructuredType;
 import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.ex.ODataRuntimeException;
@@ -36,21 +38,30 @@ import org.apache.olingo.server.api.uri.UriResourcePartTyped;
 import org.apache.olingo.server.api.uri.UriResourceRef;
 import org.apache.olingo.server.api.uri.UriResourceValue;
 import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
-import org.apache.olingo.server.api.uri.queryoption.CustomQueryOption;
+import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.server.api.uri.queryoption.FilterOption;
+import org.apache.olingo.server.api.uri.queryoption.OrderByItem;
+import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
 import org.apache.olingo.server.api.uri.queryoption.QueryOption;
+import org.apache.olingo.server.api.uri.queryoption.SelectOption;
 import org.apache.olingo.server.api.uri.queryoption.SystemQueryOption;
 import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
-import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
 import org.apache.olingo.server.core.uri.UriInfoImpl;
 import org.apache.olingo.server.core.uri.UriResourceStartingTypeFilterImpl;
 import org.apache.olingo.server.core.uri.parser.UriTokenizer.TokenKind;
 import org.apache.olingo.server.core.uri.parser.search.SearchParser;
 import org.apache.olingo.server.core.uri.queryoption.AliasQueryOptionImpl;
 import org.apache.olingo.server.core.uri.queryoption.CountOptionImpl;
+import org.apache.olingo.server.core.uri.queryoption.ExpandOptionImpl;
+import org.apache.olingo.server.core.uri.queryoption.FilterOptionImpl;
 import org.apache.olingo.server.core.uri.queryoption.FormatOptionImpl;
 import org.apache.olingo.server.core.uri.queryoption.IdOptionImpl;
+import org.apache.olingo.server.core.uri.queryoption.OrderByOptionImpl;
+import org.apache.olingo.server.core.uri.queryoption.SelectOptionImpl;
 import org.apache.olingo.server.core.uri.queryoption.SkipOptionImpl;
 import org.apache.olingo.server.core.uri.queryoption.SkipTokenOptionImpl;
+import org.apache.olingo.server.core.uri.queryoption.SystemQueryOptionImpl;
 import org.apache.olingo.server.core.uri.queryoption.TopOptionImpl;
 import org.apache.olingo.server.core.uri.validator.UriValidationException;
 
@@ -74,6 +85,32 @@ public class Parser {
       throws UriParserException, UriValidationException {
 
     UriInfoImpl contextUriInfo = new UriInfoImpl();
+
+    // Read the query options (system and custom options).
+    // This is done before parsing the resource path because the aliases have to be available there.
+    // System query options that can only be parsed with context from the resource path will be post-processed later.
+    final List<QueryOption> options =
+        query == null ? Collections.<QueryOption> emptyList() : UriDecoder.splitAndDecodeOptions(query);
+    for (final QueryOption option : options) {
+      final String optionName = option.getName();
+      // Parse the untyped option and retrieve a system-option or alias-option instance (or null for a custom option).
+      final QueryOption parsedOption = parseOption(optionName, option.getText());
+      try {
+        contextUriInfo.setQueryOption(parsedOption == null ? option : parsedOption);
+      } catch (final ODataRuntimeException e) {
+          throw new UriParserSyntaxException(
+              parsedOption instanceof SystemQueryOption ?
+                  "Double system query option!" :
+                  "Alias already specified! Name: " + optionName,
+              e,
+              parsedOption instanceof SystemQueryOption ?
+                  UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION :
+                  UriParserSyntaxException.MessageKeys.DUPLICATED_ALIAS,
+              optionName);
+      }
+    }
+
+    // Read the decoded path segments.
     EdmType contextType = null;
     boolean contextIsCollection = false;
 
@@ -85,7 +122,6 @@ public class Parser {
       numberOfSegments--;
     }
 
-    // first, read the decoded path segments
     final String firstSegment = pathSegmentsDecoded.get(0);
 
     if (firstSegment.isEmpty()) {
@@ -107,24 +143,29 @@ public class Parser {
       contextIsCollection = true;
 
     } else if (firstSegment.equals("$entity")) {
+      contextUriInfo.setKind(UriInfoKind.entityId);
       if (numberOfSegments > 1) {
         final String typeCastSegment = pathSegmentsDecoded.get(1);
         ensureLastSegment(typeCastSegment, 2, numberOfSegments);
-        contextUriInfo = new ResourcePathParser(edm).parseDollarEntityTypeCast(typeCastSegment);
-        contextType = contextUriInfo.getEntityTypeCast();
-      } else {
-        contextUriInfo.setKind(UriInfoKind.entityId);
+        contextType = new ResourcePathParser(edm, contextUriInfo.getAliasMap())
+            .parseDollarEntityTypeCast(typeCastSegment);
+        contextUriInfo.setEntityTypeCast((EdmEntityType) contextType);
       }
       contextIsCollection = false;
 
     } else if (firstSegment.startsWith("$crossjoin")) {
       ensureLastSegment(firstSegment, 1, numberOfSegments);
-      contextUriInfo = new ResourcePathParser(edm).parseCrossjoinSegment(firstSegment);
+      contextUriInfo.setKind(UriInfoKind.crossjoin);
+      final List<String> entitySetNames = new ResourcePathParser(edm, contextUriInfo.getAliasMap())
+          .parseCrossjoinSegment(firstSegment);
+      for (final String name : entitySetNames) {
+        contextUriInfo.addEntitySetName(name);
+      }
       contextIsCollection = true;
 
     } else {
       contextUriInfo.setKind(UriInfoKind.resource);
-      final ResourcePathParser resourcePathParser = new ResourcePathParser(edm);
+      final ResourcePathParser resourcePathParser = new ResourcePathParser(edm, contextUriInfo.getAliasMap());
       int count = 0;
       UriResource lastSegment = null;
       for (final String pathSegment : pathSegmentsDecoded) {
@@ -162,161 +203,168 @@ public class Parser {
       }
     }
 
-    // second, read the system query options and the custom query options
-    final List<QueryOption> options =
-        query == null ? Collections.<QueryOption> emptyList() : UriDecoder.splitAndDecodeOptions(query);
-    for (final QueryOption option : options) {
-      final String optionName = option.getName();
-      final String optionValue = option.getText();
-      if (optionName.startsWith(DOLLAR)) {
-        SystemQueryOption systemOption = null;
-        if (optionName.equals(SystemQueryOptionKind.FILTER.toString())) {
-          UriTokenizer filterTokenizer = new UriTokenizer(optionValue);
-          // The referring type could be a primitive type or a structured type.
-          systemOption = new FilterParser(edm, odata).parse(filterTokenizer,
-              contextType,
-              contextUriInfo.getEntitySetNames());
-          checkOptionEOF(filterTokenizer, optionName, optionValue);
-
-        } else if (optionName.equals(SystemQueryOptionKind.FORMAT.toString())) {
-          FormatOptionImpl formatOption = new FormatOptionImpl();
-          formatOption.setText(optionValue);
-          if (optionValue.equalsIgnoreCase(JSON)
-              || optionValue.equalsIgnoreCase(XML)
-              || optionValue.equalsIgnoreCase(ATOM)
-              || isFormatSyntaxValid(optionValue)) {
-            formatOption.setFormat(optionValue);
-          } else {
-            throw new UriParserSyntaxException("Illegal value of $format option!",
-                UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION_FORMAT, optionValue);
-          }
-          systemOption = formatOption;
-
-        } else if (optionName.equals(SystemQueryOptionKind.EXPAND.toString())) {
-          if (contextType instanceof EdmStructuredType
-              || !contextUriInfo.getEntitySetNames().isEmpty()
-              || contextUriInfo.getKind() == UriInfoKind.all) {
-            UriTokenizer expandTokenizer = new UriTokenizer(optionValue);
-            systemOption = new ExpandParser(edm, odata).parse(expandTokenizer,
-                contextType instanceof EdmStructuredType ? (EdmStructuredType) contextType : null);
-            checkOptionEOF(expandTokenizer, optionName, optionValue);
-          } else {
-            throw new UriValidationException("Expand is only allowed on structured types!",
-                UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED, optionName);
-          }
-
-        } else if (optionName.equals(SystemQueryOptionKind.ID.toString())) {
-          IdOptionImpl idOption = new IdOptionImpl();
-          idOption.setText(optionValue);
-          if (optionValue == null || optionValue.isEmpty()) {
-            throw new UriParserSyntaxException("Illegal value of $id option!",
-                UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
-                optionName, optionValue);
-          }
-          idOption.setValue(optionValue);
-          systemOption = idOption;
-
-        } else if (optionName.equals(SystemQueryOptionKind.LEVELS.toString())) {
-          throw new UriParserSyntaxException("System query option '$levels' is allowed only inside '$expand'!",
-              UriParserSyntaxException.MessageKeys.SYSTEM_QUERY_OPTION_LEVELS_NOT_ALLOWED_HERE);
-
-        } else if (optionName.equals(SystemQueryOptionKind.ORDERBY.toString())) {
-          UriTokenizer orderByTokenizer = new UriTokenizer(optionValue);
-          systemOption = new OrderByParser(edm, odata).parse(orderByTokenizer,
-              contextType instanceof EdmStructuredType ? (EdmStructuredType) contextType : null,
-              contextUriInfo.getEntitySetNames());
-          checkOptionEOF(orderByTokenizer, optionName, optionValue);
-
-        } else if (optionName.equals(SystemQueryOptionKind.SEARCH.toString())) {
-          systemOption = new SearchParser().parse(optionValue);
-
-        } else if (optionName.equals(SystemQueryOptionKind.SELECT.toString())) {
-          UriTokenizer selectTokenizer = new UriTokenizer(optionValue);
-          systemOption = new SelectParser(edm).parse(selectTokenizer,
-              contextType instanceof EdmStructuredType ? (EdmStructuredType) contextType : null,
-              contextIsCollection);
-          checkOptionEOF(selectTokenizer, optionName, optionValue);
-
-        } else if (optionName.equals(SystemQueryOptionKind.SKIP.toString())) {
-          SkipOptionImpl skipOption = new SkipOptionImpl();
-          skipOption.setText(optionValue);
-          skipOption.setValue(ParserHelper.parseNonNegativeInteger(optionName, optionValue, true));
-          systemOption = skipOption;
+    // Post-process system query options that need context information from the resource path.
+    parseFilterOption(contextUriInfo.getFilterOption(), contextType,
+        contextUriInfo.getEntitySetNames(), contextUriInfo.getAliasMap());
+    parseOrderByOption(contextUriInfo.getOrderByOption(), contextType,
+        contextUriInfo.getEntitySetNames(), contextUriInfo.getAliasMap());
+    parseExpandOption(contextUriInfo.getExpandOption(), contextType,
+        !contextUriInfo.getEntitySetNames().isEmpty() || contextUriInfo.getKind() == UriInfoKind.all,
+        contextUriInfo.getAliasMap());
+    parseSelectOption(contextUriInfo.getSelectOption(), contextType, contextIsCollection);
 
-        } else if (optionName.equals(SystemQueryOptionKind.SKIPTOKEN.toString())) {
-          SkipTokenOptionImpl skipTokenOption = new SkipTokenOptionImpl();
-          skipTokenOption.setText(optionValue);
-          if (optionValue == null || optionValue.isEmpty()) {
-            throw new UriParserSyntaxException("Illegal value of $skiptoken option!",
-                UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
-                optionName, optionValue);
-          }
-          skipTokenOption.setValue(optionValue);
-          systemOption = skipTokenOption;
-
-        } else if (optionName.equals(SystemQueryOptionKind.TOP.toString())) {
-          TopOptionImpl topOption = new TopOptionImpl();
-          topOption.setText(optionValue);
-          topOption.setValue(ParserHelper.parseNonNegativeInteger(optionName, optionValue, true));
-          systemOption = topOption;
-
-        } else if (optionName.equals(SystemQueryOptionKind.COUNT.toString())) {
-          CountOptionImpl inlineCountOption = new CountOptionImpl();
-          inlineCountOption.setText(optionValue);
-          if (optionValue.equals("true") || optionValue.equals("false")) {
-            inlineCountOption.setValue(Boolean.parseBoolean(optionValue));
-          } else {
-            throw new UriParserSyntaxException("Illegal value of $count option!",
-                UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
-                optionName, optionValue);
-          }
-          systemOption = inlineCountOption;
+    return contextUriInfo;
+  }
 
+  private QueryOption parseOption(final String optionName, final String optionValue)
+      throws UriParserException, UriValidationException {
+    if (optionName.startsWith(DOLLAR)) {
+      final SystemQueryOptionKind kind = SystemQueryOptionKind.get(optionName);
+      if (kind == null) {
+        throw new UriParserSyntaxException("Unknown system query option!",
+            UriParserSyntaxException.MessageKeys.UNKNOWN_SYSTEM_QUERY_OPTION, optionName);
+      }
+      SystemQueryOption systemOption = null;
+      switch (kind) {
+      case SEARCH:
+        systemOption = new SearchParser().parse(optionValue);
+        break;
+      case FILTER:
+        systemOption = new FilterOptionImpl();
+        break;
+      case COUNT:
+        if (optionValue.equals("true") || optionValue.equals("false")) {
+          systemOption = new CountOptionImpl().setValue(Boolean.parseBoolean(optionValue));
         } else {
-          throw new UriParserSyntaxException("Unknown system query option!",
-              UriParserSyntaxException.MessageKeys.UNKNOWN_SYSTEM_QUERY_OPTION, optionName);
+          throw new UriParserSyntaxException("Illegal value of $count option!",
+              UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
+              optionName, optionValue);
         }
-        try {
-          contextUriInfo.setSystemQueryOption(systemOption);
-        } catch (final ODataRuntimeException e) {
-          throw new UriParserSyntaxException("Double system query option!", e,
-              UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION, optionName);
+        break;
+      case ORDERBY:
+        systemOption = new OrderByOptionImpl();
+        break;
+      case SKIP:
+        systemOption = new SkipOptionImpl()
+            .setValue(ParserHelper.parseNonNegativeInteger(optionName, optionValue, true));
+        break;
+      case SKIPTOKEN:
+        if (optionValue.isEmpty()) {
+          throw new UriParserSyntaxException("Illegal value of $skiptoken option!",
+              UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
+              optionName, optionValue);
         }
-
-      } else if (optionName.startsWith(AT)) {
-        if (contextUriInfo.getAlias(optionName) == null) {
-          // TODO: Aliases can only be parsed in the context of their usage.
-          Expression expression = null;
-          UriTokenizer aliasTokenizer = new UriTokenizer(optionValue);
-          if (aliasTokenizer.next(TokenKind.jsonArrayOrObject)) {
-            if (!aliasTokenizer.next(TokenKind.EOF)) {
-              throw new UriParserSyntaxException("Illegal value for alias '" + optionName + "'.",
-                  UriParserSyntaxException.MessageKeys.SYNTAX);
-            }
-          } else {
-            UriTokenizer aliasValueTokenizer = new UriTokenizer(optionValue);
-            expression = new ExpressionParser(edm, odata).parse(aliasValueTokenizer, null,
-                contextUriInfo.getEntitySetNames());
-            if (!aliasValueTokenizer.next(TokenKind.EOF)) {
-              throw new UriParserSyntaxException("Illegal value for alias '" + optionName + "'.",
-                  UriParserSyntaxException.MessageKeys.SYNTAX);
-            }
-          }
-          contextUriInfo.addAlias((AliasQueryOption) new AliasQueryOptionImpl()
-              .setAliasValue(expression)
-              .setName(optionName)
-              .setText(NULL.equals(optionValue) ? null : optionValue));
+        systemOption = new SkipTokenOptionImpl().setValue(optionValue);
+        break;
+      case TOP:
+        systemOption = new TopOptionImpl()
+            .setValue(ParserHelper.parseNonNegativeInteger(optionName, optionValue, true));
+        break;
+      case EXPAND:
+        systemOption = new ExpandOptionImpl();
+        break;
+      case SELECT:
+        systemOption = new SelectOptionImpl();
+        break;
+      case FORMAT:
+        if (optionValue.equalsIgnoreCase(JSON)
+            || optionValue.equalsIgnoreCase(XML)
+            || optionValue.equalsIgnoreCase(ATOM)
+            || isFormatSyntaxValid(optionValue)) {
+          systemOption = new FormatOptionImpl().setFormat(optionValue);
         } else {
-          throw new UriParserSyntaxException("Alias already specified! Name: " + optionName,
-              UriParserSyntaxException.MessageKeys.DUPLICATED_ALIAS, optionName);
+          throw new UriParserSyntaxException("Illegal value of $format option!",
+              UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION_FORMAT, optionValue);
         }
+        break;
+      case ID:
+        if (optionValue.isEmpty()) {
+          throw new UriParserSyntaxException("Illegal value of $id option!",
+              UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
+              optionName, optionValue);
+        }
+        systemOption = new IdOptionImpl().setValue(optionValue);
+        break;
+      case LEVELS:
+        throw new UriParserSyntaxException("System query option '$levels' is allowed only inside '$expand'!",
+            UriParserSyntaxException.MessageKeys.SYSTEM_QUERY_OPTION_LEVELS_NOT_ALLOWED_HERE);
+      }
+      ((SystemQueryOptionImpl) systemOption).setText(optionValue);
+      return systemOption;
 
-      } else if (!optionName.isEmpty()) {
-        contextUriInfo.addCustomQueryOption((CustomQueryOption) option);
+    } else if (optionName.startsWith(AT)) {
+      // Aliases can only be parsed in the context of their usage, so the value is not checked here.
+      return new AliasQueryOptionImpl()
+          .setName(optionName)
+          .setText(NULL.equals(optionValue) ? null : optionValue);
+
+    } else {
+      // The option is a custom query option; the caller can re-use its query option.
+      return null;
+    }
+  }
+
+  private void parseFilterOption(FilterOption filterOption, final EdmType contextType,
+      final List<String> entitySetNames, final Map<String, AliasQueryOption> aliases)
+      throws UriParserException, UriValidationException {
+    if (filterOption != null) {
+      final String optionValue = filterOption.getText();
+      UriTokenizer filterTokenizer = new UriTokenizer(optionValue);
+      // The referring type could be a primitive type or a structured type.
+      ((FilterOptionImpl) filterOption).setExpression(
+          new FilterParser(edm, odata).parse(filterTokenizer, contextType, entitySetNames, aliases)
+              .getExpression());
+      checkOptionEOF(filterTokenizer, filterOption.getName(), optionValue);
+    }
+  }
+
+  private void parseOrderByOption(OrderByOption orderByOption, final EdmType contextType,
+      final List<String> entitySetNames, final Map<String, AliasQueryOption> aliases)
+      throws UriParserException, UriValidationException {
+    if (orderByOption != null) {
+      final String optionValue = orderByOption.getText();
+      UriTokenizer orderByTokenizer = new UriTokenizer(optionValue);
+      final OrderByOption option = new OrderByParser(edm, odata).parse(orderByTokenizer,
+          contextType instanceof EdmStructuredType ? (EdmStructuredType) contextType : null,
+          entitySetNames,
+          aliases);
+      checkOptionEOF(orderByTokenizer, orderByOption.getName(), optionValue);
+      for (final OrderByItem item : option.getOrders()) {
+        ((OrderByOptionImpl) orderByOption).addOrder(item);
       }
     }
+  }
 
-    return contextUriInfo;
+  private void parseExpandOption(ExpandOption expandOption, final EdmType contextType, final boolean isCrossjoinOrAll,
+      final Map<String, AliasQueryOption> aliases) throws UriParserException, UriValidationException {
+    if (expandOption != null) {
+      if (!(contextType instanceof EdmStructuredType || isCrossjoinOrAll)) {
+        throw new UriValidationException("Expand is only allowed on structured types!",
+            UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED, expandOption.getName());
+      }
+      final String optionValue = expandOption.getText();
+      UriTokenizer expandTokenizer = new UriTokenizer(optionValue);
+      final ExpandOption option = new ExpandParser(edm, odata, aliases).parse(expandTokenizer,
+          contextType instanceof EdmStructuredType ? (EdmStructuredType) contextType : null);
+      checkOptionEOF(expandTokenizer, expandOption.getName(), optionValue);
+      for (final ExpandItem item : option.getExpandItems()) {
+        ((ExpandOptionImpl) expandOption).addExpandItem(item);
+      }
+    }
+  }
+
+  private void parseSelectOption(SelectOption selectOption, final EdmType contextType,
+      final boolean contextIsCollection) throws UriParserException, UriValidationException {
+    if (selectOption != null) {
+      final String optionValue = selectOption.getText();
+      UriTokenizer selectTokenizer = new UriTokenizer(optionValue);
+      ((SelectOptionImpl) selectOption).setSelectItems(
+          new SelectParser(edm).parse(selectTokenizer,
+              contextType instanceof EdmStructuredType ? (EdmStructuredType) contextType : null,
+              contextIsCollection)
+              .getSelectItems());
+      checkOptionEOF(selectTokenizer, selectOption.getName(), optionValue);
+    }
   }
 
   private void ensureLastSegment(final String segment, final int pos, final int size)

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ParserHelper.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ParserHelper.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ParserHelper.java
index b0c2972..9986542 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ParserHelper.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ParserHelper.java
@@ -20,6 +20,7 @@ package org.apache.olingo.server.core.uri.parser;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.EnumMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -27,8 +28,10 @@ import java.util.Map.Entry;
 
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmFunction;
 import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef;
 import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
+import org.apache.olingo.commons.api.edm.EdmParameter;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
@@ -39,6 +42,7 @@ import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.uri.UriParameter;
 import org.apache.olingo.server.api.uri.UriResourcePartTyped;
+import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
 import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
 import org.apache.olingo.server.api.uri.queryoption.expression.Literal;
 import org.apache.olingo.server.core.ODataImpl;
@@ -46,6 +50,8 @@ import org.apache.olingo.server.core.uri.UriParameterImpl;
 import org.apache.olingo.server.core.uri.UriResourceTypedImpl;
 import org.apache.olingo.server.core.uri.UriResourceWithKeysImpl;
 import org.apache.olingo.server.core.uri.parser.UriTokenizer.TokenKind;
+import org.apache.olingo.server.core.uri.queryoption.AliasQueryOptionImpl;
+import org.apache.olingo.server.core.uri.queryoption.expression.LiteralImpl;
 import org.apache.olingo.server.core.uri.validator.UriValidationException;
 
 public class ParserHelper {
@@ -55,7 +61,7 @@ public class ParserHelper {
   protected static final Map<TokenKind, EdmPrimitiveTypeKind> tokenToPrimitiveType;
   static {
     /* Enum and null are not present in the map. These have to be handled differently. */
-    Map<TokenKind, EdmPrimitiveTypeKind> temp = new HashMap<TokenKind, EdmPrimitiveTypeKind>();
+    Map<TokenKind, EdmPrimitiveTypeKind> temp = new EnumMap<TokenKind, EdmPrimitiveTypeKind>(TokenKind.class);
     temp.put(TokenKind.BooleanValue, EdmPrimitiveTypeKind.Boolean);
     temp.put(TokenKind.StringValue, EdmPrimitiveTypeKind.String);
     // Very large integer values are of type Edm.Decimal but this is handled elsewhere.
@@ -87,18 +93,18 @@ public class ParserHelper {
     tokenToPrimitiveType = Collections.unmodifiableMap(temp);
   }
 
-  public static void requireNext(UriTokenizer tokenizer, final TokenKind required) throws UriParserException {
+  protected static void requireNext(UriTokenizer tokenizer, final TokenKind required) throws UriParserException {
     if (!tokenizer.next(required)) {
       throw new UriParserSyntaxException("Expected token '" + required.toString() + "' not found.",
           UriParserSyntaxException.MessageKeys.SYNTAX);
     }
   }
 
-  public static void requireTokenEnd(UriTokenizer tokenizer) throws UriParserException {
+  protected static void requireTokenEnd(UriTokenizer tokenizer) throws UriParserException {
     requireNext(tokenizer, TokenKind.EOF);
   }
 
-  public static TokenKind next(UriTokenizer tokenizer, final TokenKind... kinds) {
+  protected static TokenKind next(UriTokenizer tokenizer, final TokenKind... kinds) {
     for (final TokenKind kind : kinds) {
       if (tokenizer.next(kind)) {
         return kind;
@@ -107,7 +113,7 @@ public class ParserHelper {
     return null;
   }
 
-  public static TokenKind nextPrimitiveValue(UriTokenizer tokenizer) {
+  protected static TokenKind nextPrimitiveValue(UriTokenizer tokenizer) {
     return next(tokenizer,
         TokenKind.NULL,
         TokenKind.BooleanValue,
@@ -146,7 +152,8 @@ public class ParserHelper {
   }
 
   protected static List<UriParameter> parseFunctionParameters(UriTokenizer tokenizer,
-      final Edm edm, final EdmType referringType, final boolean withComplex)
+      final Edm edm, final EdmType referringType, final boolean withComplex,
+      final Map<String, AliasQueryOption> aliases)
       throws UriParserException, UriValidationException {
     List<UriParameter> parameters = new ArrayList<UriParameter>();
     ParserHelper.requireNext(tokenizer, TokenKind.OPEN);
@@ -164,40 +171,105 @@ public class ParserHelper {
       if (tokenizer.next(TokenKind.COMMA) || tokenizer.next(TokenKind.CLOSE) || tokenizer.next(TokenKind.EOF)) {
         throw new UriParserSyntaxException("Parameter value expected.", UriParserSyntaxException.MessageKeys.SYNTAX);
       }
+      UriParameterImpl parameter = new UriParameterImpl().setName(name);
       if (tokenizer.next(TokenKind.ParameterAliasName)) {
-        parameters.add(new UriParameterImpl().setName(name).setAlias(tokenizer.getText()));
+        final String aliasName = tokenizer.getText();
+        parameter.setAlias(aliasName)
+            .setExpression(aliases.containsKey(aliasName) ? aliases.get(aliasName).getValue() : null);
       } else if (tokenizer.next(TokenKind.jsonArrayOrObject)) {
         if (withComplex) {
-          parameters.add(new UriParameterImpl().setName(name).setText(tokenizer.getText()));
+          parameter.setText(tokenizer.getText());
         } else {
           throw new UriParserSemanticException("A JSON array or object is not allowed as parameter value.",
               UriParserSemanticException.MessageKeys.COMPLEX_PARAMETER_IN_RESOURCE_PATH, tokenizer.getText());
         }
       } else if (withComplex) {
-        final Expression expression = new ExpressionParser(edm, odata).parse(tokenizer, referringType, null);
-        parameters.add(new UriParameterImpl().setName(name)
-            .setText(expression instanceof Literal ?
-                "null".equals(((Literal) expression).getText()) ? null : ((Literal) expression).getText() :
-                null)
-            .setExpression(expression instanceof Literal ? null : expression));
+        final Expression expression = new ExpressionParser(edm, odata).parse(tokenizer, referringType, null, aliases);
+        parameter.setText(expression instanceof Literal ?
+            "null".equals(((Literal) expression).getText()) ? null : ((Literal) expression).getText() :
+            null)
+            .setExpression(expression instanceof Literal ? null : expression);
       } else if (nextPrimitiveValue(tokenizer) == null) {
         throw new UriParserSemanticException("Wrong parameter value.",
             UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, "");
       } else {
         final String literalValue = tokenizer.getText();
-        parameters.add(new UriParameterImpl().setName(name)
-            .setText("null".equals(literalValue) ? null : literalValue));
+        parameter.setText("null".equals(literalValue) ? null : literalValue);
       }
+      parameters.add(parameter);
     } while (tokenizer.next(TokenKind.COMMA));
     ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
     return parameters;
   }
 
+  protected static void validateFunctionParameters(final EdmFunction function, final List<UriParameter> parameters,
+      final Edm edm, final EdmType referringType, final Map<String, AliasQueryOption> aliases)
+      throws UriParserException, UriValidationException {
+    for (final UriParameter parameter : parameters) {
+      final String parameterName = parameter.getName();
+      final EdmParameter edmParameter = function.getParameter(parameterName);
+      final boolean isNullable = edmParameter.isNullable();
+      if (parameter.getText() == null && parameter.getExpression() == null && !isNullable) {
+        if (parameter.getAlias() == null) {
+          // No alias, value is explicitly null.
+          throw new UriValidationException("Missing non-nullable parameter " + parameterName,
+              UriValidationException.MessageKeys.MISSING_PARAMETER, parameterName);
+        } else {
+          final String valueForAlias = aliases.containsKey(parameter.getAlias()) ?
+              parseAliasValue(parameter.getAlias(),
+                  edmParameter.getType(), edmParameter.isNullable(), edmParameter.isCollection(),
+                  edm, referringType, aliases).getText() :
+              null;
+          // Alias value is missing or explicitly null.
+          if (valueForAlias == null) {
+            throw new UriValidationException("Missing alias for " + parameterName,
+                UriValidationException.MessageKeys.MISSING_ALIAS, parameter.getAlias());
+          }
+        }
+      }
+    }
+  }
+
+  protected static AliasQueryOption parseAliasValue(final String name, final EdmType type, final boolean isNullable,
+      final boolean isCollection, final Edm edm, final EdmType referringType,
+      final Map<String, AliasQueryOption> aliases) throws UriParserException, UriValidationException {
+    final EdmTypeKind kind = type == null ? null : type.getKind();
+    final AliasQueryOption alias = aliases.get(name);
+    if (alias != null && alias.getText() != null) {
+      UriTokenizer aliasTokenizer = new UriTokenizer(alias.getText());
+      if (kind == null
+          || !((isCollection || kind == EdmTypeKind.COMPLEX || kind == EdmTypeKind.ENTITY ?
+          aliasTokenizer.next(TokenKind.jsonArrayOrObject) :
+          nextPrimitiveTypeValue(aliasTokenizer, (EdmPrimitiveType) type, isNullable))
+          && aliasTokenizer.next(TokenKind.EOF))) {
+        // The alias value is not an allowed literal value, so parse it again as expression.
+        aliasTokenizer = new UriTokenizer(alias.getText());
+        // Don't pass on the current alias to avoid circular references.
+        Map<String, AliasQueryOption> aliasesInner = new HashMap<String, AliasQueryOption>(aliases);
+        aliasesInner.remove(name);
+        final Expression expression = new ExpressionParser(edm, odata)
+            .parse(aliasTokenizer, referringType, null, aliasesInner);
+        final EdmType expressionType = ExpressionParser.getType(expression);
+        if (aliasTokenizer.next(TokenKind.EOF)
+            && (expressionType == null || type == null || expressionType.equals(type))) {
+          ((AliasQueryOptionImpl) alias).setAliasValue(expression);
+        } else {
+          throw new UriParserSemanticException("Illegal value for alias '" + alias.getName() + "'.",
+              UriParserSemanticException.MessageKeys.UNKNOWN_PART, alias.getText());
+        }
+      }
+    }
+    return alias;
+  }
+
   protected static List<UriParameter> parseNavigationKeyPredicate(UriTokenizer tokenizer,
-      final EdmNavigationProperty navigationProperty) throws UriParserException, UriValidationException {
+      final EdmNavigationProperty navigationProperty,
+      final Edm edm, final EdmType referringType, final Map<String, AliasQueryOption> aliases)
+      throws UriParserException, UriValidationException {
     if (tokenizer.next(TokenKind.OPEN)) {
       if (navigationProperty.isCollection()) {
-        return parseKeyPredicate(tokenizer, navigationProperty.getType(), navigationProperty.getPartner());
+        return parseKeyPredicate(tokenizer, navigationProperty.getType(), navigationProperty.getPartner(),
+            edm, referringType, aliases);
       } else {
         throw new UriParserSemanticException("A key is not allowed on non-collection navigation properties.",
             UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED);
@@ -207,7 +279,9 @@ public class ParserHelper {
   }
 
   protected static List<UriParameter> parseKeyPredicate(UriTokenizer tokenizer, final EdmEntityType edmEntityType,
-      final EdmNavigationProperty partner) throws UriParserException, UriValidationException {
+      final EdmNavigationProperty partner,
+      final Edm edm, final EdmType referringType, final Map<String, AliasQueryOption> aliases)
+      throws UriParserException, UriValidationException {
     final List<EdmKeyPropertyRef> keyPropertyRefs = edmEntityType.getKeyPropertyRefs();
     if (tokenizer.next(TokenKind.CLOSE)) {
       throw new UriParserSemanticException(
@@ -229,11 +303,11 @@ public class ParserHelper {
     }
 
     if (tokenizer.next(TokenKind.ODataIdentifier)) {
-      keys.addAll(compoundKey(tokenizer, edmEntityType));
+      keys.addAll(compoundKey(tokenizer, edmEntityType, edm, referringType, aliases));
     } else if (keyPropertyRefs.size() - referencedNames.size() == 1) {
       for (final EdmKeyPropertyRef candidate : keyPropertyRefs) {
         if (referencedNames.get(candidate.getName()) == null) {
-          keys.add(simpleKey(tokenizer, candidate));
+          keys.add(simpleKey(tokenizer, candidate, edm, referringType, aliases));
           break;
         }
       }
@@ -271,7 +345,8 @@ public class ParserHelper {
     }
   }
 
-  private static UriParameter simpleKey(UriTokenizer tokenizer, final EdmKeyPropertyRef edmKeyPropertyRef)
+  private static UriParameter simpleKey(UriTokenizer tokenizer, final EdmKeyPropertyRef edmKeyPropertyRef,
+      final Edm edm, final EdmType referringType, final Map<String, AliasQueryOption> aliases)
       throws UriParserException, UriValidationException {
     final EdmProperty edmProperty = edmKeyPropertyRef == null ? null : edmKeyPropertyRef.getProperty();
     if (nextPrimitiveTypeValue(tokenizer,
@@ -279,14 +354,15 @@ public class ParserHelper {
         edmProperty == null ? false : edmProperty.isNullable())) {
       final String literalValue = tokenizer.getText();
       ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
-      return createUriParameter(edmProperty, edmKeyPropertyRef.getName(), literalValue);
+      return createUriParameter(edmProperty, edmKeyPropertyRef.getName(), literalValue, edm, referringType, aliases);
     } else {
       throw new UriParserSemanticException("The key value is not valid.",
           UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, edmKeyPropertyRef.getName());
     }
   }
 
-  private static List<UriParameter> compoundKey(UriTokenizer tokenizer, final EdmEntityType edmEntityType)
+  private static List<UriParameter> compoundKey(UriTokenizer tokenizer, final EdmEntityType edmEntityType,
+      final Edm edm, final EdmType referringType, final Map<String, AliasQueryOption> aliases)
       throws UriParserException, UriValidationException {
 
     List<UriParameter> parameters = new ArrayList<UriParameter>();
@@ -312,7 +388,7 @@ public class ParserHelper {
         throw new UriValidationException("Unknown key property " + keyPredicateName,
             UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, keyPredicateName);
       }
-      parameters.add(keyValuePair(tokenizer, keyPredicateName, edmEntityType));
+      parameters.add(keyValuePair(tokenizer, keyPredicateName, edmEntityType, edm, referringType, aliases));
       parameterNames.add(keyPredicateName);
       hasComma = tokenizer.next(TokenKind.COMMA);
       if (hasComma) {
@@ -324,8 +400,9 @@ public class ParserHelper {
     return parameters;
   }
 
-  protected static UriParameter keyValuePair(UriTokenizer tokenizer,
-      final String keyPredicateName, final EdmEntityType edmEntityType)
+  private static UriParameter keyValuePair(UriTokenizer tokenizer,
+      final String keyPredicateName, final EdmEntityType edmEntityType,
+      final Edm edm, final EdmType referringType, final Map<String, AliasQueryOption> aliases)
       throws UriParserException, UriValidationException {
     final EdmKeyPropertyRef keyPropertyRef = edmEntityType.getKeyPropertyRef(keyPredicateName);
     final EdmProperty edmProperty = keyPropertyRef == null ? null : keyPropertyRef.getProperty();
@@ -338,7 +415,7 @@ public class ParserHelper {
       throw new UriParserSyntaxException("Key value expected.", UriParserSyntaxException.MessageKeys.SYNTAX);
     }
     if (nextPrimitiveTypeValue(tokenizer, (EdmPrimitiveType) edmProperty.getType(), edmProperty.isNullable())) {
-      return createUriParameter(edmProperty, keyPredicateName, tokenizer.getText());
+      return createUriParameter(edmProperty, keyPredicateName, tokenizer.getText(), edm, referringType, aliases);
     } else {
       throw new UriParserSemanticException(keyPredicateName + " has not a valid  key value.",
           UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, keyPredicateName);
@@ -346,28 +423,43 @@ public class ParserHelper {
   }
 
   private static UriParameter createUriParameter(final EdmProperty edmProperty, final String parameterName,
-      final String literalValue) throws UriParserException, UriValidationException {
-    if (literalValue.startsWith("@")) {
-      return new UriParameterImpl()
-          .setName(parameterName)
-          .setAlias(literalValue);
-    }
-
+      final String literalValue, final Edm edm, final EdmType referringType,
+      final Map<String, AliasQueryOption> aliases) throws UriParserException, UriValidationException {
+    final AliasQueryOption alias = literalValue.startsWith("@") ?
+        getKeyAlias(literalValue, edmProperty, edm, referringType, aliases) :
+        null;
+    final String value = alias == null ? literalValue : alias.getText();
     final EdmPrimitiveType primitiveType = (EdmPrimitiveType) edmProperty.getType();
     try {
-      if (!(primitiveType.validate(primitiveType.fromUriLiteral(literalValue), edmProperty.isNullable(),
+      if (!(primitiveType.validate(primitiveType.fromUriLiteral(value), edmProperty.isNullable(),
           edmProperty.getMaxLength(), edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode()))) {
         throw new UriValidationException("Invalid key property",
             UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, parameterName);
       }
     } catch (final EdmPrimitiveTypeException e) {
-      throw new UriValidationException("Invalid key property",
+      throw new UriValidationException("Invalid key property", e,
           UriValidationException.MessageKeys.INVALID_KEY_PROPERTY, parameterName);
     }
 
     return new UriParameterImpl()
         .setName(parameterName)
-        .setText("null".equals(literalValue) ? null : literalValue);
+        .setText("null".equals(literalValue) ? null : literalValue)
+        .setAlias(alias == null ? null : literalValue)
+        .setExpression(alias == null ? null :
+            alias.getValue() == null ? new LiteralImpl(value, primitiveType) : alias.getValue());
+  }
+
+  private static AliasQueryOption getKeyAlias(final String name, final EdmProperty edmProperty,
+      final Edm edm, final EdmType referringType, final Map<String, AliasQueryOption> aliases)
+      throws UriParserException, UriValidationException {
+    if (aliases.containsKey(name)) {
+      return parseAliasValue(name,
+          edmProperty.getType(), edmProperty.isNullable(), edmProperty.isCollection(),
+          edm, referringType, aliases);
+    } else {
+      throw new UriValidationException("Alias '" + name + "' for key value not found.",
+          UriValidationException.MessageKeys.MISSING_ALIAS, name);
+    }
   }
 
   private static boolean nextPrimitiveTypeValue(UriTokenizer tokenizer,

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ResourcePathParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ResourcePathParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ResourcePathParser.java
index 87cb91a..8d6d52d 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ResourcePathParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ResourcePathParser.java
@@ -18,7 +18,9 @@
  */
 package org.apache.olingo.server.core.uri.parser;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmAction;
@@ -35,11 +37,10 @@ import org.apache.olingo.commons.api.edm.EdmStructuredType;
 import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
-import org.apache.olingo.server.api.uri.UriInfoKind;
 import org.apache.olingo.server.api.uri.UriParameter;
 import org.apache.olingo.server.api.uri.UriResource;
 import org.apache.olingo.server.api.uri.UriResourcePartTyped;
-import org.apache.olingo.server.core.uri.UriInfoImpl;
+import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
 import org.apache.olingo.server.core.uri.UriResourceActionImpl;
 import org.apache.olingo.server.core.uri.UriResourceComplexPropertyImpl;
 import org.apache.olingo.server.core.uri.UriResourceCountImpl;
@@ -59,10 +60,12 @@ public class ResourcePathParser {
 
   private final Edm edm;
   private final EdmEntityContainer edmEntityContainer;
+  private final Map<String, AliasQueryOption> aliases;
   private UriTokenizer tokenizer;
 
-  public ResourcePathParser(final Edm edm) {
+  public ResourcePathParser(final Edm edm, final Map<String, AliasQueryOption> aliases) {
     this.edm = edm;
+    this.aliases = aliases;
     edmEntityContainer = edm.getEntityContainer();
   }
 
@@ -100,8 +103,7 @@ public class ResourcePathParser {
         UriParserSyntaxException.MessageKeys.SYNTAX);
   }
 
-  public UriInfoImpl parseDollarEntityTypeCast(final String pathSegment) throws UriParserException {
-    UriInfoImpl uriInfo = new UriInfoImpl().setKind(UriInfoKind.entityId);
+  public EdmEntityType parseDollarEntityTypeCast(final String pathSegment) throws UriParserException {
     tokenizer = new UriTokenizer(pathSegment);
     ParserHelper.requireNext(tokenizer, TokenKind.QualifiedName);
     final String name = tokenizer.getText();
@@ -110,18 +112,16 @@ public class ResourcePathParser {
     if (type == null) {
       throw new UriParserSemanticException("Type '" + name + "' not found.",
           UriParserSemanticException.MessageKeys.UNKNOWN_TYPE, name);
-    } else {
-      uriInfo.setEntityTypeCast(type);
     }
-    return uriInfo;
+    return type;
   }
 
-  public UriInfoImpl parseCrossjoinSegment(final String pathSegment) throws UriParserException {
-    UriInfoImpl uriInfo = new UriInfoImpl().setKind(UriInfoKind.crossjoin);
+  public List<String> parseCrossjoinSegment(final String pathSegment) throws UriParserException {
     tokenizer = new UriTokenizer(pathSegment);
     ParserHelper.requireNext(tokenizer, TokenKind.CROSSJOIN);
     ParserHelper.requireNext(tokenizer, TokenKind.OPEN);
     // At least one entity-set name is mandatory.  Try to fetch all.
+    List<String> entitySetNames = new ArrayList<String>();
     do {
       ParserHelper.requireNext(tokenizer, TokenKind.ODataIdentifier);
       final String name = tokenizer.getText();
@@ -130,12 +130,12 @@ public class ResourcePathParser {
         throw new UriParserSemanticException("Expected Entity Set Name.",
             UriParserSemanticException.MessageKeys.UNKNOWN_PART, name);
       } else {
-        uriInfo.addEntitySetName(name);
+        entitySetNames.add(name);
       }
     } while (tokenizer.next(TokenKind.COMMA));
     ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
     ParserHelper.requireTokenEnd(tokenizer);
-    return uriInfo;
+    return entitySetNames;
   }
 
   private UriResource ref(final UriResource previous) throws UriParserException {
@@ -180,7 +180,7 @@ public class ResourcePathParser {
 
       if (tokenizer.next(TokenKind.OPEN)) {
         final List<UriParameter> keyPredicates =
-            ParserHelper.parseKeyPredicate(tokenizer, entitySetResource.getEntityType(), null);
+            ParserHelper.parseKeyPredicate(tokenizer, entitySetResource.getEntityType(), null, edm, null, aliases);
         entitySetResource.setKeyPredicates(keyPredicates);
       }
 
@@ -251,7 +251,8 @@ public class ResourcePathParser {
           UriParserSemanticException.MessageKeys.PROPERTY_NOT_IN_TYPE,
           structType.getFullQualifiedName().getFullQualifiedNameAsString(), name);
     }
-    List<UriParameter> keyPredicate = ParserHelper.parseNavigationKeyPredicate(tokenizer, navigationProperty);
+    List<UriParameter> keyPredicate =
+        ParserHelper.parseNavigationKeyPredicate(tokenizer, navigationProperty, edm, null, aliases);
     ParserHelper.requireTokenEnd(tokenizer);
     return new UriResourceNavigationPropertyImpl(navigationProperty)
         .setKeyPredicates(keyPredicate);
@@ -320,7 +321,8 @@ public class ResourcePathParser {
           ((UriResourceWithKeysImpl) previousTyped).setEntryTypeFilter(type);
         }
         if (tokenizer.next(TokenKind.OPEN)) {
-          final List<UriParameter> keys = ParserHelper.parseKeyPredicate(tokenizer, (EdmEntityType) type, null);
+          final List<UriParameter> keys =
+              ParserHelper.parseKeyPredicate(tokenizer, (EdmEntityType) type, null, edm, null, aliases);
           if (previousTyped.isCollection()) {
             ((UriResourceWithKeysImpl) previousTyped).setKeyPredicates(keys);
           } else {
@@ -359,7 +361,7 @@ public class ResourcePathParser {
   private UriResource functionCall(final EdmFunctionImport edmFunctionImport,
       final FullQualifiedName boundFunctionName, final FullQualifiedName bindingParameterTypeName,
       final boolean isBindingParameterCollection) throws UriParserException, UriValidationException {
-    final List<UriParameter> parameters = ParserHelper.parseFunctionParameters(tokenizer, edm, null, false);
+    final List<UriParameter> parameters = ParserHelper.parseFunctionParameters(tokenizer, edm, null, false, aliases);
     final List<String> names = ParserHelper.getParameterNames(parameters);
     EdmFunction function = null;
     if (edmFunctionImport != null) {
@@ -379,13 +381,15 @@ public class ResourcePathParser {
             UriParserSemanticException.MessageKeys.UNKNOWN_PART, boundFunctionName.getFullQualifiedNameAsString());
       }
     }
+    ParserHelper.validateFunctionParameters(function, parameters, edm, null, aliases);
     UriResourceFunctionImpl resource = new UriResourceFunctionImpl(edmFunctionImport, function, parameters);
     if (tokenizer.next(TokenKind.OPEN)) {
       if (function.getReturnType() != null
           && function.getReturnType().getType().getKind() == EdmTypeKind.ENTITY
           && function.getReturnType().isCollection()) {
         resource.setKeyPredicates(
-            ParserHelper.parseKeyPredicate(tokenizer, (EdmEntityType) function.getReturnType().getType(), null));
+            ParserHelper.parseKeyPredicate(tokenizer,
+                (EdmEntityType) function.getReturnType().getType(), null, edm, null, aliases));
       } else {
         throw new UriParserSemanticException("A key is not allowed.",
             UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/SelectParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/SelectParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/SelectParser.java
index 00f3673..9ec29e3 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/SelectParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/SelectParser.java
@@ -123,11 +123,17 @@ public class SelectParser {
   }
 
   private FullQualifiedName parseAllOperationsInSchema(UriTokenizer tokenizer) throws UriParserException {
-    final String name = tokenizer.getText();
+    final String namespace = tokenizer.getText();
     if (tokenizer.next(TokenKind.DOT)) {
       if (tokenizer.next(TokenKind.STAR)) {
-        // TODO: Validate the namespace without loading the whole schema.
-        return new FullQualifiedName(name, tokenizer.getText());
+        // Validate the namespace.  Currently a namespace from a non-default schema is not supported.
+        // There is no direct access to the namespace without loading the whole schema;
+        // however, the default entity container should always be there, so its access methods can be used.
+        if (edm.getEntityContainer(new FullQualifiedName(namespace, edm.getEntityContainer().getName())) == null) {
+          throw new UriParserSemanticException("Wrong namespace '" + namespace + "'.",
+              UriParserSemanticException.MessageKeys.UNKNOWN_PART, namespace);
+        }
+        return new FullQualifiedName(namespace, tokenizer.getText());
       } else {
         throw new UriParserSemanticException("Expected star after dot.",
             UriParserSemanticException.MessageKeys.UNKNOWN_PART, "");

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/110c7b0e/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
index 0504473..d218666 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
@@ -1311,8 +1311,18 @@ public class UriTokenizer {
         || nextJsonArrayOrObject();
   }
 
+  /**
+   * Moves past a JSON object member if found; otherwise leaves the index unchanged.
+   * @return whether a JSON object member has been found at the current index
+   */
   private boolean nextJsonMember() {
-    return nextJsonString() && nextCharacter(':') && nextJsonValue();
+    final int lastGoodIndex = index;
+    if (nextJsonString() && nextCharacter(':') && nextJsonValue()) {
+      return true;
+    } else {
+      index = lastGoodIndex;
+      return false;
+    }
   }
 
   /**