Repository: olingo-odata4
Updated Branches:
  refs/heads/master 72fcaa1a5 -> 9e67d0e3e


[OLINGO-935] $apply as option for $expand should be possible

Signed-off-by: Christian Amend <[email protected]>


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

Branch: refs/heads/master
Commit: 1600684d4f7dab8db570d02212f4bd12bb73a1a0
Parents: 72fcaa1
Author: Klaus Straubinger <[email protected]>
Authored: Fri Oct 7 14:36:51 2016 +0200
Committer: Christian Amend <[email protected]>
Committed: Fri Oct 7 14:51:57 2016 +0200

----------------------------------------------------------------------
 .../server/api/uri/queryoption/ExpandItem.java  |   5 +
 .../server/core/uri/parser/ExpandParser.java    |   7 +
 .../core/uri/queryoption/ExpandItemImpl.java    |  12 +-
 .../core/uri/queryoption/ExpandOptionImpl.java  |   3 +-
 .../core/uri/queryoption/OrderByItemImpl.java   |   4 +-
 .../core/uri/queryoption/SearchOptionImpl.java  |   3 +-
 .../olingo/server/core/uri/UriInfoImplTest.java |   6 +-
 .../core/uri/parser/ExpandParserTest.java       | 491 ++++++++-----------
 .../server/core/uri/parser/UriParserTest.java   |  24 +-
 .../core/uri/testutil/ExpandValidator.java      |  37 +-
 .../core/uri/testutil/FilterTreeToText.java     |  12 +-
 .../core/uri/testutil/TestUriValidator.java     |  28 +-
 12 files changed, 284 insertions(+), 348 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1600684d/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/ExpandItem.java
----------------------------------------------------------------------
diff --git 
a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/ExpandItem.java
 
