http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/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 0cc1977..eb5d679 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
@@ -38,6 +38,8 @@ 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.ApplyItem;
+import org.apache.olingo.server.api.uri.queryoption.ApplyOption;
 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;
@@ -53,6 +55,7 @@ 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.ApplyOptionImpl;
 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;
@@ -206,6 +209,8 @@ public class Parser {
     }
 
     // Post-process system query options that need context information from 
the resource path.
+    parseApplyOption(contextUriInfo.getApplyOption(), contextType,
+        contextUriInfo.getEntitySetNames(), contextUriInfo.getAliasMap());
     parseFilterOption(contextUriInfo.getFilterOption(), contextType,
         contextUriInfo.getEntitySetNames(), contextUriInfo.getAliasMap());
     parseOrderByOption(contextUriInfo.getOrderByOption(), contextType,
@@ -226,7 +231,7 @@ public class Parser {
         throw new UriParserSyntaxException("Unknown system query option!",
             UriParserSyntaxException.MessageKeys.UNKNOWN_SYSTEM_QUERY_OPTION, 
optionName);
       }
-      final SystemQueryOptionImpl systemOption;
+      SystemQueryOptionImpl systemOption;
       switch (kind) {
       case SEARCH:
         SearchOption searchOption = new SearchParser().parse(optionValue);
@@ -293,6 +298,9 @@ public class Parser {
       case LEVELS:
         throw new UriParserSyntaxException("System query option '$levels' is 
allowed only inside '$expand'!",
             
UriParserSyntaxException.MessageKeys.SYSTEM_QUERY_OPTION_LEVELS_NOT_ALLOWED_HERE);
+      case APPLY:
+        systemOption = new ApplyOptionImpl();
+        break;
       default:
           throw new UriParserSyntaxException("System query option '" + kind + 
"' is not known!",
               
UriParserSyntaxException.MessageKeys.UNKNOWN_SYSTEM_QUERY_OPTION, optionName);
@@ -344,8 +352,8 @@ public class Parser {
   }
 
   private void parseExpandOption(ExpandOption expandOption, final EdmType 
contextType, final boolean isAll,
-      final List<String> entitySetNames, final Map<String, AliasQueryOption> 
aliases) throws UriParserException,
-      UriValidationException {
+      final List<String> entitySetNames, final Map<String, AliasQueryOption> 
aliases)
+      throws UriParserException, UriValidationException {
     if (expandOption != null) {
       if (!(contextType instanceof EdmStructuredType || isAll
       || (entitySetNames != null && !entitySetNames.isEmpty()))) {
@@ -377,6 +385,23 @@ public class Parser {
     }
   }
 
+  private void parseApplyOption(ApplyOption applyOption, final EdmType 
contextType,
+      final List<String> entitySetNames, final Map<String, AliasQueryOption> 
aliases)
+      throws UriParserException, UriValidationException {
+    if (applyOption != null) {
+      final String optionValue = applyOption.getText();
+      UriTokenizer applyTokenizer = new UriTokenizer(optionValue);
+      final ApplyOption option = new ApplyParser(edm, 
odata).parse(applyTokenizer,
+          contextType instanceof EdmStructuredType ? (EdmStructuredType) 
contextType : null,
+          entitySetNames,
+          aliases);
+      checkOptionEOF(applyTokenizer, applyOption.getName(), optionValue);
+      for (final ApplyItem item : option.getApplyItems()) {
+        ((ApplyOptionImpl) applyOption).add(item);
+      }
+    }
+  }
+
   private void ensureLastSegment(final String segment, final int pos, final 
int size)
       throws UriParserSyntaxException {
     if (pos < size) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSemanticException.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSemanticException.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSemanticException.java
index db33a6a..f2c4634 100644
--- 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSemanticException.java
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSemanticException.java
@@ -67,9 +67,15 @@ public class UriParserSemanticException extends 
UriParserException {
     COMPLEX_PARAMETER_IN_RESOURCE_PATH,
     /** parameters: left type, right type */
     TYPES_NOT_COMPATIBLE,
-    /** parameter: addressed resource name*/
-    NOT_A_MEDIA_RESOURCE;
-    
+    /** parameter: addressed resource name */
+    NOT_A_MEDIA_RESOURCE,
+    /** parameters: property name */
+    IS_PROPERTY,
+    /** parameter: expression */
+    ONLY_FOR_PRIMITIVE_TYPES,
+    /** parameter: function name */
+    FUNCTION_MUST_USE_COLLECTIONS;
+
     @Override
     public String getKey() {
       return name();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/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 d218666..6654df9 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
@@ -23,7 +23,8 @@ package org.apache.olingo.server.core.uri.parser;
  * <p>As far as feasible, it tries to work on character basis, assuming this 
to be faster than string operations.
  * Since only the index is "moved", backing out while parsing a token is easy 
and used throughout.
  * There is intentionally no method to push back tokens (although it would be 
easy to add such a method)
- * because this tokenizer should behave like a classical token-consuming 
tokenizer.</p>
+ * because this tokenizer should behave like a classical token-consuming 
tokenizer.
+ * There is, however, the possibility to save the current state and return to 
it later.</p>
  * <p>Whitespace is not an extra token but consumed with the tokens that 
require whitespace.
  * Optional whitespace is not supported.</p>
  */
@@ -40,6 +41,7 @@ public class UriTokenizer {
     ROOT,
     IT,
 
+    APPLY, // for the aggregation extension
     EXPAND,
     FILTER,
     LEVELS,
@@ -66,6 +68,13 @@ public class UriTokenizer {
     NULL,
     MAX,
 
+    AVERAGE, // for the aggregation extension
+    COUNTDISTINCT, // for the aggregation extension
+    IDENTITY, // for the aggregation extension
+    MIN, // for the aggregation extension
+    SUM, // for the aggregation extension
+    ROLLUP_ALL, // for the aggregation extension
+
     // variable-value tokens (convention: mixed case)
     ODataIdentifier,
     QualifiedName,
@@ -125,6 +134,10 @@ public class UriTokenizer {
     MinusOperator,
     NotOperator,
 
+    AsOperator, // for the aggregation extension
+    FromOperator, // for the aggregation extension
+    WithOperator, // for the aggregation extension
+
     CastMethod,
     CeilingMethod,
     ConcatMethod,
@@ -158,6 +171,23 @@ public class UriTokenizer {
     TrimMethod,
     YearMethod,
 
+    IsDefinedMethod, // for the aggregation extension
+
+    AggregateTrafo, // for the aggregation extension
+    BottomCountTrafo, // for the aggregation extension
+    BottomPercentTrafo, // for the aggregation extension
+    BottomSumTrafo, // for the aggregation extension
+    ComputeTrafo, // for the aggregation extension
+    ExpandTrafo, // for the aggregation extension
+    FilterTrafo, // for the aggregation extension
+    GroupByTrafo, // for the aggregation extension
+    SearchTrafo, // for the aggregation extension
+    TopCountTrafo, // for the aggregation extension
+    TopPercentTrafo, // for the aggregation extension
+    TopSumTrafo, // for the aggregation extension
+
+    RollUpSpec, // for the aggregation extension
+
     AscSuffix,
     DescSuffix
   }
@@ -167,10 +197,31 @@ public class UriTokenizer {
   private int startIndex = 0;
   private int index = 0;
 
+  private int savedStartIndex;
+  private int savedIndex;
+
   public UriTokenizer(final String parseString) {
     this.parseString = parseString == null ? "" : parseString;
   }
 
+  /**
+   * Save the current state.
+   * @see #returnToSavedState()
+   */
+  public void saveState() {
+    savedStartIndex = startIndex;
+    savedIndex = index;
+  }
+
+  /**
+   * Return to the previously saved state.
+   * @see #saveState()
+   */
+  public void returnToSavedState() {
+    startIndex = savedStartIndex;
+    index = savedIndex;
+  }
+
   /** Returns the string value corresponding to the last successful {@link 
#next(TokenKind)} call. */
   public String getText() {
     return parseString.substring(startIndex, index);
@@ -218,6 +269,9 @@ public class UriTokenizer {
       found = nextConstant("$it");
       break;
 
+    case APPLY:
+      found = nextConstant("$apply");
+      break;
     case EXPAND:
       found = nextConstant("$expand");
       break;
@@ -288,6 +342,26 @@ public class UriTokenizer {
       found = nextConstant("max");
       break;
 
+    case AVERAGE:
+      found = nextConstant("average");
+      break;
+    case COUNTDISTINCT:
+      found = nextConstant("countdistinct");
+      break;
+    case IDENTITY:
+      found = nextConstant("identity");
+      break;
+    case MIN:
+      found = nextConstant("min");
+      break;
+    case SUM:
+      found = nextConstant("sum");
+      break;
+
+    case ROLLUP_ALL:
+      found = nextConstant("$all");
+      break;
+
     // Identifiers
     case ODataIdentifier:
       found = nextODataIdentifier();
@@ -456,6 +530,17 @@ public class UriTokenizer {
       found = nextUnaryOperator("not");
       break;
 
+    // Operators for the aggregation extension
+    case AsOperator:
+      found = nextBinaryOperator("as");
+      break;
+    case FromOperator:
+      found = nextBinaryOperator("from");
+      break;
+    case WithOperator:
+      found = nextBinaryOperator("with");
+      break;
+
     // Methods
     case CastMethod:
       found = nextMethod("cast");
@@ -554,6 +639,54 @@ public class UriTokenizer {
       found = nextMethod("year");
       break;
 
+    // Method for the aggregation extension
+    case IsDefinedMethod:
+      found = nextMethod("isdefined");
+      break;
+
+    // Transformations for the aggregation extension
+    case AggregateTrafo:
+      found = nextMethod("aggregate");
+      break;
+    case BottomCountTrafo:
+      found = nextMethod("bottomcount");
+      break;
+    case BottomPercentTrafo:
+      found = nextMethod("bottompercent");
+      break;
+    case BottomSumTrafo:
+      found = nextMethod("bottomsum");
+      break;
+    case ComputeTrafo:
+      found = nextMethod("compute");
+      break;
+    case ExpandTrafo:
+      found = nextMethod("expand");
+      break;
+    case FilterTrafo:
+      found = nextMethod("filter");
+      break;
+    case GroupByTrafo:
+      found = nextMethod("groupby");
+      break;
+    case SearchTrafo:
+      found = nextMethod("search");
+      break;
+    case TopCountTrafo:
+      found = nextMethod("topcount");
+      break;
+    case TopPercentTrafo:
+      found = nextMethod("toppercent");
+      break;
+    case TopSumTrafo:
+      found = nextMethod("topsum");
+      break;
+
+    // Roll-up specification for the aggregation extension
+    case RollUpSpec:
+      found = nextMethod("rollup");
+      break;
+
     // Suffixes
     case AscSuffix:
       found = nextSuffix("asc");

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/ApplyOptionImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/ApplyOptionImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/ApplyOptionImpl.java
new file mode 100644
index 0000000..066352d
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/ApplyOptionImpl.java
@@ -0,0 +1,46 @@
+/*
+ * 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.server.core.uri.queryoption;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.olingo.server.api.uri.queryoption.ApplyItem;
+import org.apache.olingo.server.api.uri.queryoption.ApplyOption;
+import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
+
+public class ApplyOptionImpl extends SystemQueryOptionImpl implements 
ApplyOption {
+
+  private List<ApplyItem> transformations = new ArrayList<ApplyItem>();
+
+  public ApplyOptionImpl() {
+    setKind(SystemQueryOptionKind.APPLY);
+  }
+
+  @Override
+  public List<ApplyItem> getApplyItems() {
+    return Collections.unmodifiableList(transformations);
+  }
+
+  public ApplyOptionImpl add(final ApplyItem transformation) {
+    transformations.add(transformation);
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/AggregateExpressionImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/AggregateExpressionImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/AggregateExpressionImpl.java
new file mode 100644
index 0000000..1bacfe0
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/AggregateExpressionImpl.java
@@ -0,0 +1,113 @@
+/*
+ * 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.server.core.uri.queryoption.apply;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.queryoption.apply.AggregateExpression;
+import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
+
+/**
+ * Represents an aggregate expression.
+ */
+public class AggregateExpressionImpl implements AggregateExpression {
+
+  private UriInfo path;
+  private Expression expression;
+  private StandardMethod standardMethod;
+  private FullQualifiedName customMethod;
+  private String alias;
+  private AggregateExpression inlineAggregateExpression;
+  private List<AggregateExpression> from = new 
ArrayList<AggregateExpression>();
+
+  @Override
+  public List<UriResource> getPath() {
+    return path == null ? Collections.<UriResource> emptyList() : 
path.getUriResourceParts();
+  }
+
+  public AggregateExpressionImpl setPath(final UriInfo uriInfo) {
+    path = uriInfo;
+    return this;
+  }
+
+  @Override
+  public Expression getExpression() {
+    return expression;
+  }
+
+  public AggregateExpressionImpl setExpression(final Expression expression) {
+    this.expression = expression;
+    return this;
+  }
+
+  @Override
+  public StandardMethod getStandardMethod() {
+    return standardMethod;
+  }
+
+  public AggregateExpressionImpl setStandardMethod(final StandardMethod 
standardMethod) {
+    this.standardMethod = standardMethod;
+    return this;
+  }
+
+  @Override
+  public FullQualifiedName getCustomMethod() {
+    return customMethod;
+  }
+
+  public AggregateExpressionImpl setCustomMethod(final FullQualifiedName 
customMethod) {
+    this.customMethod = customMethod;
+    return this;
+  }
+
+  @Override
+  public AggregateExpression getInlineAggregateExpression() {
+    return inlineAggregateExpression;
+  }
+
+  public AggregateExpressionImpl setInlineAggregateExpression(final 
AggregateExpression aggregateExpression) {
+    inlineAggregateExpression = aggregateExpression;
+    return this;
+  }
+
+  @Override
+  public List<AggregateExpression> getFrom() {
+    return Collections.unmodifiableList(from);
+  }
+
+  public AggregateExpressionImpl addFrom(final AggregateExpression from) {
+    this.from.add(from);
+    return this;
+  }
+
+  @Override
+  public String getAlias() {
+    return alias;
+  }
+
+  public AggregateExpressionImpl setAlias(final String alias) {
+    this.alias = alias;
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/AggregateImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/AggregateImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/AggregateImpl.java
new file mode 100644
index 0000000..3414d2d
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/AggregateImpl.java
@@ -0,0 +1,48 @@
+/*
+ * 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.server.core.uri.queryoption.apply;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.server.api.uri.queryoption.apply.Aggregate;
+import org.apache.olingo.server.api.uri.queryoption.apply.AggregateExpression;
+
+/**
+ * Represents the aggregate transformation.
+ */
+public class AggregateImpl implements Aggregate {
+
+  private List<AggregateExpression> expressions = new 
ArrayList<AggregateExpression>();
+
+  @Override
+  public Kind getKind() {
+    return Kind.AGGREGATE;
+  }
+
+  @Override
+  public List<AggregateExpression> getExpressions() {
+    return expressions;
+  }
+
+  public AggregateImpl addExpression(final AggregateExpression expression) {
+    expressions.add(expression);
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/BottomTopImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/BottomTopImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/BottomTopImpl.java
new file mode 100644
index 0000000..3deb895
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/BottomTopImpl.java
@@ -0,0 +1,69 @@
+/*
+ * 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.server.core.uri.queryoption.apply;
+
+import org.apache.olingo.server.api.uri.queryoption.apply.BottomTop;
+import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
+
+/**
+ * Represents a transformation with one of the pre-defined methods
+ * <code>bottomcount</code>, <code>bottompercent</code>, 
<code>bottomsum</code>,
+ * <code>topcount</code>, <code>toppercent</code>, <code>topsum</code>.
+ */
+public class BottomTopImpl implements BottomTop {
+
+  private Method method;
+  private Expression number;
+  private Expression value;
+
+  @Override
+  public Kind getKind() {
+    return Kind.BOTTOM_TOP;
+  }
+
+  @Override
+  public Method getMethod() {
+    return method;
+  }
+
+  public BottomTopImpl setMethod(final Method method) {
+    this.method = method;
+    return this;
+  }
+
+  @Override
+  public Expression getNumber() {
+    return number;
+  }
+
+  public BottomTopImpl setNumber(final Expression number) {
+    this.number = number;
+    return this;
+  }
+
+  @Override
+  public Expression getValue() {
+    return value;
+  }
+
+  public BottomTopImpl setValue(final Expression value) {
+    this.value = value;
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ComputeExpressionImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ComputeExpressionImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ComputeExpressionImpl.java
new file mode 100644
index 0000000..c073aa3
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ComputeExpressionImpl.java
@@ -0,0 +1,51 @@
+/*
+ * 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.server.core.uri.queryoption.apply;
+
+import org.apache.olingo.server.api.uri.queryoption.apply.ComputeExpression;
+import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
+
+/**
+ * Represents an aggregate expression.
+ */
+public class ComputeExpressionImpl implements ComputeExpression {
+
+  private Expression expression;
+  private String alias;
+
+  @Override
+  public Expression getExpression() {
+    return expression;
+  }
+
+  public ComputeExpressionImpl setExpression(final Expression expression) {
+    this.expression = expression;
+    return this;
+  }
+
+  @Override
+  public String getAlias() {
+    return alias;
+  }
+
+  public ComputeExpressionImpl setAlias(final String alias) {
+    this.alias = alias;
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ComputeImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ComputeImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ComputeImpl.java
new file mode 100644
index 0000000..8e57120
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ComputeImpl.java
@@ -0,0 +1,48 @@
+/*
+ * 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.server.core.uri.queryoption.apply;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.server.api.uri.queryoption.apply.Compute;
+import org.apache.olingo.server.api.uri.queryoption.apply.ComputeExpression;
+
+/**
+ * Represents the compute transformation.
+ */
+public class ComputeImpl implements Compute {
+
+  private List<ComputeExpression> expressions = new 
ArrayList<ComputeExpression>();
+
+  @Override
+  public Kind getKind() {
+    return Kind.COMPUTE;
+  }
+
+  @Override
+  public List<ComputeExpression> getExpressions() {
+    return expressions;
+  }
+
+  public ComputeImpl addExpression(final ComputeExpressionImpl expression) {
+    expressions.add(expression);
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ConcatImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ConcatImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ConcatImpl.java
new file mode 100644
index 0000000..0a3b919
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ConcatImpl.java
@@ -0,0 +1,48 @@
+/*
+ * 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.server.core.uri.queryoption.apply;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.server.api.uri.queryoption.ApplyOption;
+import org.apache.olingo.server.api.uri.queryoption.apply.Concat;
+
+/**
+ * Represents the concat transformation.
+ */
+public class ConcatImpl implements Concat {
+
+  private List<ApplyOption> options = new ArrayList<ApplyOption>();
+
+  @Override
+  public Kind getKind() {
+    return Kind.CONCAT;
+  }
+
+  @Override
+  public List<ApplyOption> getApplyOptions() {
+    return options;
+  }
+
+  public ConcatImpl addApplyOption(final ApplyOption option) {
+    options.add(option);
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/CustomFunctionImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/CustomFunctionImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/CustomFunctionImpl.java
new file mode 100644
index 0000000..ba083dd
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/CustomFunctionImpl.java
@@ -0,0 +1,62 @@
+/*
+ * 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.server.core.uri.queryoption.apply;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.olingo.commons.api.edm.EdmFunction;
+import org.apache.olingo.server.api.uri.UriParameter;
+import org.apache.olingo.server.api.uri.queryoption.apply.CustomFunction;
+
+/**
+ * Represents a transformation with a custom function.
+ */
+public class CustomFunctionImpl implements CustomFunction {
+
+  private EdmFunction function = null;
+  private List<UriParameter> parameters;
+
+  @Override
+  public Kind getKind() {
+    return Kind.CUSTOM_FUNCTION;
+  }
+
+  @Override
+  public EdmFunction getFunction() {
+    return function;
+  }
+
+  public CustomFunctionImpl setFunction(final EdmFunction function) {
+    this.function = function;
+    return this;
+  }
+
+  @Override
+  public List<UriParameter> getParameters() {
+    return parameters == null ?
+        Collections.<UriParameter> emptyList() :
+        Collections.unmodifiableList(parameters);
+  }
+
+  public CustomFunctionImpl setParameters(final List<UriParameter> parameters) 
{
+    this.parameters = parameters;
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicProperty.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicProperty.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicProperty.java
new file mode 100644
index 0000000..d9fbde9
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicProperty.java
@@ -0,0 +1,118 @@
+/*
+ * 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.server.core.uri.queryoption.apply;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.olingo.commons.api.edm.EdmAnnotation;
+import org.apache.olingo.commons.api.edm.EdmMapping;
+import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmTerm;
+import org.apache.olingo.commons.api.edm.EdmType;
+import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
+import org.apache.olingo.commons.api.edm.geo.SRID;
+
+/** A dynamic EDM property containing an aggregation. */
+public class DynamicProperty implements EdmProperty {
+
+  private final String name;
+  private final EdmType propertyType;
+
+  /** Creates a dynamic property with a mandatory name and an optional type. */
+  public DynamicProperty(final String name, final EdmType type) {
+    this.name = name;
+    propertyType = type;
+  }
+
+  @Override
+  public String getName() {
+    return name;
+  }
+
+  @Override
+  public EdmType getType() {
+    return propertyType;
+  }
+
+  @Override
+  public boolean isCollection() {
+    return false;
+  }
+
+  @Override
+  public EdmMapping getMapping() {
+    return null;
+  }
+
+  @Override
+  public String getMimeType() {
+    return null;
+  }
+
+  @Override
+  public boolean isNullable() {
+    return false;
+  }
+
+  @Override
+  public Integer getMaxLength() {
+    return null;
+  }
+
+  @Override
+  public Integer getPrecision() {
+    return null;
+  }
+
+  @Override
+  public Integer getScale() {
+    return null;
+  }
+
+  @Override
+  public SRID getSrid() {
+    return null;
+  }
+
+  @Override
+  public boolean isUnicode() {
+    return true;
+  }
+
+  @Override
+  public String getDefaultValue() {
+    return null;
+  }
+
+  @Override
+  public boolean isPrimitive() {
+    return propertyType != null && propertyType.getKind() == 
EdmTypeKind.PRIMITIVE;
+  }
+
+  @Override
+  public EdmAnnotation getAnnotation(final EdmTerm term, final String 
qualifier) {
+    return null;
+  }
+
+  @Override
+  public List<EdmAnnotation> getAnnotations() {
+    return Collections.emptyList();
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicStructuredType.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicStructuredType.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicStructuredType.java
new file mode 100644
index 0000000..f0ac5c6
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicStructuredType.java
@@ -0,0 +1,141 @@
+/*
+ * 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.server.core.uri.queryoption.apply;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.commons.api.edm.EdmAnnotation;
+import org.apache.olingo.commons.api.edm.EdmElement;
+import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
+import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmStructuredType;
+import org.apache.olingo.commons.api.edm.EdmTerm;
+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;
+
+/** A dynamic structured type used to incorporate dynamic properties 
containing aggregations. */
+public class DynamicStructuredType implements EdmStructuredType, Cloneable {
+
+  private final EdmStructuredType startType;
+  private Map<String, EdmProperty> properties;
+
+  public DynamicStructuredType(final EdmStructuredType startType) {
+    this.startType = startType;
+  }
+
+  public DynamicStructuredType addProperty(final EdmProperty property) {
+    if (properties == null) {
+      properties = new LinkedHashMap<String, EdmProperty>();
+    }
+    properties.put(property.getName(), property);
+    return this;
+  }
+
+  @Override
+  public EdmElement getProperty(final String name) {
+    final EdmElement property = startType.getProperty(name);
+    return property == null ?
+        properties == null ? null : properties.get(name) :
+        property;
+  }
+
+  @Override
+  public List<String> getPropertyNames() {
+    if (properties == null || properties.isEmpty()) {
+      return startType.getPropertyNames();
+    } else {
+      List<String> names = new ArrayList<String>(startType.getPropertyNames());
+      names.addAll(properties.keySet());
+      return Collections.unmodifiableList(names);
+    }
+  }
+
+  @Override
+  public EdmProperty getStructuralProperty(final String name) {
+    final EdmProperty property = startType.getStructuralProperty(name);
+    return property == null ?
+        properties == null ? null : properties.get(name) :
+        property;
+  }
+
+  @Override
+  public EdmNavigationProperty getNavigationProperty(final String name) {
+    return startType.getNavigationProperty(name);
+  }
+
+  @Override
+  public List<String> getNavigationPropertyNames() {
+    return startType.getNavigationPropertyNames();
+  }
+
+  @Override
+  public String getNamespace() {
+    return startType.getNamespace();
+  }
+
+  @Override
+  public String getName() {
+    return startType.getName();
+  }
+
+  @Override
+  public FullQualifiedName getFullQualifiedName() {
+    return startType.getFullQualifiedName();
+  }
+
+  @Override
+  public EdmTypeKind getKind() {
+    return startType.getKind();
+  }
+
+  @Override
+  public EdmAnnotation getAnnotation(final EdmTerm term, final String 
qualifier) {
+    return startType.getAnnotation(term, qualifier);
+  }
+
+  @Override
+  public List<EdmAnnotation> getAnnotations() {
+    return startType.getAnnotations();
+  }
+
+  @Override
+  public EdmStructuredType getBaseType() {
+    return startType.getBaseType();
+  }
+
+  @Override
+  public boolean compatibleTo(final EdmType targetType) {
+    return startType.compatibleTo(targetType);
+  }
+
+  @Override
+  public boolean isOpenType() {
+    return startType.isOpenType();
+  }
+
+  @Override
+  public boolean isAbstract() {
+    return startType.isAbstract();
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ExpandImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ExpandImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ExpandImpl.java
new file mode 100644
index 0000000..a9992c5
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/ExpandImpl.java
@@ -0,0 +1,45 @@
+/*
+ * 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.server.core.uri.queryoption.apply;
+
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.server.api.uri.queryoption.apply.Expand;
+
+/**
+ * Represents the expand transformation.
+ */
+public class ExpandImpl implements Expand {
+
+  private ExpandOption expandOption = null;
+
+  @Override
+  public Kind getKind() {
+    return Kind.EXPAND;
+  }
+
+  @Override
+  public ExpandOption getExpandOption() {
+    return expandOption;
+  }
+
+  public ExpandImpl setExpandOption(final ExpandOption expandOption) {
+    this.expandOption = expandOption;
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/FilterImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/FilterImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/FilterImpl.java
new file mode 100644
index 0000000..c356845
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/FilterImpl.java
@@ -0,0 +1,45 @@
+/*
+ * 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.server.core.uri.queryoption.apply;
+
+import org.apache.olingo.server.api.uri.queryoption.FilterOption;
+import org.apache.olingo.server.api.uri.queryoption.apply.Filter;
+
+/**
+ * Represents the filter transformation.
+ */
+public class FilterImpl implements Filter {
+
+  private FilterOption filterOption = null;
+
+  @Override
+  public Kind getKind() {
+    return Kind.FILTER;
+  }
+
+  @Override
+  public FilterOption getFilterOption() {
+    return filterOption;
+  }
+
+  public FilterImpl setFilterOption(final FilterOption filterOption) {
+    this.filterOption = filterOption;
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/GroupByImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/GroupByImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/GroupByImpl.java
new file mode 100644
index 0000000..9946e17
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/GroupByImpl.java
@@ -0,0 +1,60 @@
+/*
+ * 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.server.core.uri.queryoption.apply;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.server.api.uri.queryoption.ApplyOption;
+import org.apache.olingo.server.api.uri.queryoption.apply.GroupBy;
+import org.apache.olingo.server.api.uri.queryoption.apply.GroupByItem;
+
+/**
+ * Represents the grouping transformation.
+ */
+public class GroupByImpl implements GroupBy {
+
+  private ApplyOption applyOption;
+  private List<GroupByItem> groupByItems = new ArrayList<GroupByItem>();
+
+  @Override
+  public Kind getKind() {
+    return Kind.GROUP_BY;
+  }
+
+  @Override
+  public ApplyOption getApplyOption() {
+    return applyOption;
+  }
+
+  public GroupByImpl setApplyOption(final ApplyOption applyOption) {
+    this.applyOption = applyOption;
+    return this;
+  }
+
+  @Override
+  public List<GroupByItem> getGroupByItems() {
+    return groupByItems;
+  }
+
+  public GroupByImpl addGroupByItem(final GroupByItem groupByItem) {
+    groupByItems.add(groupByItem);
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/GroupByItemImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/GroupByItemImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/GroupByItemImpl.java
new file mode 100644
index 0000000..0dd52b1
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/GroupByItemImpl.java
@@ -0,0 +1,67 @@
+/*
+ * 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.server.core.uri.queryoption.apply;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.queryoption.apply.GroupByItem;
+
+/**
+ * Represents a grouping property.
+ */
+public class GroupByItemImpl implements GroupByItem {
+
+  private UriInfo path;
+  private boolean isRollupAll;
+  private List<GroupByItem> rollup = new ArrayList<GroupByItem>();
+
+  @Override
+  public List<UriResource> getPath() {
+    return path == null ? Collections.<UriResource> emptyList() : 
path.getUriResourceParts();
+  }
+
+  public GroupByItemImpl setPath(final UriInfo uriInfo) {
+    path = uriInfo;
+    return this;
+  }
+
+  @Override
+  public List<GroupByItem> getRollup() {
+    return rollup;
+  }
+
+  public GroupByItemImpl addRollupItem(final GroupByItem groupByItem) {
+    rollup.add(groupByItem);
+    return this;
+  }
+
+  @Override
+  public boolean isRollupAll() {
+    return isRollupAll;
+  }
+
+  public GroupByItemImpl setIsRollupAll() {
+    this.isRollupAll = true;
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/IdentityImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/IdentityImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/IdentityImpl.java
new file mode 100644
index 0000000..838d0b2
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/IdentityImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.server.core.uri.queryoption.apply;
+
+import org.apache.olingo.server.api.uri.queryoption.apply.Identity;
+
+/**
+ * Represents the identity transformation.
+ */
+public class IdentityImpl implements Identity {
+
+  @Override
+  public Kind getKind() {
+    return Kind.IDENTITY;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/SearchImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/SearchImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/SearchImpl.java
new file mode 100644
index 0000000..9a588d9
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/SearchImpl.java
@@ -0,0 +1,45 @@
+/*
+ * 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.server.core.uri.queryoption.apply;
+
+import org.apache.olingo.server.api.uri.queryoption.SearchOption;
+import org.apache.olingo.server.api.uri.queryoption.apply.Search;
+
+/**
+ * Represents the search transformation.
+ */
+public class SearchImpl implements Search {
+
+  private SearchOption searchOption = null;
+
+  @Override
+  public Kind getKind() {
+    return Kind.SEARCH;
+  }
+
+  @Override
+  public SearchOption getSearchOption() {
+    return searchOption;
+  }
+
+  public SearchImpl setSearchOption(final SearchOption searchOption) {
+    this.searchOption = searchOption;
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/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 0946b60..64c3cf7 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
@@ -45,27 +45,27 @@ public class UriValidator {
   //CHECKSTYLE:OFF (Maven checkstyle)
   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  },
-      /*                            batch  1 */ { false,   false,   false,   
false,   false,   false,    false,   false,   false,   false,      false },
-      /*                        crossjoin  2 */ { true ,   true ,   true ,   
false,   true ,   true ,    true ,   true ,   true ,   true ,      true  },
-      /*                         entityId  3 */ { false,   true ,   true ,   
true ,   false,   false,    false,   true ,   false,   false,      false },
-      /*                         metadata  4 */ { false,   true ,   false,   
false,   false,   false,    false,   false,   false,   false,      false },
-      /*                          service  5 */ { false,   true ,   false,   
false,   false,   false,    false,   false,   false,   false,      false },
-      /*                        entitySet  6 */ { true ,   true ,   true ,   
false,   true ,   true ,    true ,   true ,   true ,   true ,      true  },
-      /*                   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,   
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  },
-      /*   propertyComplexCollectionCount 14 */ { true ,   false,   false,   
false,   false,   false,    false,   false,   false,   false,      false },
-      /*                propertyPrimitive 15 */ { false,   true ,   false,   
false,   false,   false,    false,   false,   false,   false,      false },
-      /*      propertyPrimitiveCollection 16 */ { true ,   true ,   false,   
false,   true ,   true ,    false,   false,   true ,   true ,      true  },
-      /* propertyPrimitiveCollectionCount 17 */ { true ,   false,   false,   
false,   false,   false,    false,   false,   false,   false,      false },
-      /*           propertyPrimitiveValue 18 */ { false,   true ,   false,   
false,   false,   false,    false,   false,   false,   false,      false },
-      /*                             none 19 */ { false,   true ,   false,   
false,   false,   false,    false,   false,   false,   false,      false }
+      /*                                          0-FILTER 1-FORMAT 2-EXPAND 
3-ID     4-COUNT  5-ORDERBY 6-SEARCH 7-SELECT 8-SKIP   9-SKIPTOKEN 10-TOP 
11-APPLY */
+      /*                              all  0 */ { true ,   true ,   true ,   
false,   true ,   true ,    true ,   true ,   true ,   true ,      true , true  
},
+      /*                            batch  1 */ { false,   false,   false,   
false,   false,   false,    false,   false,   false,   false,      false, false 
},
+      /*                        crossjoin  2 */ { true ,   true ,   true ,   
false,   true ,   true ,    true ,   true ,   true ,   true ,      true , true  
},
+      /*                         entityId  3 */ { false,   true ,   true ,   
true ,   false,   false,    false,   true ,   false,   false,      false, false 
},
+      /*                         metadata  4 */ { false,   true ,   false,   
false,   false,   false,    false,   false,   false,   false,      false, false 
},
+      /*                          service  5 */ { false,   true ,   false,   
false,   false,   false,    false,   false,   false,   false,      false, false 
},
+      /*                        entitySet  6 */ { true ,   true ,   true ,   
false,   true ,   true ,    true ,   true ,   true ,   true ,      true , true  
},
+      /*                   entitySetCount  7 */ { true ,   false,   false,   
false,   false,   false,    true ,   false,   false,   false,      false, false 
},
+      /*                           entity  8 */ { false,   true ,   true ,   
false,   false,   false,    false,   true ,   false,   false,      false, false 
},
+      /*                      mediaStream  9 */ { false,   false,   false,   
false,   false,   false,    false,   false,   false,   false,      false, false 
},
+      /*                       references 10 */ { true ,   true ,   false,   
false,   true ,   true ,    true ,   false,   true ,   true ,      true , false 
},
+      /*                        reference 11 */ { false,   true ,   false,   
false,   false,   false,    false,   false,   false,   false,      false, false 
},
+      /*                  propertyComplex 12 */ { false,   true ,   true ,   
false,   false,   false,    false,   true ,   false,   false,      false, false 
},
+      /*        propertyComplexCollection 13 */ { true ,   true ,   true ,   
false,   true ,   true ,    false,   true ,   true ,   true ,      true , true  
},
+      /*   propertyComplexCollectionCount 14 */ { true ,   false,   false,   
false,   false,   false,    false,   false,   false,   false,      false, false 
},
+      /*                propertyPrimitive 15 */ { false,   true ,   false,   
false,   false,   false,    false,   false,   false,   false,      false, false 
},
+      /*      propertyPrimitiveCollection 16 */ { true ,   true ,   false,   
false,   true ,   true ,    false,   false,   true ,   true ,      true , false 
},
+      /* propertyPrimitiveCollectionCount 17 */ { true ,   false,   false,   
false,   false,   false,    false,   false,   false,   false,      false, false 
},
+      /*           propertyPrimitiveValue 18 */ { false,   true ,   false,   
false,   false,   false,    false,   false,   false,   false,      false, false 
},
+      /*                             none 19 */ { false,   true ,   false,   
false,   false,   false,    false,   false,   false,   false,      false, false 
}
     };
   //CHECKSTYLE:ON
   //@formatter:on
@@ -118,6 +118,7 @@ public class UriValidator {
     temp.put(SystemQueryOptionKind.SKIP, 8);
     temp.put(SystemQueryOptionKind.SKIPTOKEN, 9);
     temp.put(SystemQueryOptionKind.TOP, 10);
+    temp.put(SystemQueryOptionKind.APPLY, 11);
     OPTION_INDEX = Collections.unmodifiableMap(temp);
   }
 
@@ -255,7 +256,6 @@ public class UriValidator {
 
   private UriType getUriTypeForFunction(final UriResource lastPathSegment) 
throws UriValidationException {
     final UriResourceFunction uriFunction = (UriResourceFunction) 
lastPathSegment;
-
     final boolean isCollection = uriFunction.isCollection();
     final EdmTypeKind typeKind = 
uriFunction.getFunction().getReturnType().getType().getKind();
     UriType uriType;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/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 3b63c1b..985bfe6 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
@@ -73,6 +73,9 @@ 
UriParserSemanticException.NAMESPACE_NOT_ALLOWED_AT_FIRST_ELEMENT=Namespace is n
 UriParserSemanticException.COMPLEX_PARAMETER_IN_RESOURCE_PATH=Complex 
parameters must not appear in resource path segments; found: '%1$s'.
 UriParserSemanticException.TYPES_NOT_COMPATIBLE=The types '%1$s' and '%2$s' 
are not compatible.
 UriParserSemanticException.NOT_A_MEDIA_RESOURCE=The resource '%1$s' is not a 
media resource. $value can only be applied on media resources.
+UriParserSemanticException.IS_PROPERTY=The identifier '%1$s' is already used 
as a property.
+UriParserSemanticException.ONLY_FOR_PRIMITIVE_TYPES='%1$s' is only allowed for 
primitive-type expressions.
+UriParserSemanticException.FUNCTION_MUST_USE_COLLECTIONS=Only bound functions 
with collections of structural types as binding parameter and as return type 
are allowed; '%1$s' is not such a function.
 
 UriValidationException.UNSUPPORTED_QUERY_OPTION=The query option '%1$s' is not 
supported.
 UriValidationException.UNSUPPORTED_URI_KIND=The URI kind '%1$s' is not 
supported.

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/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 118e2ea..23bf1d1 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
@@ -97,6 +97,18 @@ public class UriTokenizerTest {
   }
 
   @Test
+  public void saveState() {
+    UriTokenizer tokenizer = new UriTokenizer("a*");
+    assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
+    tokenizer.saveState();
+    assertTrue(tokenizer.next(TokenKind.STAR));
+    assertTrue(tokenizer.next(TokenKind.EOF));
+    tokenizer.returnToSavedState();
+    assertTrue(tokenizer.next(TokenKind.STAR));
+    assertTrue(tokenizer.next(TokenKind.EOF));
+  }
+
+  @Test
   public void systemQueryOptions() {
     UriTokenizer tokenizer = new 
UriTokenizer("$expand=*;$filter=true;$levels=max;$orderby=false");
     assertTrue(tokenizer.next(TokenKind.EXPAND));
@@ -642,6 +654,64 @@ public class UriTokenizerTest {
     wrongToken(TokenKind.GeometryCollection, 
"geometry'SRID=0;Collection(Point(1 2),Point(3 4))'", 'x');
   }
 
+  @Test
+  public void aggregation() {
+    UriTokenizer tokenizer = new UriTokenizer("$apply=aggregate(a with sum as 
s from x with average)");
+    assertTrue(tokenizer.next(TokenKind.APPLY));
+    assertTrue(tokenizer.next(TokenKind.EQ));
+    assertTrue(tokenizer.next(TokenKind.AggregateTrafo));
+    assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
+    assertTrue(tokenizer.next(TokenKind.WithOperator));
+    assertTrue(tokenizer.next(TokenKind.SUM));
+    assertTrue(tokenizer.next(TokenKind.AsOperator));
+    assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
+    assertTrue(tokenizer.next(TokenKind.FromOperator));
+    assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
+    assertTrue(tokenizer.next(TokenKind.WithOperator));
+    assertTrue(tokenizer.next(TokenKind.AVERAGE));
+    assertTrue(tokenizer.next(TokenKind.CLOSE));
+    assertTrue(tokenizer.next(TokenKind.EOF));
+
+    tokenizer = new UriTokenizer("a with min as m");
+    assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
+    assertTrue(tokenizer.next(TokenKind.WithOperator));
+    assertTrue(tokenizer.next(TokenKind.MIN));
+
+    tokenizer = new UriTokenizer("a with countdistinct as c");
+    assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
+    assertTrue(tokenizer.next(TokenKind.WithOperator));
+    assertTrue(tokenizer.next(TokenKind.COUNTDISTINCT));
+
+    assertTrue(new UriTokenizer("identity").next(TokenKind.IDENTITY));
+    assertTrue(new 
UriTokenizer("bottomcount(1,x)").next(TokenKind.BottomCountTrafo));
+    assertTrue(new 
UriTokenizer("bottompercent(1,x)").next(TokenKind.BottomPercentTrafo));
+    assertTrue(new 
UriTokenizer("bottomsum(1,x)").next(TokenKind.BottomSumTrafo));
+    assertTrue(new 
UriTokenizer("topcount(1,x)").next(TokenKind.TopCountTrafo));
+    assertTrue(new 
UriTokenizer("toppercent(1,x)").next(TokenKind.TopPercentTrafo));
+    assertTrue(new UriTokenizer("topsum(1,x)").next(TokenKind.TopSumTrafo));
+    assertTrue(new UriTokenizer("compute(a mul b as 
m)").next(TokenKind.ComputeTrafo));
+
+    assertTrue(new UriTokenizer("search(a)").next(TokenKind.SearchTrafo));
+    assertTrue(new UriTokenizer("expand(a)").next(TokenKind.ExpandTrafo));
+    assertTrue(new UriTokenizer("filter(true)").next(TokenKind.FilterTrafo));
+
+    tokenizer = new UriTokenizer("groupby((rollup($all,x,y)))");
+    assertTrue(tokenizer.next(TokenKind.GroupByTrafo));
+    assertTrue(tokenizer.next(TokenKind.OPEN));
+    assertTrue(tokenizer.next(TokenKind.RollUpSpec));
+    assertTrue(tokenizer.next(TokenKind.ROLLUP_ALL));
+    assertTrue(tokenizer.next(TokenKind.COMMA));
+    assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
+    assertTrue(tokenizer.next(TokenKind.COMMA));
+    assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
+    assertTrue(tokenizer.next(TokenKind.CLOSE));
+    assertTrue(tokenizer.next(TokenKind.CLOSE));
+    assertTrue(tokenizer.next(TokenKind.CLOSE));
+    assertTrue(tokenizer.next(TokenKind.EOF));
+
+    assertTrue(new 
UriTokenizer("isdefined(x)").next(TokenKind.IsDefinedMethod));
+  }
+
   private void wrongToken(final TokenKind kind, final String value, final char 
disturbCharacter) {
     assertFalse(new UriTokenizer(disturbCharacter + value).next(kind));
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/6553e950/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
----------------------------------------------------------------------
diff --git 
a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
 
b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
index 28cf63d..ddbfb1a 100644
--- 
a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
+++ 
b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
@@ -233,7 +233,7 @@ public abstract class TechnicalProcessor implements 
Processor {
   }
 
   protected void validateOptions(final UriInfoResource uriInfo) throws 
ODataApplicationException {
-    if (uriInfo.getIdOption() != null) {
+    if (uriInfo.getIdOption() != null || uriInfo.getApplyOption() != null) {
       throw new ODataApplicationException("Not all of the specified options 
are supported.",
           HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
     }

Reply via email to