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

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

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);
     }
   }