b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/ExpandItem.java
index 4e71157..8ae8898 100644
--- 
a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/ExpandItem.java
+++ 
b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/ExpandItem.java
@@ -73,6 +73,11 @@ public interface ExpandItem {
   ExpandOption getExpandOption();
 
   /**
+   * @return Information on the option $apply when used within $expand
+   */
+  ApplyOption getApplyOption();
+
+  /**
    * @return A {@link UriInfoResource} object containing the resource path 
segments to be expanded
    */
   UriInfoResource getResourcePath();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1600684d/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
index 8a493ff..53a14d7 100644
--- 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
@@ -50,6 +50,7 @@ import 
org.apache.olingo.server.core.uri.queryoption.ExpandOptionImpl;
 import org.apache.olingo.server.core.uri.queryoption.LevelsOptionImpl;
 import org.apache.olingo.server.core.uri.queryoption.SkipOptionImpl;
 import org.apache.olingo.server.core.uri.queryoption.TopOptionImpl;
+import 
org.apache.olingo.server.core.uri.queryoption.apply.DynamicStructuredType;
 import org.apache.olingo.server.core.uri.validator.UriValidationException;
 
 public class ExpandParser {
@@ -276,6 +277,12 @@ public class ExpandParser {
           topOption.setValue(value);
           systemQueryOption = topOption;
 
+        } else if (!forRef && !forCount && tokenizer.next(TokenKind.APPLY)) {
+          ParserHelper.requireNext(tokenizer, TokenKind.EQ);
+          systemQueryOption = new ApplyParser(edm, odata).parse(tokenizer,
+              // Data aggregation may change the structure of the result, so 
we create a new dynamic type.
+              new DynamicStructuredType(referencedType), null, aliases);
+
         } else {
           throw new UriParserSyntaxException("Allowed query option expected.",
               UriParserSyntaxException.MessageKeys.SYNTAX);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1600684d/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/ExpandItemImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/ExpandItemImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/ExpandItemImpl.java
index c21aa26..a1dc64b 100644
--- 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/ExpandItemImpl.java
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/ExpandItemImpl.java
@@ -23,6 +23,7 @@ import java.util.List;
 import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.ex.ODataRuntimeException;
 import org.apache.olingo.server.api.uri.UriInfoResource;
+import org.apache.olingo.server.api.uri.queryoption.ApplyOption;
 import org.apache.olingo.server.api.uri.queryoption.CountOption;
 import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
 import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
@@ -45,6 +46,7 @@ public class ExpandItemImpl implements ExpandItem {
   private CountOption inlineCountOption;
   private SelectOption selectOption;
   private ExpandOption expandOption;
+  private ApplyOption applyOption;
 
   private UriInfoResource resourceInfo;
 
@@ -56,7 +58,10 @@ public class ExpandItemImpl implements ExpandItem {
 
   public ExpandItemImpl setSystemQueryOption(final SystemQueryOption sysItem) {
 
-    if (sysItem instanceof ExpandOption) {
+    if (sysItem instanceof ApplyOption) {
+      validateDoubleSystemQueryOption(applyOption, sysItem);
+      applyOption = (ApplyOption) sysItem;
+    } else if (sysItem instanceof ExpandOption) {
       validateDoubleSystemQueryOption(expandOption, sysItem);
       expandOption = (ExpandOption) sysItem;
     } else if (sysItem instanceof FilterOption) {
@@ -148,6 +153,11 @@ public class ExpandItemImpl implements ExpandItem {
     return expandOption;
   }
 
+  @Override
+  public ApplyOption getApplyOption() {
+    return applyOption;
+  }
+
   public ExpandItemImpl setResourcePath(final UriInfoResource resourceInfo) {
     this.resourceInfo = resourceInfo;
     return this;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1600684d/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/ExpandOptionImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/ExpandOptionImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/ExpandOptionImpl.java
index 87e2b6c..bda2957 100644
--- 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/ExpandOptionImpl.java
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/ExpandOptionImpl.java
@@ -34,8 +34,9 @@ public class ExpandOptionImpl extends SystemQueryOptionImpl 
implements ExpandOpt
     setKind(SystemQueryOptionKind.EXPAND);
   }
 
-  public void addExpandItem(final ExpandItem expandItem) {
+  public ExpandOptionImpl addExpandItem(final ExpandItem expandItem) {
     expandItems.add(expandItem);
+    return this;
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1600684d/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/OrderByItemImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/OrderByItemImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/OrderByItemImpl.java
index ad57d6b..ae3d66c 100644
--- 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/OrderByItemImpl.java
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/OrderByItemImpl.java
@@ -32,7 +32,7 @@ public class OrderByItemImpl implements OrderByItem {
     return descending;
   }
 
-  public OrderByItem setDescending(final boolean descending) {
+  public OrderByItemImpl setDescending(final boolean descending) {
     this.descending = descending;
     return this;
   }
@@ -42,7 +42,7 @@ public class OrderByItemImpl implements OrderByItem {
     return expression;
   }
 
-  public OrderByItem setExpression(final Expression expression) {
+  public OrderByItemImpl setExpression(final Expression expression) {
     this.expression = expression;
     return this;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1600684d/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/SearchOptionImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/SearchOptionImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/SearchOptionImpl.java
index 45a0cd4..813798e 100644
--- 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/SearchOptionImpl.java
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/SearchOptionImpl.java
@@ -35,7 +35,8 @@ public class SearchOptionImpl extends SystemQueryOptionImpl 
implements SearchOpt
     return searchExpression;
   }
 
-  public void setSearchExpression(final SearchExpression searchExpression) {
+  public SearchOptionImpl setSearchExpression(final SearchExpression 
searchExpression) {
     this.searchExpression = searchExpression;
+    return this;
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1600684d/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 bdc2986..ac35292 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
@@ -33,6 +33,7 @@ import org.apache.olingo.server.api.uri.UriResourceEntitySet;
 import org.apache.olingo.server.api.uri.queryoption.AliasQueryOption;
 import org.apache.olingo.server.api.uri.queryoption.QueryOption;
 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.CustomQueryOptionImpl;
 import org.apache.olingo.server.core.uri.queryoption.ExpandOptionImpl;
@@ -107,6 +108,7 @@ public class UriInfoImplTest {
 
   @Test
   public void customQueryOption() {
+    final QueryOption apply = new ApplyOptionImpl().setName("");
     final QueryOption expand = new ExpandOptionImpl().setName("");
     final QueryOption filter = new FilterOptionImpl().setName("");
     final QueryOption format = new FormatOptionImpl().setName("");
@@ -128,6 +130,7 @@ public class UriInfoImplTest {
     final QueryOption alias = new 
AliasQueryOptionImpl().setName("alias").setText("C");
 
     final UriInfo uriInfo = new UriInfoImpl()
+        .setQueryOption(apply)
         .setQueryOption(expand)
         .setQueryOption(filter)
         .setQueryOption(format)
@@ -145,7 +148,8 @@ public class UriInfoImplTest {
         .setQueryOption(initialQueryOption)
         .setQueryOption(alias);
 
-    assertEquals(12, uriInfo.getSystemQueryOptions().size());
+    assertEquals(13, uriInfo.getSystemQueryOptions().size());
+    assertEquals(apply, uriInfo.getApplyOption());
     assertEquals(expand, uriInfo.getExpandOption());
     assertEquals(filter, uriInfo.getFilterOption());
     assertEquals(format, uriInfo.getFormatOption());

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1600684d/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/ExpandParserTest.java
----------------------------------------------------------------------
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/ExpandParserTest.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/ExpandParserTest.java
index ebc4cc6..e2f129d 100644
--- 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/ExpandParserTest.java
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/ExpandParserTest.java
@@ -23,172 +23,131 @@ import java.util.Collections;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edmx.EdmxReference;
 import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataLibraryException;
+import org.apache.olingo.server.api.uri.UriInfo;
 import org.apache.olingo.server.api.uri.UriInfoKind;
+import org.apache.olingo.server.api.uri.queryoption.ApplyItem;
+import org.apache.olingo.server.api.uri.queryoption.apply.Aggregate;
+import org.apache.olingo.server.api.uri.queryoption.apply.AggregateExpression;
 import 
org.apache.olingo.server.core.uri.parser.UriParserSemanticException.MessageKeys;
+import org.apache.olingo.server.core.uri.testutil.ExpandValidator;
 import org.apache.olingo.server.core.uri.testutil.TestUriValidator;
 import org.apache.olingo.server.tecsvc.provider.ComplexTypeProvider;
 import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
 import org.apache.olingo.server.tecsvc.provider.EntityTypeProvider;
 import org.apache.olingo.server.tecsvc.provider.PropertyProvider;
+import org.junit.Assert;
 import org.junit.Test;
 
 /** Tests of the parts of the URI parser that parse the sytem query option 
$expand. */
 public class ExpandParserTest {
 
-  private static final Edm edm = OData.newInstance().createServiceMetadata(
+  private static final OData oData = OData.newInstance();
+  private static final Edm edm = oData.createServiceMetadata(
       new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
 
-  private final TestUriValidator testUri = new TestUriValidator().setEdm(edm);
-
   @Test
   public void expandStar() throws Exception {
-    testUri.run("ESKeyNav(1)", "$expand=*")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .isSegmentStar();
-
-    testUri.run("ESKeyNav(1)", "$expand=*/$ref")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
+    runOnETKeyNav("*").isSegmentStar();
+
+    runOnETKeyNav("*/$ref")
         .isSegmentStar()
         .isSegmentRef();
 
-    testUri.run("ESKeyNav(1)", "$expand=*/$ref,NavPropertyETKeyNavMany")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
+    runOnETKeyNav("*/$ref,NavPropertyETKeyNavMany")
         .isSegmentStar().isSegmentRef()
         .next()
-        .goPath().first()
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true);
 
-    testUri.run("ESKeyNav(1)", "$expand=*($levels=3)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
+    runOnETKeyNav("*($levels=3)")
         .isSegmentStar()
-        .isLevelText("3");
+        .isLevels(3);
 
-    testUri.run("ESKeyNav(1)", "$expand=*($levels=max)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
+    runOnETKeyNav("*($levels=max)")
         .isSegmentStar()
-        .isLevelText("max");
+        .isLevelsMax();
   }
 
   @Test
   public void expandNavigationRef() throws Exception {
-    testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany/$ref")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany/$ref")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .n().isRef();
 
-    testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavOne/$ref")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavOne/$ref")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavOne", 
EntityTypeProvider.nameETKeyNav, false)
-        .isType(EntityTypeProvider.nameETKeyNav, false)
         .n().isRef();
 
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany/$ref($filter=PropertyInt16 eq 1)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany/$ref($filter=PropertyInt16 eq 1)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .n().isRef()
         .goUpExpandValidator().goFilter().is("<<PropertyInt16> eq <1>>");
 
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany/$ref($orderby=PropertyInt16)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany/$ref($orderby=PropertyInt16)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .n().isRef()
         .goUpExpandValidator()
         .isSortOrder(0, false)
         .goOrder(0).goPath().isPrimitiveProperty("PropertyInt16", 
PropertyProvider.nameInt16, false);
 
-    testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany/$ref($skip=1)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany/$ref($skip=1)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .n().isRef()
         .goUpExpandValidator()
-        .isSkipText("1");
+        .isSkip(1);
 
-    testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany/$ref($top=2)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany/$ref($top=2)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .n().isRef()
         .goUpExpandValidator()
-        .isTopText("2");
+        .isTop(2);
 
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany/$ref($count=true)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany/$ref($count=true)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .n().isRef()
         .goUpExpandValidator()
-        .isInlineCountText("true");
+        .isInlineCount(true);
 
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany/$ref($skip=1;$top=3)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany/$ref($skip=1;$top=3)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .n().isRef()
         .goUpExpandValidator()
-        .isSkipText("1")
-        .isTopText("3");
+        .isSkip(1)
+        .isTop(3);
 
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany/$ref($skip=1%3b$top=3)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany/$ref($skip=1%3b$top=3)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .n().isRef()
         .goUpExpandValidator()
-        .isSkipText("1")
-        .isTopText("3");
+        .isSkip(1)
+        .isTop(3);
   }
 
   @Test
   public void expandNavigationCount() throws Exception {
-    testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany/$count")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany/$count")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .n().isCount();
 
-    testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavOne/$count")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavOne/$count")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavOne", 
EntityTypeProvider.nameETKeyNav, false)
-        .isType(EntityTypeProvider.nameETKeyNav, false)
         .n().isCount();
 
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany/$count($filter=PropertyInt16 gt 1)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany/$count($filter=PropertyInt16 gt 1)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .n().isCount()
         .goUpExpandValidator()
         .goFilter().is("<<PropertyInt16> gt <1>>");
@@ -196,366 +155,322 @@ public class ExpandParserTest {
 
   @Test
   public void expandNavigationOptions() throws Exception {
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany($filter=PropertyInt16 eq 1)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETTwoKeyNav("NavPropertyETKeyNavMany")
+        .goPath()
+        .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true);
+
+    runOnETKeyNav("NavPropertyETKeyNavMany($filter=PropertyInt16 eq 1)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .goUpExpandValidator().goFilter().is("<<PropertyInt16> eq <1>>");
 
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany($orderby=PropertyInt16)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany($orderby=PropertyInt16)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .goUpExpandValidator()
         .isSortOrder(0, false)
         .goOrder(0).goPath().isPrimitiveProperty("PropertyInt16", 
PropertyProvider.nameInt16, false);
 
-    testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany($skip=1)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany($skip=1)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .goUpExpandValidator()
-        .isSkipText("1");
+        .isSkip(1);
 
-    testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany($top=2)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany($top=2)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .goUpExpandValidator()
-        .isTopText("2");
+        .isTop(2);
 
-    testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavMany($count=true)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany($count=true)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .goUpExpandValidator()
-        .isInlineCountText("true");
+        .isInlineCount(true);
 
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany($select=PropertyString)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany($select=PropertyString)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .goUpExpandValidator()
         .goSelectItem(0).isPrimitiveProperty("PropertyString", 
PropertyProvider.nameString, false);
 
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany($expand=NavPropertyETTwoKeyNavOne)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany($expand=NavPropertyETTwoKeyNavOne)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .goUpExpandValidator()
         .goExpand()
-        .goPath().first()
+        .goPath()
         .isNavProperty("NavPropertyETTwoKeyNavOne", 
EntityTypeProvider.nameETTwoKeyNav, false);
 
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany($expand=NavPropertyETKeyNavMany)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany($expand=NavPropertyETKeyNavMany)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .goUpExpandValidator()
         .goExpand()
-        .goPath().first()
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true);
 
-    testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavOne($levels=5)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavOne($levels=5)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavOne", 
EntityTypeProvider.nameETKeyNav, false)
-        .isType(EntityTypeProvider.nameETKeyNav, false)
         .goUpExpandValidator()
-        .isLevelText("5");
+        .isLevels(5);
 
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany($select=PropertyString)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany($select=PropertyString)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .goUpExpandValidator()
         .goSelectItem(0).isPrimitiveProperty("PropertyString", 
PropertyProvider.nameString, false);
 
-    testUri.run("ESKeyNav(1)", "$expand=NavPropertyETKeyNavOne($levels=max)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavOne($levels=max)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavOne", 
EntityTypeProvider.nameETKeyNav, false)
-        .isType(EntityTypeProvider.nameETKeyNav, false)
         .goUpExpandValidator()
-        .isLevelText("max");
+        .isLevelsMax();
 
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany($skip=1;$top=2)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany($skip=1;$top=2)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .goUpExpandValidator()
-        .isSkipText("1")
-        .isTopText("2");
+        .isSkip(1)
+        .isTop(2);
 
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany($skip=1%3b$top=2)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavMany($skip=1%3b$top=2)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true)
         .goUpExpandValidator()
-        .isSkipText("1")
-        .isTopText("2");
+        .isSkip(1)
+        .isTop(2);
 
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany($search=Country AND Western)")
-        .isKind(UriInfoKind.resource).goExpand()
-        .first().goPath().first().isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
+    runOnETKeyNav("NavPropertyETKeyNavMany($search=Country AND Western)")
+        .goPath().isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
         .goUpExpandValidator()
         .isSearchSerialized("{'Country' AND 'Western'}");
+  }
 
-    testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='Hugo')", 
"$expand=NavPropertyETKeyNavMany")
-        .isKind(UriInfoKind.resource).goPath()
-        .first()
-        .isKeyPredicate(0, "PropertyInt16", "1")
-        .isKeyPredicate(1, "PropertyString", "'Hugo'")
-        .goUpUriValidator().goExpand()
-        .first()
-        .goPath().first()
-        .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav, true);
+  @Test
+  public void expandNavigationApplyOption() throws Exception {
+    UriInfo uriInfo = new Parser(edm, oData).parseUri("ESTwoKeyNav",
+        
"$expand=NavPropertyETKeyNavMany($apply=identity),NavPropertyETKeyNavOne", 
null);
+    Assert.assertEquals(ApplyItem.Kind.IDENTITY,
+        
uriInfo.getExpandOption().getExpandItems().get(0).getApplyOption().getApplyItems().get(0).getKind());
+    Assert.assertEquals("NavPropertyETKeyNavOne",
+        uriInfo.getExpandOption().getExpandItems().get(1)
+            .getResourcePath().getUriResourceParts().get(0).getSegmentValue());
+
+    uriInfo = new Parser(edm, oData).parseUri("ESTwoKeyNav",
+        "$expand=NavPropertyETKeyNavMany($apply=aggregate(PropertyInt16 with 
sum as s))", null);
+    final ApplyItem applyItem =
+        
uriInfo.getExpandOption().getExpandItems().get(0).getApplyOption().getApplyItems().get(0);
+    Assert.assertEquals(ApplyItem.Kind.AGGREGATE, applyItem.getKind());
+    Assert.assertEquals(AggregateExpression.StandardMethod.SUM,
+        ((Aggregate) applyItem).getExpressions().get(0).getStandardMethod());
   }
 
   @Test
   public void expandTypeCasts() throws Exception {
-    testUri.run("ESTwoKeyNav", 
"$expand=olingo.odata.test1.ETBaseTwoKeyNav/NavPropertyETKeyNavMany")
-        .isKind(UriInfoKind.resource)
-        .goExpand().first()
+    
runOnETTwoKeyNav("olingo.odata.test1.ETBaseTwoKeyNav/NavPropertyETKeyNavMany")
         .isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
-        .goPath().first()
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true);
 
-    testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='Hugo')",
-        "$expand=olingo.odata.test1.ETBaseTwoKeyNav/NavPropertyETKeyNavMany")
-        .isKind(UriInfoKind.resource).goPath().first()
-        .isKeyPredicate(0, "PropertyInt16", "1")
-        .isKeyPredicate(1, "PropertyString", "'Hugo'")
-        .goUpUriValidator().goExpand().first()
+    
runOnETTwoKeyNav("olingo.odata.test1.ETBaseTwoKeyNav/NavPropertyETKeyNavMany")
         .isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
-        .goPath().first()
-        .isType(EntityTypeProvider.nameETKeyNav)
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true);
 
-    testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')",
-        
"$expand=olingo.odata.test1.ETBaseTwoKeyNav/NavPropertyETTwoKeyNavMany")
-        .isKind(UriInfoKind.resource).goPath().first()
-        .isKeyPredicate(0, "PropertyInt16", "1")
-        .isKeyPredicate(1, "PropertyString", "'2'")
-        .goUpUriValidator().goExpand().first()
+    
runOnETTwoKeyNav("olingo.odata.test1.ETBaseTwoKeyNav/NavPropertyETTwoKeyNavMany")
         .isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
-        .goPath().first()
-        .isType(EntityTypeProvider.nameETTwoKeyNav)
+        .goPath()
         .isNavProperty("NavPropertyETTwoKeyNavMany", 
EntityTypeProvider.nameETTwoKeyNav, true);
 
-    testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')",
-        
"$expand=olingo.odata.test1.ETBaseTwoKeyNav/NavPropertyETTwoKeyNavMany/olingo.odata.test1.ETTwoBaseTwoKeyNav")
-        .isKind(UriInfoKind.resource).goPath().first()
-        .isKeyPredicate(0, "PropertyInt16", "1")
-        .isKeyPredicate(1, "PropertyString", "'2'")
-        .goUpUriValidator().goExpand().first()
+    
runOnETTwoKeyNav("olingo.odata.test1.ETBaseTwoKeyNav/NavPropertyETTwoKeyNavMany"
+        + "/olingo.odata.test1.ETTwoBaseTwoKeyNav")
         .isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
-        .goPath().first()
+        .goPath()
         .isNavProperty("NavPropertyETTwoKeyNavMany", 
EntityTypeProvider.nameETTwoKeyNav, true)
         .isTypeFilterOnCollection(EntityTypeProvider.nameETTwoBaseTwoKeyNav);
 
-    testUri.run("ESTwoKeyNav", 
"$expand=olingo.odata.test1.ETBaseTwoKeyNav/PropertyCompNav/NavPropertyETTwoKeyNavOne")
-        .isKind(UriInfoKind.resource)
-        .goExpand().first()
+    
runOnETTwoKeyNav("olingo.odata.test1.ETBaseTwoKeyNav/PropertyCompNav/NavPropertyETTwoKeyNavOne")
         .isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
-        .goPath().first()
+        .goPath()
         .isComplexProperty("PropertyCompNav", 
ComplexTypeProvider.nameCTBasePrimCompNav, false)
         .n()
         .isNavProperty("NavPropertyETTwoKeyNavOne", 
EntityTypeProvider.nameETTwoKeyNav, false);
 
-    testUri.run("ESTwoKeyNav", 
"$expand=olingo.odata.test1.ETBaseTwoKeyNav/PropertyCompNav/*")
-        .isKind(UriInfoKind.resource)
-        .goExpand().first()
+    runOnETTwoKeyNav("olingo.odata.test1.ETBaseTwoKeyNav/PropertyCompNav/*")
         .isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
         .isSegmentStar()
-        .goPath().first().isComplexProperty("PropertyCompNav", 
ComplexTypeProvider.nameCTBasePrimCompNav, false);
+        .goPath().isComplexProperty("PropertyCompNav", 
ComplexTypeProvider.nameCTBasePrimCompNav, false);
 
-    testUri.run("ESTwoKeyNav", 
"$expand=olingo.odata.test1.ETBaseTwoKeyNav/PropertyCompNav"
+    runOnETTwoKeyNav("olingo.odata.test1.ETBaseTwoKeyNav/PropertyCompNav"
         + "/olingo.odata.test1.CTTwoBasePrimCompNav/NavPropertyETTwoKeyNavOne")
-        .isKind(UriInfoKind.resource)
-        .goExpand().first()
         .isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
-        .goPath().first()
+        .goPath()
         .isComplexProperty("PropertyCompNav", 
ComplexTypeProvider.nameCTBasePrimCompNav, false)
         .isTypeFilter(ComplexTypeProvider.nameCTTwoBasePrimCompNav)
         .n()
         .isNavProperty("NavPropertyETTwoKeyNavOne", 
EntityTypeProvider.nameETTwoKeyNav, false);
 
-    testUri.run("ESKeyNav", 
"$expand=NavPropertyETTwoKeyNavMany/Namespace1_Alias.ETBaseTwoKeyNav"
+    runOnETKeyNav("NavPropertyETTwoKeyNavMany/Namespace1_Alias.ETBaseTwoKeyNav"
         + "($expand=NavPropertyETBaseTwoKeyNavOne)")
-        .isKind(UriInfoKind.resource)
-        .goExpand().goPath().first()
+        .goPath()
         .isNavProperty("NavPropertyETTwoKeyNavMany", 
EntityTypeProvider.nameETTwoKeyNav, true)
-        .isType(EntityTypeProvider.nameETTwoKeyNav, true)
         .isTypeFilterOnCollection(EntityTypeProvider.nameETBaseTwoKeyNav)
         .goUpExpandValidator()
         // go to the expand options of the current expand
         .goExpand()
-        .goPath().first()
+        .goPath()
         .isNavProperty("NavPropertyETBaseTwoKeyNavOne", 
EntityTypeProvider.nameETBaseTwoKeyNav, false);
 
-    testUri.run("ESKeyNav(1)", 
"$expand=NavPropertyETKeyNavMany/$ref,NavPropertyETTwoKeyNavMany($skip=2;$top=1)")
-        .isKind(UriInfoKind.resource)
-        .goExpand().first()
+    
runOnETKeyNav("NavPropertyETKeyNavMany/$ref,NavPropertyETTwoKeyNavMany($skip=2;$top=1)")
         .goPath()
-        .first()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
         .n().isRef()
         .goUpExpandValidator()
         .next()
         .goPath()
-        .first().isNavProperty("NavPropertyETTwoKeyNavMany", 
EntityTypeProvider.nameETTwoKeyNav, true)
+        .isNavProperty("NavPropertyETTwoKeyNavMany", 
EntityTypeProvider.nameETTwoKeyNav, true)
         .goUpExpandValidator()
-        .isSkipText("2")
-        .isTopText("1");
+        .isSkip(2)
+        .isTop(1);
 
-    testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')", 
"$expand=olingo.odata.test1.ETBaseTwoKeyNav"
-        + 
"/NavPropertyETTwoKeyNavMany/olingo.odata.test1.ETTwoBaseTwoKeyNav($select=PropertyString)")
-        .isKind(UriInfoKind.resource).goPath()
-        .first()
-        .isKeyPredicate(0, "PropertyInt16", "1")
-        .isKeyPredicate(1, "PropertyString", "'2'")
-        .goUpUriValidator().goExpand().first()
+    
runOnETTwoKeyNav("olingo.odata.test1.ETBaseTwoKeyNav/NavPropertyETTwoKeyNavMany"
+        + "/olingo.odata.test1.ETTwoBaseTwoKeyNav($select=PropertyString)")
         .isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
-        .goPath().first()
+        .goPath()
         .isNavProperty("NavPropertyETTwoKeyNavMany", 
EntityTypeProvider.nameETTwoKeyNav, true)
-        .isType(EntityTypeProvider.nameETTwoKeyNav)
         .isTypeFilterOnCollection(EntityTypeProvider.nameETTwoBaseTwoKeyNav)
         .goUpExpandValidator()
         .goSelectItem(0).isPrimitiveProperty("PropertyString", 
PropertyProvider.nameString, false);
 
-    testUri.run("ESKeyNav", 
"$expand=NavPropertyETKeyNavOne($expand=NavPropertyETKeyNavMany("
-        + "$expand=NavPropertyETKeyNavOne))")
-        .isKind(UriInfoKind.resource)
-        .goExpand().first()
-        .goPath().first()
+    
runOnETKeyNav("NavPropertyETKeyNavOne($expand=NavPropertyETKeyNavMany($expand=NavPropertyETKeyNavOne))")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavOne", 
EntityTypeProvider.nameETKeyNav, false)
-        .isType(EntityTypeProvider.nameETKeyNav)
         .goUpExpandValidator()
-        .goExpand().first()
-        .goPath().first()
+        .goExpand()
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavMany", 
EntityTypeProvider.nameETKeyNav, true)
-        .isType(EntityTypeProvider.nameETKeyNav)
         .goUpExpandValidator()
-        .goExpand().first()
-        .goPath().first()
-        .isNavProperty("NavPropertyETKeyNavOne", 
EntityTypeProvider.nameETKeyNav, false)
-        .isType(EntityTypeProvider.nameETKeyNav);
+        .goExpand()
+        .goPath()
+        .isNavProperty("NavPropertyETKeyNavOne", 
EntityTypeProvider.nameETKeyNav, false);
 
-    testUri.run("ESKeyNav", 
"$expand=NavPropertyETKeyNavOne($select=PropertyInt16)")
-        .isKind(UriInfoKind.resource)
-        .goExpand().first()
-        .goPath().first()
+    runOnETKeyNav("NavPropertyETKeyNavOne($select=PropertyInt16)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavOne", 
EntityTypeProvider.nameETKeyNav, false)
-        .isType(EntityTypeProvider.nameETKeyNav)
         .goUpExpandValidator()
         .goSelectItem(0).isPrimitiveProperty("PropertyInt16", 
PropertyProvider.nameInt16, false);
 
-    testUri.run("ESKeyNav", 
"$expand=NavPropertyETKeyNavOne($select=PropertyCompNav/PropertyInt16)")
-        .isKind(UriInfoKind.resource)
-        .goExpand().first()
-        .goPath().first()
+    
runOnETKeyNav("NavPropertyETKeyNavOne($select=PropertyCompNav/PropertyInt16)")
+        .goPath()
         .isNavProperty("NavPropertyETKeyNavOne", 
EntityTypeProvider.nameETKeyNav, false)
-        .isType(EntityTypeProvider.nameETKeyNav)
         .goUpExpandValidator()
         .goSelectItem(0)
-        .first().isComplexProperty("PropertyCompNav", 
ComplexTypeProvider.nameCTNavFiveProp, false)
+        .isComplexProperty("PropertyCompNav", 
ComplexTypeProvider.nameCTNavFiveProp, false)
         .n().isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, 
false);
 
-    testUri.runEx("ESKeyNav", "$expand=undefined")
-        .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/*+")
+    
runOnETKeyNavEx("undefined").isExSemantic(MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
+    
runOnETTwoKeyNavEx("PropertyCompNav/undefined").isExSemantic(MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
+    runOnETTwoKeyNavEx("PropertyCompNav/*+")
         
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
   }
 
   @Test
   public void duplicatedSystemQueryOptionsInExpand() throws Exception {
-    testUri.runEx("ESKeyNav", 
"$expand=NavPropertyETKeyNavOne($select=PropertyInt16;$select=PropertyInt16)")
+    
runOnETKeyNavEx("NavPropertyETKeyNavOne($select=PropertyInt16;$select=PropertyInt16)")
         
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
 
-    testUri.runEx("ESKeyNav", 
"$expand=NavPropertyETKeyNavOne($filter=true;$filter=true)")
+    runOnETKeyNavEx("NavPropertyETKeyNavOne($filter=true;$filter=true)")
         
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
 
-    testUri.runEx("ESKeyNav", 
"$expand=NavPropertyETKeyNavOne($orderby=PropertyInt16;$orderby=PropertyInt16)")
+    
runOnETKeyNavEx("NavPropertyETKeyNavOne($orderby=PropertyInt16;$orderby=PropertyInt16)")
         
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
 
-    testUri.runEx("ESKeyNav", 
"$expand=NavPropertyETKeyNavOne($levels=2;$levels=3)")
+    runOnETKeyNavEx("NavPropertyETKeyNavOne($levels=2;$levels=3)")
         
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
 
-    testUri.runEx("ESKeyNav", 
"$expand=NavPropertyETKeyNavOne($expand=*;$expand=*)")
+    runOnETKeyNavEx("NavPropertyETKeyNavOne($expand=*;$expand=*)")
         
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
 
-    testUri.runEx("ESKeyNav", 
"$expand=NavPropertyETKeyNavOne($count=true;$count=true)")
+    runOnETKeyNavEx("NavPropertyETKeyNavOne($count=true;$count=true)")
         
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
 
-    testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($top=1;$top=1)")
+    runOnETKeyNavEx("NavPropertyETKeyNavOne($top=1;$top=1)")
         
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
 
-    testUri.runEx("ESKeyNav", 
"$expand=NavPropertyETKeyNavOne($skip=2;$skip=2)")
+    runOnETKeyNavEx("NavPropertyETKeyNavOne($skip=2;$skip=2)")
         
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
 
-    testUri.runEx("ESKeyNav", 
"$expand=NavPropertyETKeyNavOne($search=Test;$search=Test)")
+    runOnETKeyNavEx("NavPropertyETKeyNavOne($search=Test;$search=Test)")
         
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
   }
 
   @Test
   public void simpleKeyInExpandSystemQueryOption() throws Exception {
-    testUri.runEx("ESAllPrim(0)", 
"$expand=NavPropertyETTwoPrimMany(-365)($filter=PropertyString eq 'Test 
String1')")
+    runOnETTwoKeyNavEx("NavPropertyETKeyNavMany(-365)($filter=PropertyString 
eq 'Test String1')")
         .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
   }
 
   @Test
   public void compoundKeyInExpandSystemQueryOption() throws Exception {
-    testUri.runEx("ESAllPrim(0)", 
"$expand=NavPropertyETTwoPrimMany(PropertyInt16=1,PropertyString=2)"
+    
runOnETKeyNavEx("NavPropertyETTwoKeyNavMany(PropertyInt16=1,PropertyString=2)"
         + "($filter=PropertyString eq 'Test String1')")
         .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
   }
 
   @Test
   public void keyPredicatesInExpandFilter() throws Exception {
-    testUri.run("ESKeyNav(0)", 
"$expand=NavPropertyETTwoKeyNavMany($filter=NavPropertyETTwoKeyNavMany"
-        + "(PropertyInt16=1,PropertyString='2')/PropertyInt16 eq 
1)").goExpand()
-        .first().goPath().isNavProperty("NavPropertyETTwoKeyNavMany", 
EntityTypeProvider.nameETTwoKeyNav, true)
+    
runOnETKeyNav("NavPropertyETTwoKeyNavMany($filter=NavPropertyETTwoKeyNavMany"
+        + "(PropertyInt16=1,PropertyString='2')/PropertyInt16 eq 1)")
+        .goPath().isNavProperty("NavPropertyETTwoKeyNavMany", 
EntityTypeProvider.nameETTwoKeyNav, true)
         .goUpExpandValidator().goFilter()
-        .is("<<NavPropertyETTwoKeyNavMany/PropertyInt16> eq <1>>");
+        .left().goPath()
+        .isNavProperty("NavPropertyETTwoKeyNavMany", 
EntityTypeProvider.nameETTwoKeyNav, false)
+        .isKeyPredicate(0, "PropertyInt16", "1")
+        .isKeyPredicate(1, "PropertyString", "'2'")
+        .n().isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, 
false);
   }
 
   @Test
   public void keyPredicatesInDoubleExpandedFilter() throws Exception {
-    testUri.run("ESKeyNav(0)", 
"$expand=NavPropertyETTwoKeyNavMany($expand=NavPropertyETTwoKeyNavMany"
+    
runOnETKeyNav("NavPropertyETTwoKeyNavMany($expand=NavPropertyETTwoKeyNavMany"
         + 
"($filter=NavPropertyETTwoKeyNavMany(PropertyInt16=1,PropertyString='2')/PropertyInt16
 eq 1))")
-        .goExpand()
-        .first().goPath().isNavProperty("NavPropertyETTwoKeyNavMany", 
EntityTypeProvider.nameETTwoKeyNav, true)
+        .goPath().isNavProperty("NavPropertyETTwoKeyNavMany", 
EntityTypeProvider.nameETTwoKeyNav, true)
         .goUpExpandValidator().goExpand()
-        .first().goPath().isNavProperty("NavPropertyETTwoKeyNavMany", 
EntityTypeProvider.nameETTwoKeyNav, true)
+        .goPath().isNavProperty("NavPropertyETTwoKeyNavMany", 
EntityTypeProvider.nameETTwoKeyNav, true)
         .goUpExpandValidator().goFilter()
-        .is("<<NavPropertyETTwoKeyNavMany/PropertyInt16> eq <1>>");
+        .left().goPath()
+        .isNavProperty("NavPropertyETTwoKeyNavMany", 
EntityTypeProvider.nameETTwoKeyNav, false)
+        .isKeyPredicate(0, "PropertyInt16", "1")
+        .isKeyPredicate(1, "PropertyString", "'2'")
+        .n().isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, 
false);
+  }
+
+  private ExpandValidator runOnETKeyNav(final String expand) throws 
ODataLibraryException {
+    return new TestUriValidator().setEdm(edm).run("ESKeyNav(1)", "$expand=" + 
expand)
+        
.isKind(UriInfoKind.resource).goPath().isType(EntityTypeProvider.nameETKeyNav, 
false)
+        .goUpUriValidator().goExpand();
+  }
+
+  private ExpandValidator runOnETTwoKeyNav(final String expand) throws 
ODataLibraryException {
+    return new TestUriValidator().setEdm(edm)
+        .run("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')", "$expand=" + 
expand)
+        .isKind(UriInfoKind.resource)
+        .goPath()
+        .isType(EntityTypeProvider.nameETTwoKeyNav, false)
+        .isKeyPredicate(0, "PropertyInt16", "1")
+        .isKeyPredicate(1, "PropertyString", "'2'")
+        .goUpUriValidator()
+        .goExpand();
+  }
+
+  private TestUriValidator runOnETKeyNavEx(final String expand) throws 
ODataLibraryException {
+    return new TestUriValidator().setEdm(edm).runEx("ESKeyNav(1)", "$expand=" 
+ expand);
+  }
+
+  private TestUriValidator runOnETTwoKeyNavEx(final String expand) throws 
ODataLibraryException {
+    return new TestUriValidator().setEdm(edm).runEx("ESTwoKeyNav", "$expand=" 
+ expand);
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1600684d/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/UriParserTest.java
----------------------------------------------------------------------
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/UriParserTest.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/UriParserTest.java
index 87a702c..693f5b6 100644
--- 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/UriParserTest.java
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/UriParserTest.java
@@ -439,12 +439,12 @@ public class UriParserTest {
     testUri.run("ESKeyNav", "$top=1")
         .isKind(UriInfoKind.resource)
         .goPath().isEntitySet("ESKeyNav")
-        .goUpUriValidator().isTopText("1");
+        .goUpUriValidator().isTop(1);
 
     testUri.run("ESKeyNav", "$top=0")
         .isKind(UriInfoKind.resource)
         .goPath().isEntitySet("ESKeyNav")
-        .goUpUriValidator().isTopText("0");
+        .goUpUriValidator().isTop(0);
 
     testUri.runEx("ESKeyNav", "$top=undefined")
         
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
@@ -490,10 +490,10 @@ public class UriParserTest {
   public void count() throws Exception {
     testUri.run("ESAllPrim", "$count=true")
         .isKind(UriInfoKind.resource)
-        .isInlineCountText("true");
+        .isInlineCount(true);
     testUri.run("ESAllPrim", "$count=false")
         .isKind(UriInfoKind.resource)
-        .isInlineCountText("false");
+        .isInlineCount(false);
     testUri.runEx("ESAllPrim", "$count=undefined")
         
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
     testUri.runEx("ESAllPrim", "$count=")
@@ -504,10 +504,10 @@ public class UriParserTest {
   public void skip() throws Exception {
     testUri.run("ESAllPrim", "$skip=3")
         .isKind(UriInfoKind.resource)
-        .isSkipText("3");
+        .isSkip(3);
     testUri.run("ESAllPrim", "$skip=0")
         .isKind(UriInfoKind.resource)
-        .isSkipText("0");
+        .isSkip(0);
 
     testUri.runEx("ESAllPrim", "$skip=F")
         
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
@@ -795,11 +795,11 @@ public class UriParserTest {
   public void allowedSystemQueryOptionsOnAll() throws Exception {
     testUri.run("$all", 
"$count=true&$format=json&$search=abc&$skip=5&$top=5&$skiptoken=abc")
         .isKind(UriInfoKind.all)
-        .isInlineCountText("true")
+        .isInlineCount(true)
         .isFormatText("json")
         .isSearchSerialized("'abc'")
-        .isSkipText("5")
-        .isTopText("5")
+        .isSkip(5)
+        .isTop(5)
         .isSkipTokenText("abc");
   }
 
@@ -809,7 +809,7 @@ public class UriParserTest {
         + "&$filter=ESAllPrim/PropertyInt16 eq 
2&$format=json&$orderby=ESAllPrim/PropertyInt16"
         + "&$search=abc&$skip=5&$top=5&$skiptoken=abc")
         .isKind(UriInfoKind.crossjoin)
-        .isInlineCountText("true")
+        .isInlineCount(true)
         .goExpand().goPath().isEntitySet("ESAllPrim")
         .goUpExpandValidator().goUpToUriValidator()
         .goFilter().left().goPath().first().isEntitySet("ESAllPrim")
@@ -817,8 +817,8 @@ public class UriParserTest {
         .goUpFilterValidator().goUpToUriValidator()
         .isFormatText("json")
         .isSearchSerialized("'abc'")
-        .isSkipText("5")
-        .isTopText("5")
+        .isSkip(5)
+        .isTop(5)
         .isSkipTokenText("abc");
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1600684d/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/ExpandValidator.java
----------------------------------------------------------------------
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/ExpandValidator.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/ExpandValidator.java
index 0c60ee2..9a08b97 100644
--- 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/ExpandValidator.java
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/ExpandValidator.java
@@ -27,7 +27,6 @@ import org.apache.olingo.commons.api.edm.FullQualifiedName;
 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.OrderByOption;
-import org.apache.olingo.server.api.uri.queryoption.QueryOption;
 import org.apache.olingo.server.api.uri.queryoption.SelectItem;
 import org.apache.olingo.server.api.uri.queryoption.SelectOption;
 
@@ -127,47 +126,43 @@ public class ExpandValidator implements TestValidator {
     return this;
   }
 
-  public ExpandValidator isLevelText(final String text) {
-    final QueryOption option = (QueryOption) expandItem.getLevelsOption();
-    assertEquals(text, option.getText());
+  public ExpandValidator isLevels(final int levels) {
+    assertEquals(levels, expandItem.getLevelsOption().getValue());
     return this;
   }
 
-  public ExpandValidator isSkipText(final String text) {
-    final QueryOption option = expandItem.getSkipOption();
-    assertEquals(text, option.getText());
+  public ExpandValidator isLevelsMax() {
+    assertTrue(expandItem.getLevelsOption().isMax());
     return this;
   }
 
-  public ExpandValidator isTopText(final String text) {
-    final QueryOption option = expandItem.getTopOption();
-    assertEquals(text, option.getText());
+  public ExpandValidator isSkip(final int skip) {
+    assertEquals(skip, expandItem.getSkipOption().getValue());
     return this;
   }
 
-  public ExpandValidator isInlineCountText(final String text) {
-    final QueryOption option = expandItem.getCountOption();
-    assertEquals(text, option.getText());
+  public ExpandValidator isTop(final int top) {
+    assertEquals(top, expandItem.getTopOption().getValue());
+    return this;
+  }
+
+  public ExpandValidator isInlineCount(final boolean value) {
+    assertEquals(value, expandItem.getCountOption().getValue());
     return this;
   }
 
   public ExpandValidator isSelectItemStar(final int index) {
-    SelectOption select = expandItem.getSelectOption();
-    SelectItem item = select.getSelectItems().get(index);
-    assertTrue(item.isStar());
+    
assertTrue(expandItem.getSelectOption().getSelectItems().get(index).isStar());
     return this;
   }
 
   public ExpandValidator isSelectItemAllOperations(final int index, final 
FullQualifiedName fqn) {
-    SelectOption select = expandItem.getSelectOption();
-    SelectItem item = select.getSelectItems().get(index);
-    assertEquals(fqn.toString(), 
item.getAllOperationsInSchemaNameSpace().toString());
+    assertEquals(fqn, 
expandItem.getSelectOption().getSelectItems().get(index).getAllOperationsInSchemaNameSpace());
     return this;
   }
 
   public ExpandValidator isSortOrder(final int index, final boolean 
descending) {
-    OrderByOption orderBy = expandItem.getOrderByOption();
-    assertEquals(descending, orderBy.getOrders().get(index).isDescending());
+    assertEquals(descending, 
expandItem.getOrderByOption().getOrders().get(index).isDescending());
     return this;
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1600684d/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterTreeToText.java
----------------------------------------------------------------------
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterTreeToText.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterTreeToText.java
index 610b666..2103dd1 100644
--- 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterTreeToText.java
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterTreeToText.java
@@ -71,13 +71,13 @@ public class FilterTreeToText implements 
ExpressionVisitor<String> {
       throws ExpressionVisitException {
 
     String text = "<" + methodCall + "(";
-    int i = 0;
-    while (i < parameters.size()) {
-      if (i > 0) {
+    boolean first = true;
+    for (final String parameter : parameters) {
+      if (!first) {
         text += ",";
       }
-      text += parameters.get(i);
-      i++;
+      text += parameter;
+      first = false;
     }
     return text + ")>";
   }
@@ -104,7 +104,7 @@ public class FilterTreeToText implements 
ExpressionVisitor<String> {
         tmp = typed.toString(true);
       }
 
-      if (ret.length() != 0) {
+      if (ret.length() > 0) {
         ret += "/";
       }
       ret += tmp;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1600684d/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/TestUriValidator.java
----------------------------------------------------------------------
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/TestUriValidator.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/TestUriValidator.java
index d869cb1..3f1b913 100644
--- 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/TestUriValidator.java
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/TestUriValidator.java
@@ -26,7 +26,6 @@ import static org.junit.Assert.fail;
 import java.util.List;
 
 import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.http.HttpMethod;
 import org.apache.olingo.server.api.OData;
@@ -121,7 +120,7 @@ public class TestUriValidator implements TestValidator {
   public ResourceValidator goSelectItemPath(final int index) {
     final SelectOption select = uriInfo.getSelectOption();
     assertNotNull("no select found", select);
-    SelectItem item = select.getSelectItems().get(index);
+    final SelectItem item = select.getSelectItems().get(index);
     return new ResourceValidator()
         .setUpValidator(this)
         .setEdm(edm)
@@ -131,16 +130,15 @@ public class TestUriValidator implements TestValidator {
   public TestUriValidator isSelectStartType(final int index, final 
FullQualifiedName fullName) {
     final SelectOption select = uriInfo.getSelectOption();
     assertNotNull("no select found", select);
-    SelectItem item = select.getSelectItems().get(index);
-    EdmType actualType = item.getStartTypeFilter();
-    assertEquals(fullName, actualType.getFullQualifiedName());
+    final SelectItem item = select.getSelectItems().get(index);
+    assertEquals(fullName, item.getStartTypeFilter().getFullQualifiedName());
     return this;
   }
 
   public TestUriValidator isSelectItemStar(final int index) {
     final SelectOption select = uriInfo.getSelectOption();
     assertNotNull("no select found", select);
-    SelectItem item = select.getSelectItems().get(index);
+    final SelectItem item = select.getSelectItems().get(index);
     assertTrue(item.isStar());
     return this;
   }
@@ -148,7 +146,7 @@ public class TestUriValidator implements TestValidator {
   public TestUriValidator isSelectItemAllOp(final int index, final 
FullQualifiedName fqn) {
     final SelectOption select = uriInfo.getSelectOption();
     assertNotNull("no select found", select);
-    SelectItem item = select.getSelectItems().get(index);
+    final SelectItem item = select.getSelectItems().get(index);
     assertEquals(fqn, item.getAllOperationsInSchemaNameSpace());
     return this;
   }
@@ -162,27 +160,27 @@ public class TestUriValidator implements TestValidator {
   }
 
   public TestUriValidator isFormatText(final String text) {
-    assertEquals(text, uriInfo.getFormatOption().getText());
+    assertEquals(text, uriInfo.getFormatOption().getFormat());
     return this;
   }
 
-  public TestUriValidator isTopText(final String topText) {
-    assertEquals(topText, uriInfo.getTopOption().getText());
+  public TestUriValidator isSkip(final int skip) {
+    assertEquals(skip, uriInfo.getSkipOption().getValue());
     return this;
   }
 
-  public TestUriValidator isInlineCountText(final String inlineCountText) {
-    assertEquals(inlineCountText, uriInfo.getCountOption().getText());
+  public TestUriValidator isTop(final int top) {
+    assertEquals(top, uriInfo.getTopOption().getValue());
     return this;
   }
 
-  public TestUriValidator isSkipText(final String skipText) {
-    assertEquals(skipText, uriInfo.getSkipOption().getText());
+  public TestUriValidator isInlineCount(final boolean value) {
+    assertEquals(value, uriInfo.getCountOption().getValue());
     return this;
   }
 
   public TestUriValidator isSkipTokenText(final String skipTokenText) {
-    assertEquals(skipTokenText, uriInfo.getSkipTokenOption().getText());
+    assertEquals(skipTokenText, uriInfo.getSkipTokenOption().getValue());
     return this;
   }
 

Reply via email to