You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2016/01/25 21:30:54 UTC

[14/51] [abbrv] olingo-odata4 git commit: [OLINGO-834] ExpressionParser parses path expressions

[OLINGO-834] ExpressionParser parses path expressions

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


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

Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: a809165896e8315a04b566e11bd1637c26044c7d
Parents: 104ecf4
Author: Klaus Straubinger <kl...@sap.com>
Authored: Fri Dec 18 16:42:51 2015 +0100
Committer: Christian Amend <ch...@sap.com>
Committed: Mon Dec 21 10:10:35 2015 +0100

----------------------------------------------------------------------
 .../deserializer/helper/ExpandTreeBuilder.java  |  14 +-
 .../server/core/uri/UriResourceActionImpl.java  |  44 +-
 .../uri/UriResourceComplexPropertyImpl.java     |  18 +-
 .../server/core/uri/UriResourceCountImpl.java   |  10 +-
 .../core/uri/UriResourceEntitySetImpl.java      |  19 +-
 .../core/uri/UriResourceFunctionImpl.java       |  48 +-
 .../olingo/server/core/uri/UriResourceImpl.java |   6 +-
 .../server/core/uri/UriResourceItImpl.java      |  31 +-
 .../core/uri/UriResourceLambdaAllImpl.java      |  26 +-
 .../core/uri/UriResourceLambdaAnyImpl.java      |  25 +-
 .../core/uri/UriResourceLambdaVarImpl.java      |  32 +-
 .../uri/UriResourceNavigationPropertyImpl.java  |  21 +-
 .../uri/UriResourcePrimitivePropertyImpl.java   |  20 +-
 .../server/core/uri/UriResourceRefImpl.java     |  10 +-
 .../server/core/uri/UriResourceRootImpl.java    |  31 +-
 .../core/uri/UriResourceSingletonImpl.java      |  21 +-
 .../uri/UriResourceStartingTypeFilterImpl.java  |  33 +-
 .../server/core/uri/UriResourceTypedImpl.java   |  11 +-
 .../server/core/uri/UriResourceValueImpl.java   |   9 +-
 .../core/uri/parser/ExpressionParser.java       | 560 ++++++++++-
 .../server/core/uri/parser/FilterParser.java    |  49 +
 .../server/core/uri/parser/OrderByParser.java   |  61 ++
 .../olingo/server/core/uri/parser/Parser.java   | 123 +--
 .../server/core/uri/parser/ParserHelper.java    | 335 ++++++-
 .../core/uri/parser/ResourcePathParser.java     | 323 +-----
 .../server/core/uri/parser/SelectParser.java    |  10 +-
 .../server/core/uri/parser/UriContext.java      |   7 +-
 .../core/uri/parser/UriParseTreeVisitor.java    | 124 +--
 .../server/core/uri/parser/UriTokenizer.java    |  36 +-
 .../uri/queryoption/expression/MemberImpl.java  |   5 +
 .../olingo/server/core/uri/UriInfoImplTest.java |  10 +-
 .../core/uri/parser/ExpressionParserTest.java   |  21 +-
 .../core/uri/parser/UriTokenizerTest.java       |  31 +-
 .../server/core/uri/UriResourceImplTest.java    | 156 ++-
 .../core/uri/antlr/TestFullResourcePath.java    | 979 +++++++++----------
 .../core/uri/antlr/TestUriParserImpl.java       |  36 +-
 .../queryoption/expression/ExpressionTest.java  |  12 +-
 37 files changed, 1816 insertions(+), 1491 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilder.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilder.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilder.java
index 549cf33..7577e7b 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilder.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilder.java
@@ -27,14 +27,8 @@ public abstract class ExpandTreeBuilder {
   public abstract ExpandTreeBuilder expand(EdmNavigationProperty edmNavigationProperty);
 
   protected ExpandItemImpl buildExpandItem(final EdmNavigationProperty edmNavigationProperty) {
-    final ExpandItemImpl expandItem = new ExpandItemImpl();
-    final UriInfoImpl uriInfo = new UriInfoImpl();
-    final UriResourceNavigationPropertyImpl resourceNavigation = new UriResourceNavigationPropertyImpl();
-
-    resourceNavigation.setNavigationProperty(edmNavigationProperty);
-    uriInfo.addResourcePart(resourceNavigation);
-    expandItem.setResourcePath(uriInfo);
-
-    return expandItem;
+    return new ExpandItemImpl()
+        .setResourcePath(new UriInfoImpl()
+            .addResourcePart(new UriResourceNavigationPropertyImpl(edmNavigationProperty)));
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceActionImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceActionImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceActionImpl.java
index 4126110..1853942 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceActionImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceActionImpl.java
@@ -31,11 +31,19 @@ import org.apache.olingo.server.api.uri.UriResourceKind;
  */
 public class UriResourceActionImpl extends UriResourceImpl implements UriResourceAction {
 
-  protected EdmAction action;
-  protected EdmActionImport actionImport;
+  private final EdmActionImport actionImport;
+  private final EdmAction action;
 
-  public UriResourceActionImpl() {
+  public UriResourceActionImpl(final EdmActionImport actionImport) {
     super(UriResourceKind.action);
+    this.actionImport = actionImport;
+    this.action = actionImport.getUnboundAction();
+  }
+
+  public UriResourceActionImpl(final EdmAction action) {
+    super(UriResourceKind.action);
+    this.actionImport = null;
+    this.action = action;
   }
 
   @Override
@@ -43,38 +51,21 @@ public class UriResourceActionImpl extends UriResourceImpl implements UriResourc
     return action;
   }
 
-  public UriResourceActionImpl setAction(final EdmAction action) {
-    this.action = action;
-    return this;
-  }
-
   @Override
   public EdmActionImport getActionImport() {
     return actionImport;
   }
 
-  public UriResourceActionImpl setActionImport(final EdmActionImport actionImport) {
-    this.actionImport = actionImport;
-    setAction(actionImport.getUnboundAction());
-    return this;
-  }
-
   @Override
   public boolean isCollection() {
-    if (action.getReturnType() != null) {
-      return action.getReturnType().isCollection();
-    }
-    return false;
+    return action.getReturnType() != null && action.getReturnType().isCollection();
   }
 
   @Override
   public EdmType getType() {
-    if (action.getReturnType() != null) {
-      return action.getReturnType().getType();
-    }
-    return null;
+    return action.getReturnType() == null ? null : action.getReturnType().getType();
   }
-  
+
   @Override
   public String getSegmentValue(final boolean includeFilters) {
     return actionImport == null ? (action == null ? "" : action.getName()) : actionImport.getName();
@@ -84,14 +75,9 @@ public class UriResourceActionImpl extends UriResourceImpl implements UriResourc
   public String getSegmentValue() {
     return getSegmentValue(false);
   }
-  
+
   @Override
   public String toString(final boolean includeFilters) {
     return getSegmentValue(includeFilters);
   }
-
-  @Override
-  public String toString() {
-    return getSegmentValue();
-  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceComplexPropertyImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceComplexPropertyImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceComplexPropertyImpl.java
index 63db69c..9c83f24 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceComplexPropertyImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceComplexPropertyImpl.java
@@ -26,10 +26,11 @@ import org.apache.olingo.server.api.uri.UriResourceKind;
 
 public class UriResourceComplexPropertyImpl extends UriResourceTypedImpl implements UriResourceComplexProperty {
 
-  protected EdmProperty property;
+  private final EdmProperty property;
 
-  public UriResourceComplexPropertyImpl() {
+  public UriResourceComplexPropertyImpl(final EdmProperty property) {
     super(UriResourceKind.complexProperty);
+    this.property = property;
   }
 
   @Override
@@ -37,11 +38,6 @@ public class UriResourceComplexPropertyImpl extends UriResourceTypedImpl impleme
     return property;
   }
 
-  public UriResourceComplexPropertyImpl setProperty(final EdmProperty property) {
-    this.property = property;
-    return this;
-  }
-
   @Override
   public EdmComplexType getComplexType() {
     return (EdmComplexType) getType();
@@ -63,13 +59,7 @@ public class UriResourceComplexPropertyImpl extends UriResourceTypedImpl impleme
   }
 
   @Override
-  public String getSegmentValue(){
+  public String getSegmentValue() {
     return property.getName();
   }
-  
-  @Override
-  public String toString() {
-    return getSegmentValue();
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceCountImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceCountImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceCountImpl.java
index e1859a6..90dc4f5 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceCountImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceCountImpl.java
@@ -26,15 +26,9 @@ public class UriResourceCountImpl extends UriResourceImpl implements UriResource
   public UriResourceCountImpl() {
     super(UriResourceKind.count);
   }
-  
-  @Override
-  public String getSegmentValue(){
-    return "$count";
-  }
 
   @Override
-  public String toString() {
-    return getSegmentValue();
+  public String getSegmentValue() {
+    return "$count";
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceEntitySetImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceEntitySetImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceEntitySetImpl.java
index 4675964..ea21fe5 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceEntitySetImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceEntitySetImpl.java
@@ -25,10 +25,12 @@ import org.apache.olingo.server.api.uri.UriResourceEntitySet;
 import org.apache.olingo.server.api.uri.UriResourceKind;
 
 public class UriResourceEntitySetImpl extends UriResourceWithKeysImpl implements UriResourceEntitySet {
-  protected EdmEntitySet edmEntitySet = null;
 
-  public UriResourceEntitySetImpl() {
+  private final EdmEntitySet edmEntitySet;
+
+  public UriResourceEntitySetImpl(final EdmEntitySet edmEntitySet) {
     super(UriResourceKind.entitySet);
+    this.edmEntitySet = edmEntitySet;
   }
 
   @Override
@@ -36,11 +38,6 @@ public class UriResourceEntitySetImpl extends UriResourceWithKeysImpl implements
     return edmEntitySet;
   }
 
-  public UriResourceEntitySetImpl setEntitSet(final EdmEntitySet edmES) {
-    edmEntitySet = edmES;
-    return this;
-  }
-
   @Override
   public EdmEntityType getEntityType() {
     return edmEntitySet.getEntityType();
@@ -57,13 +54,7 @@ public class UriResourceEntitySetImpl extends UriResourceWithKeysImpl implements
   }
   
   @Override
-  public String getSegmentValue(){
+  public String getSegmentValue() {
     return edmEntitySet.getName();
   }
-  
-
-  @Override
-  public String toString() {
-    return getSegmentValue();
-  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceFunctionImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceFunctionImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceFunctionImpl.java
index a47a6ab..7784062 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceFunctionImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceFunctionImpl.java
@@ -33,13 +33,16 @@ import org.apache.olingo.server.api.uri.UriResourceKind;
  */
 public class UriResourceFunctionImpl extends UriResourceWithKeysImpl implements UriResourceFunction {
 
-  protected List<UriParameter> parameters;
-  protected EdmFunction function;
-  protected EdmFunctionImport functionImport;
-  private boolean isParameterListFilled = false;
+  private final EdmFunctionImport functionImport;
+  private final EdmFunction function;
+  private final List<UriParameter> parameters;
 
-  public UriResourceFunctionImpl() {
+  public UriResourceFunctionImpl(final EdmFunctionImport edmFunctionImport, final EdmFunction function,
+      final List<UriParameter> parameters) {
     super(UriResourceKind.function);
+    this.functionImport = edmFunctionImport;
+    this.function = function;
+    this.parameters = parameters;
   }
 
   @Override
@@ -49,34 +52,16 @@ public class UriResourceFunctionImpl extends UriResourceWithKeysImpl implements
         Collections.unmodifiableList(parameters);
   }
 
-  public UriResourceFunctionImpl setParameters(final List<UriParameter> parameters) {
-    isParameterListFilled = true;
-    this.parameters = parameters;
-    return this;
-  }
-
   @Override
   public EdmFunction getFunction() {
     return function;
   }
 
-  public UriResourceFunctionImpl setFunction(final EdmFunction function) {
-    this.function = function;
-    return this;
-  }
-
   @Override
   public EdmFunctionImport getFunctionImport() {
     return functionImport;
   }
 
-  public UriResourceFunctionImpl setFunctionImport(final EdmFunctionImport edmFunctionImport,
-      final List<UriParameter> parameters) {
-    functionImport = edmFunctionImport;
-    setParameters(parameters);
-    return this;
-  }
-
   @Override
   public EdmType getType() {
     return function.getReturnType().getType();
@@ -89,21 +74,6 @@ public class UriResourceFunctionImpl extends UriResourceWithKeysImpl implements
 
   @Override
   public String getSegmentValue() {
-    if (functionImport != null) {
-      return functionImport.getName();
-    } else if (function != null) {
-      return function.getName();
-    }
-    return "";
+    return functionImport == null ? (function == null ? "" : function.getName()) : functionImport.getName();
   }
-
-  @Override
-  public String toString() {
-    return getSegmentValue();
-  }
-
-  public boolean isParameterListFilled() {
-    return isParameterListFilled;
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceImpl.java
index 9fbcbd0..db991a8 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceImpl.java
@@ -22,7 +22,7 @@ import org.apache.olingo.server.api.uri.UriResource;
 import org.apache.olingo.server.api.uri.UriResourceKind;
 
 /**
- * Covers Functionimports and BoundFunction in URI
+ * Abstract class for resource-path elements in URI.
  */
 public abstract class UriResourceImpl implements UriResource {
   protected UriResourceKind kind;
@@ -36,4 +36,8 @@ public abstract class UriResourceImpl implements UriResource {
     return kind;
   }
 
+  @Override
+  public String toString() {
+    return getSegmentValue();
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceItImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceItImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceItImpl.java
index fc31910..e7db56c 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceItImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceItImpl.java
@@ -27,11 +27,13 @@ import org.apache.olingo.server.api.uri.UriResourceKind;
  */
 public class UriResourceItImpl extends UriResourceWithKeysImpl implements UriResourceIt {
 
-  private EdmType type;
-  private boolean isCollection;
+  private final EdmType type;
+  private final boolean isCollection;
 
-  public UriResourceItImpl() {
+  public UriResourceItImpl(final EdmType type, final boolean isCollection) {
     super(UriResourceKind.it);
+    this.type = type;
+    this.isCollection = isCollection;
   }
 
   @Override
@@ -39,32 +41,13 @@ public class UriResourceItImpl extends UriResourceWithKeysImpl implements UriRes
     return type;
   }
 
-  public UriResourceItImpl setType(final EdmType type) {
-    this.type = type;
-    return this;
-  }
-
   @Override
   public boolean isCollection() {
-    if (keyPredicates != null) {
-      return false;
-    }
-    return isCollection;
+    return keyPredicates == null && isCollection;
   }
 
-  public UriResourceItImpl setCollection(final boolean isCollection) {
-    this.isCollection = isCollection;
-    return this;
-  }
-  
   @Override
-  public String getSegmentValue(){
+  public String getSegmentValue() {
     return "$it";
   }
-
-  @Override
-  public String toString() {
-    return getSegmentValue();
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAllImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAllImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAllImpl.java
index d980777..4f5a4fa 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAllImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAllImpl.java
@@ -19,7 +19,6 @@
 package org.apache.olingo.server.core.uri;
 
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
-import org.apache.olingo.commons.api.edm.EdmProperty;
 import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
 import org.apache.olingo.server.api.uri.UriResourceKind;
@@ -28,12 +27,13 @@ import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
 
 public class UriResourceLambdaAllImpl extends UriResourceTypedImpl implements UriResourceLambdaAll {
 
-  protected EdmProperty property;
-  private String lambdaVariable;
-  private Expression expression;
+  private final String lambdaVariable;
+  private final Expression expression;
 
-  public UriResourceLambdaAllImpl() {
+  public UriResourceLambdaAllImpl(final String lambdaVariable, final Expression expression) {
     super(UriResourceKind.lambdaAll);
+    this.lambdaVariable = lambdaVariable;
+    this.expression = expression;
   }
 
   @Override
@@ -51,29 +51,13 @@ public class UriResourceLambdaAllImpl extends UriResourceTypedImpl implements Ur
     return lambdaVariable;
   }
 
-  public UriResourceLambdaAllImpl setLamdaVariable(final String lambdaVariable) {
-    this.lambdaVariable = lambdaVariable;
-    return this;
-  }
-
   @Override
   public Expression getExpression() {
     return expression;
   }
 
-  public UriResourceLambdaAllImpl setExpression(final Expression expression) {
-    this.expression = expression;
-    return this;
-  }
-
   @Override
   public String getSegmentValue() {
     return "all";
   }
-
-  @Override
-  public String toString() {
-    return getSegmentValue();
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java
index fe5dfee..b586a09 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaAnyImpl.java
@@ -19,7 +19,6 @@
 package org.apache.olingo.server.core.uri;
 
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
-import org.apache.olingo.commons.api.edm.EdmProperty;
 import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
 import org.apache.olingo.server.api.uri.UriResourceKind;
@@ -28,12 +27,13 @@ import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
 
 public class UriResourceLambdaAnyImpl extends UriResourceTypedImpl implements UriResourceLambdaAny {
 
-  protected EdmProperty property;
-  private String lambdaVariable;
-  private Expression expression;
+  private final String lambdaVariable;
+  private final Expression expression;
 
-  public UriResourceLambdaAnyImpl() {
+  public UriResourceLambdaAnyImpl(final String lambdaVariable, final Expression expression) {
     super(UriResourceKind.lambdaAny);
+    this.lambdaVariable = lambdaVariable;
+    this.expression = expression;
   }
 
   @Override
@@ -51,28 +51,13 @@ public class UriResourceLambdaAnyImpl extends UriResourceTypedImpl implements Ur
     return lambdaVariable;
   }
 
-  public UriResourceLambdaAnyImpl setLamdaVariable(final String lambdaVariable) {
-    this.lambdaVariable = lambdaVariable;
-    return this;
-  }
-
   @Override
   public Expression getExpression() {
     return expression;
   }
 
-  public UriResourceLambdaAnyImpl setExpression(final Expression expression) {
-    this.expression = expression;
-    return this;
-  }
-
   @Override
   public String getSegmentValue() {
     return "any";
   }
-
-  @Override
-  public String toString() {
-    return getSegmentValue();
-  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaVarImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaVarImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaVarImpl.java
index 2eb7607..306807a 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaVarImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceLambdaVarImpl.java
@@ -24,12 +24,13 @@ import org.apache.olingo.server.api.uri.UriResourceLambdaVariable;
 
 public class UriResourceLambdaVarImpl extends UriResourceTypedImpl implements UriResourceLambdaVariable {
 
-  private EdmType type;
-  private boolean isCollection;
-  private String variableText;
+  private final String variableText;
+  private final EdmType type;
 
-  public UriResourceLambdaVarImpl() {
+  public UriResourceLambdaVarImpl(final String variableText, final EdmType type) {
     super(UriResourceKind.lambdaVariable);
+    this.variableText = variableText;
+    this.type = type;
   }
 
   @Override
@@ -37,39 +38,18 @@ public class UriResourceLambdaVarImpl extends UriResourceTypedImpl implements Ur
     return variableText;
   }
 
-  public UriResourceLambdaVarImpl setVariableText(final String variableText) {
-    this.variableText = variableText;
-    return this;
-  }
-
   @Override
   public EdmType getType() {
     return type;
   }
 
-  public UriResourceLambdaVarImpl setType(final EdmType type) {
-    this.type = type;
-    return this;
-
-  }
-
   @Override
   public boolean isCollection() {
-    return isCollection;
-  }
-
-  public UriResourceLambdaVarImpl setCollection(final boolean isCollection) {
-    this.isCollection = isCollection;
-    return this;
+    return false;
   }
 
   @Override
   public String getSegmentValue() {
     return variableText;
   }
-
-  @Override
-  public String toString() {
-    return getSegmentValue();
-  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceNavigationPropertyImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceNavigationPropertyImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceNavigationPropertyImpl.java
index f4390b5..1d8b321 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceNavigationPropertyImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceNavigationPropertyImpl.java
@@ -25,10 +25,11 @@ import org.apache.olingo.server.api.uri.UriResourceNavigation;
 
 public class UriResourceNavigationPropertyImpl extends UriResourceWithKeysImpl implements UriResourceNavigation {
 
-  protected EdmNavigationProperty navigationProperty;
+  private final EdmNavigationProperty navigationProperty;
 
-  public UriResourceNavigationPropertyImpl() {
+  public UriResourceNavigationPropertyImpl(final EdmNavigationProperty property) {
     super(UriResourceKind.navigationProperty);
+    navigationProperty = property;
   }
 
   @Override
@@ -36,12 +37,6 @@ public class UriResourceNavigationPropertyImpl extends UriResourceWithKeysImpl i
     return navigationProperty;
   }
 
-  public UriResourceNavigationPropertyImpl setNavigationProperty(final EdmNavigationProperty property) {
-    navigationProperty = property;
-    return this;
-
-  }
-
   @Override
   public EdmType getType() {
     return navigationProperty.getType();
@@ -51,15 +46,9 @@ public class UriResourceNavigationPropertyImpl extends UriResourceWithKeysImpl i
   public boolean isCollection() {
     return navigationProperty.isCollection() && keyPredicates == null;
   }
-  
-  @Override
-  public String getSegmentValue(){
-    return navigationProperty.getName();
-  }
 
   @Override
-  public String toString() {
-    return getSegmentValue();
+  public String getSegmentValue() {
+    return navigationProperty.getName();
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourcePrimitivePropertyImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourcePrimitivePropertyImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourcePrimitivePropertyImpl.java
index d470ef4..bb04142 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourcePrimitivePropertyImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourcePrimitivePropertyImpl.java
@@ -25,10 +25,11 @@ import org.apache.olingo.server.api.uri.UriResourcePrimitiveProperty;
 
 public class UriResourcePrimitivePropertyImpl extends UriResourceTypedImpl implements UriResourcePrimitiveProperty {
 
-  EdmProperty property;
+  private final EdmProperty property;
 
-  public UriResourcePrimitivePropertyImpl() {
+  public UriResourcePrimitivePropertyImpl(final EdmProperty property) {
     super(UriResourceKind.primitiveProperty);
+    this.property = property;
   }
 
   @Override
@@ -36,11 +37,6 @@ public class UriResourcePrimitivePropertyImpl extends UriResourceTypedImpl imple
     return property;
   }
 
-  public UriResourcePrimitivePropertyImpl setProperty(final EdmProperty property) {
-    this.property = property;
-    return this;
-  }
-
   @Override
   public EdmType getType() {
     return property.getType();
@@ -50,15 +46,9 @@ public class UriResourcePrimitivePropertyImpl extends UriResourceTypedImpl imple
   public boolean isCollection() {
     return property.isCollection();
   }
-  
-  @Override
-  public String getSegmentValue(){
-    return  property.getName();
-  }
 
   @Override
-  public String toString() {
-    return getSegmentValue();
+  public String getSegmentValue() {
+    return property.getName();
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRefImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRefImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRefImpl.java
index 0c45f9a..6f01936 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRefImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRefImpl.java
@@ -25,16 +25,10 @@ public class UriResourceRefImpl extends UriResourceImpl implements UriResourceRe
 
   public UriResourceRefImpl() {
     super(UriResourceKind.ref);
-
-  }
-  @Override
-  public String getSegmentValue(){
-    return "$ref";
   }
 
   @Override
-  public String toString() {
-    return getSegmentValue();
+  public String getSegmentValue() {
+    return "$ref";
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRootImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRootImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRootImpl.java
index 5d8737f..761899f 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRootImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceRootImpl.java
@@ -24,11 +24,13 @@ import org.apache.olingo.server.api.uri.UriResourceRoot;
 
 public class UriResourceRootImpl extends UriResourceWithKeysImpl implements UriResourceRoot {
 
-  private EdmType type;
-  private boolean isCollection;
+  private final EdmType type;
+  private final boolean isCollection;
 
-  public UriResourceRootImpl() {
+  public UriResourceRootImpl(final EdmType type, final boolean isCollection) {
     super(UriResourceKind.root);
+    this.type = type;
+    this.isCollection = isCollection;
   }
 
   @Override
@@ -36,32 +38,13 @@ public class UriResourceRootImpl extends UriResourceWithKeysImpl implements UriR
     return type;
   }
 
-  public UriResourceRootImpl setType(final EdmType type) {
-    this.type = type;
-    return this;
-  }
-
   @Override
   public boolean isCollection() {
-    if (keyPredicates != null) {
-      return false;
-    }
-    return isCollection;
+    return keyPredicates == null && isCollection;
   }
 
-  public UriResourceRootImpl setCollection(final boolean isCollection) {
-    this.isCollection = isCollection;
-    return this;
-  }
-  
   @Override
-  public String getSegmentValue(){
+  public String getSegmentValue() {
     return "$root";
   }
-
-  @Override
-  public String toString() {
-    return getSegmentValue();
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceSingletonImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceSingletonImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceSingletonImpl.java
index 72289f6..381a518 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceSingletonImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceSingletonImpl.java
@@ -26,10 +26,11 @@ import org.apache.olingo.server.api.uri.UriResourceSingleton;
 
 public class UriResourceSingletonImpl extends UriResourceTypedImpl implements UriResourceSingleton {
 
-  private EdmSingleton singleton;
+  private final EdmSingleton singleton;
 
-  public UriResourceSingletonImpl() {
+  public UriResourceSingletonImpl(final EdmSingleton singleton) {
     super(UriResourceKind.singleton);
+    this.singleton = singleton;
   }
 
   @Override
@@ -37,12 +38,6 @@ public class UriResourceSingletonImpl extends UriResourceTypedImpl implements Ur
     return singleton;
   }
 
-  public UriResourceSingletonImpl setSingleton(final EdmSingleton singleton) {
-
-    this.singleton = singleton;
-    return this;
-  }
-
   @Override
   public EdmEntityType getEntityTypeFilter() {
     return (EdmEntityType) typeFilter;
@@ -62,15 +57,9 @@ public class UriResourceSingletonImpl extends UriResourceTypedImpl implements Ur
   public boolean isCollection() {
     return false;
   }
-  
-  @Override
-  public String getSegmentValue(){
-    return singleton.getName();
-  }
 
   @Override
-  public String toString() {
-    return getSegmentValue();
+  public String getSegmentValue() {
+    return singleton.getName();
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceStartingTypeFilterImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceStartingTypeFilterImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceStartingTypeFilterImpl.java
index 24d3713..09af068 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceStartingTypeFilterImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceStartingTypeFilterImpl.java
@@ -23,11 +23,13 @@ import org.apache.olingo.server.api.uri.UriResourceKind;
 
 public class UriResourceStartingTypeFilterImpl extends UriResourceWithKeysImpl {
 
-  private EdmType type;
-  private boolean isCollection;
+  private final EdmType type;
+  private final boolean isCollection;
 
-  public UriResourceStartingTypeFilterImpl() {
+  public UriResourceStartingTypeFilterImpl(final EdmType type, final boolean isCollection) {
     super(null);
+    this.type = type;
+    this.isCollection = isCollection;
   }
 
   @Override
@@ -40,32 +42,13 @@ public class UriResourceStartingTypeFilterImpl extends UriResourceWithKeysImpl {
     return type;
   }
 
-  public UriResourceStartingTypeFilterImpl setType(final EdmType type) {
-    this.type = type;
-    return this;
-  }
-
   @Override
   public boolean isCollection() {
-    if (keyPredicates != null) {
-      return false;
-    }
-    return isCollection;
-  }
-
-  public UriResourceStartingTypeFilterImpl setCollection(final boolean isCollection) {
-    this.isCollection = isCollection;
-    return this;
+    return keyPredicates == null && isCollection;
   }
 
   @Override
-  public String getSegmentValue(){
-    return type.getNamespace() + "." + type.getName();
+  public String getSegmentValue() {
+    return type.getFullQualifiedName().getFullQualifiedNameAsString();
   }
-  
-  @Override
-  public String toString() {
-    return getSegmentValue();
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceTypedImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceTypedImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceTypedImpl.java
index d6710ad..9930a7e 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceTypedImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceTypedImpl.java
@@ -41,14 +41,9 @@ public abstract class UriResourceTypedImpl extends UriResourceImpl implements Ur
   }
 
   public String getSegmentValue(final boolean includeFilters) {
-    if (includeFilters) {
-      if (typeFilter != null) {
-        return getSegmentValue() + "/" + typeFilter.getFullQualifiedName().toString();
-      } else {
-        return getSegmentValue();
-      }
-    }
-    return getSegmentValue();
+    return includeFilters && typeFilter != null ?
+        getSegmentValue() + "/" + typeFilter.getFullQualifiedName().getFullQualifiedNameAsString() :
+        getSegmentValue();
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceValueImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceValueImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceValueImpl.java
index 73f86c4..d2b70d5 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceValueImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceValueImpl.java
@@ -25,17 +25,10 @@ public class UriResourceValueImpl extends UriResourceImpl implements UriResource
 
   public UriResourceValueImpl() {
     super(UriResourceKind.value);
-
   }
 
   @Override
-  public String getSegmentValue(){
+  public String getSegmentValue() {
     return "$value";
   }
-
-  @Override
-  public String toString() {
-    return getSegmentValue();
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java
index 61c023d..2f7fdb2 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpressionParser.java
@@ -18,20 +18,41 @@
  */
 package org.apache.olingo.server.core.uri.parser;
 
+import java.util.ArrayDeque;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.Deque;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.EdmComplexType;
+import org.apache.olingo.commons.api.edm.EdmElement;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmEnumType;
+import org.apache.olingo.commons.api.edm.EdmFunction;
+import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmReturnType;
+import org.apache.olingo.commons.api.edm.EdmSingleton;
+import org.apache.olingo.commons.api.edm.EdmStructuredType;
 import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.edm.EdmTypeDefinition;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
 import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.uri.UriParameter;
+import org.apache.olingo.server.api.uri.UriResourceFunction;
+import org.apache.olingo.server.api.uri.UriResourceLambdaVariable;
+import org.apache.olingo.server.api.uri.UriResourceNavigation;
+import org.apache.olingo.server.api.uri.UriResourcePartTyped;
 import org.apache.olingo.server.api.uri.queryoption.expression.Alias;
 import org.apache.olingo.server.api.uri.queryoption.expression.Binary;
 import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
@@ -45,12 +66,32 @@ import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind;
 import org.apache.olingo.server.api.uri.queryoption.expression.TypeLiteral;
 import org.apache.olingo.server.api.uri.queryoption.expression.Unary;
 import org.apache.olingo.server.api.uri.queryoption.expression.UnaryOperatorKind;
+import org.apache.olingo.server.core.uri.UriInfoImpl;
+import org.apache.olingo.server.core.uri.UriResourceComplexPropertyImpl;
+import org.apache.olingo.server.core.uri.UriResourceCountImpl;
+import org.apache.olingo.server.core.uri.UriResourceEntitySetImpl;
+import org.apache.olingo.server.core.uri.UriResourceFunctionImpl;
+import org.apache.olingo.server.core.uri.UriResourceItImpl;
+import org.apache.olingo.server.core.uri.UriResourceLambdaAllImpl;
+import org.apache.olingo.server.core.uri.UriResourceLambdaAnyImpl;
+import org.apache.olingo.server.core.uri.UriResourceLambdaVarImpl;
+import org.apache.olingo.server.core.uri.UriResourceNavigationPropertyImpl;
+import org.apache.olingo.server.core.uri.UriResourcePrimitivePropertyImpl;
+import org.apache.olingo.server.core.uri.UriResourceRootImpl;
+import org.apache.olingo.server.core.uri.UriResourceSingletonImpl;
+import org.apache.olingo.server.core.uri.UriResourceStartingTypeFilterImpl;
+import org.apache.olingo.server.core.uri.UriResourceTypedImpl;
+import org.apache.olingo.server.core.uri.UriResourceWithKeysImpl;
 import org.apache.olingo.server.core.uri.parser.UriTokenizer.TokenKind;
 import org.apache.olingo.server.core.uri.queryoption.expression.AliasImpl;
 import org.apache.olingo.server.core.uri.queryoption.expression.BinaryImpl;
+import org.apache.olingo.server.core.uri.queryoption.expression.EnumerationImpl;
 import org.apache.olingo.server.core.uri.queryoption.expression.LiteralImpl;
+import org.apache.olingo.server.core.uri.queryoption.expression.MemberImpl;
 import org.apache.olingo.server.core.uri.queryoption.expression.MethodImpl;
+import org.apache.olingo.server.core.uri.queryoption.expression.TypeLiteralImpl;
 import org.apache.olingo.server.core.uri.queryoption.expression.UnaryImpl;
+import org.apache.olingo.server.core.uri.validator.UriValidationException;
 
 public class ExpressionParser {
   private static final Map<TokenKind, BinaryOperatorKind> tokenToBinaryOperator;
@@ -129,7 +170,7 @@ public class ExpressionParser {
     Map<TokenKind, EdmPrimitiveTypeKind> temp = new HashMap<TokenKind, EdmPrimitiveTypeKind>();
     temp.put(TokenKind.BooleanValue, EdmPrimitiveTypeKind.Boolean);
     temp.put(TokenKind.StringValue, EdmPrimitiveTypeKind.String);
-    // TODO:Check if int64 is correct here or if it has to be single instead
+    // TODO: Check if int64 is correct here or if it has to be decimal or single or double instead.
     temp.put(TokenKind.IntegerValue, EdmPrimitiveTypeKind.Int64);
     temp.put(TokenKind.GuidValue, EdmPrimitiveTypeKind.Guid);
     temp.put(TokenKind.DateValue, EdmPrimitiveTypeKind.Date);
@@ -147,20 +188,27 @@ public class ExpressionParser {
   private final OData odata;
 
   private UriTokenizer tokenizer;
+  private Deque<UriResourceLambdaVariable> lambdaVariables = new ArrayDeque<UriResourceLambdaVariable>();
+  private EdmType referringType;
+  private Collection<String> crossjoinEntitySetNames;
 
   public ExpressionParser(final Edm edm, final OData odata) {
     this.edm = edm;
     this.odata = odata;
   }
 
-  public Expression parse(UriTokenizer tokenizer) throws UriParserException {
+  public Expression parse(UriTokenizer tokenizer, final EdmType referringType,
+      final Collection<String> crossjoinEntitySetNames)
+      throws UriParserException, UriValidationException {
     // Initialize tokenizer.
     this.tokenizer = tokenizer;
+    this.referringType = referringType;
+    this.crossjoinEntitySetNames = crossjoinEntitySetNames;
 
     return parseExpression();
   }
 
-  private Expression parseExpression() throws UriParserException {
+  private Expression parseExpression() throws UriParserException, UriValidationException {
     Expression left = parseAnd();
     while (tokenizer.next(TokenKind.OrOperator)) {
       final Expression right = parseAnd();
@@ -172,7 +220,7 @@ public class ExpressionParser {
     return left;
   }
 
-  private Expression parseAnd() throws UriParserException {
+  private Expression parseAnd() throws UriParserException, UriValidationException {
     Expression left = parseExprEquality();
     while (tokenizer.next(TokenKind.AndOperator)) {
       final Expression right = parseExprEquality();
@@ -184,7 +232,7 @@ public class ExpressionParser {
     return left;
   }
 
-  private Expression parseExprEquality() throws UriParserException {
+  private Expression parseExprEquality() throws UriParserException, UriValidationException {
     Expression left = parseExprRel();
     TokenKind operatorTokenKind = ParserHelper.next(tokenizer, TokenKind.EqualsOperator, TokenKind.NotEqualsOperator);
     // Null for everything other than EQ or NE
@@ -199,7 +247,7 @@ public class ExpressionParser {
   }
 
   // TODO: The 'isof' method has relational precedence and should appear here.
-  private Expression parseExprRel() throws UriParserException {
+  private Expression parseExprRel() throws UriParserException, UriValidationException {
     Expression left = parseExprAdd();
     TokenKind operatorTokenKind = ParserHelper.next(tokenizer,
         TokenKind.GreaterThanOperator, TokenKind.GreaterThanOrEqualsOperator,
@@ -217,7 +265,7 @@ public class ExpressionParser {
     return left;
   }
 
-  private Expression parseExprAdd() throws UriParserException {
+  private Expression parseExprAdd() throws UriParserException, UriValidationException {
     Expression left = parseExprMul();
     TokenKind operatorTokenKind = ParserHelper.next(tokenizer, TokenKind.AddOperator, TokenKind.SubOperator);
     // Null for everything other than ADD or SUB
@@ -231,7 +279,7 @@ public class ExpressionParser {
     return left;
   }
 
-  private Expression parseExprMul() throws UriParserException {
+  private Expression parseExprMul() throws UriParserException, UriValidationException {
     Expression left = parseExprUnary();
     TokenKind operatorTokenKind = ParserHelper.next(tokenizer,
         TokenKind.MulOperator, TokenKind.DivOperator, TokenKind.ModOperator);
@@ -255,7 +303,22 @@ public class ExpressionParser {
   }
 
   // TODO: The 'cast' method has unary precedence and should appear here.
-  private Expression parseExprUnary() throws UriParserException {
+  private Expression parseExprUnary() throws UriParserException, UriValidationException {
+    // Negative numbers start with a minus indistinguishable from an unary minus operator.
+    // So we read numbers (and primitive values starting with numbers) right here.
+    // TODO: Find a better idea how to solve this problem.
+    final TokenKind numberTokenKind = ParserHelper.next(tokenizer,
+        TokenKind.DoubleValue, TokenKind.DecimalValue, TokenKind.GuidValue,
+        TokenKind.DateTimeOffsetValue, TokenKind.DateValue, TokenKind.TimeOfDayValue,
+        TokenKind.IntegerValue);
+    if (numberTokenKind != null) {
+      final EdmPrimitiveTypeKind primitiveTypeKind = tokenToPrimitiveType.get(numberTokenKind);
+      final EdmPrimitiveType type = primitiveTypeKind == null ?
+          // Null handling
+          null :
+          odata.createPrimitiveTypeInstance(primitiveTypeKind);
+      return new LiteralImpl(tokenizer.getText(), type);
+    }
     Expression left = null;
     TokenKind operatorTokenKind = ParserHelper.next(tokenizer, TokenKind.MINUS, TokenKind.NotOperator);
     // Null for everything other than - or NOT
@@ -279,13 +342,11 @@ public class ExpressionParser {
     return left;
   }
 
-  private Expression parseExprPrimary() throws UriParserException {
+  private Expression parseExprPrimary() throws UriParserException, UriValidationException {
     final Expression left = parseExprValue();
     if (isEnumType(left) && tokenizer.next(TokenKind.HasOperator)) {
       ParserHelper.requireNext(tokenizer, TokenKind.EnumValue);
-      final String primitiveValueLiteral = tokenizer.getText();
-      final Expression right = new LiteralImpl(primitiveValueLiteral, getEnumType(primitiveValueLiteral));
-      checkEnumLiteral(right);
+      final Expression right = createEnumExpression(tokenizer.getText());
       return new BinaryImpl(left, BinaryOperatorKind.HAS, right,
           odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Boolean));
     } else {
@@ -293,7 +354,7 @@ public class ExpressionParser {
     }
   }
 
-  private Expression parseExprValue() throws UriParserException {
+  private Expression parseExprValue() throws UriParserException, UriValidationException {
     if (tokenizer.next(TokenKind.OPEN)) {
       final Expression expression = parseExpression();
       ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
@@ -310,51 +371,49 @@ public class ExpressionParser {
     }
 
     if (tokenizer.next(TokenKind.ROOT)) {
-      // TODO: Consume $root expression.
+      return parseFirstMemberExpr(TokenKind.ROOT);
     }
 
     if (tokenizer.next(TokenKind.IT)) {
-      // TODO: Consume $it expression.
+      return parseFirstMemberExpr(TokenKind.IT);
     }
 
-    TokenKind nextPrimitive = ParserHelper.nextPrimitive(tokenizer);
+    final TokenKind nextPrimitive = ParserHelper.nextPrimitiveValue(tokenizer);
     if (nextPrimitive != null) {
       final String primitiveValueLiteral = tokenizer.getText();
-      final EdmPrimitiveTypeKind primitiveTypeKind = tokenToPrimitiveType.get(nextPrimitive);
-      EdmPrimitiveType type;
-      if (primitiveTypeKind == null) {
-        if (nextPrimitive == TokenKind.EnumValue) {
-          type = getEnumType(primitiveValueLiteral);
-        } else {
-          // Null handling
-          type = null;
-        }
+      if (nextPrimitive == TokenKind.EnumValue) {
+        return createEnumExpression(primitiveValueLiteral);
       } else {
-        type = odata.createPrimitiveTypeInstance(primitiveTypeKind);
+        final EdmPrimitiveTypeKind primitiveTypeKind = tokenToPrimitiveType.get(nextPrimitive);
+        final EdmPrimitiveType type = primitiveTypeKind == null ?
+            // Null handling
+            null :
+            odata.createPrimitiveTypeInstance(primitiveTypeKind);
+        return new LiteralImpl(primitiveValueLiteral, type);
       }
-      return new LiteralImpl(primitiveValueLiteral, type);
     }
 
     // The method token text includes the opening parenthesis so that method calls can be recognized unambiguously.
     // OData identifiers have to be considered after that.
-    TokenKind nextMethod = nextMethod();
+    final TokenKind nextMethod = nextMethod();
     if (nextMethod != null) {
       MethodKind methodKind = tokenToMethod.get(nextMethod);
       return new MethodImpl(methodKind, parseMethodParameters(methodKind));
     }
 
     if (tokenizer.next(TokenKind.QualifiedName)) {
-      // TODO: Consume typecast or bound-function expression.
+      return parseFirstMemberExpr(TokenKind.QualifiedName);
     }
 
     if (tokenizer.next(TokenKind.ODataIdentifier)) {
-      // TODO: Consume property-path or lambda-variable expression.
+      return parseFirstMemberExpr(TokenKind.ODataIdentifier);
     }
 
-    throw new UriParserSyntaxException("Unexpected token", UriParserSyntaxException.MessageKeys.SYNTAX);
+    throw new UriParserSyntaxException("Unexpected token.", UriParserSyntaxException.MessageKeys.SYNTAX);
   }
 
-  private List<Expression> parseMethodParameters(final MethodKind methodKind) throws UriParserException {
+  private List<Expression> parseMethodParameters(final MethodKind methodKind)
+      throws UriParserException, UriValidationException {
     List<Expression> parameters = new ArrayList<Expression>();
     switch (methodKind) {
     // Must have no parameter.
@@ -477,6 +536,411 @@ public class ExpressionParser {
     return parameters;
   }
 
+  private Expression parseFirstMemberExpr(final TokenKind lastTokenKind)
+      throws UriParserException, UriValidationException {
+
+    final UriInfoImpl uriInfo = new UriInfoImpl();
+    EdmType startTypeFilter = null;
+
+    if (lastTokenKind == TokenKind.ROOT) {
+      parseDollarRoot(uriInfo);
+    } else if (lastTokenKind == TokenKind.IT) {
+      parseDollarIt(uriInfo);
+    } else if (lastTokenKind == TokenKind.ODataIdentifier) {
+      parseFirstMemberODataIdentifier(uriInfo);
+    } else if (lastTokenKind == TokenKind.QualifiedName) {
+      // Special handling for leading type casts and type literals
+      final FullQualifiedName fullQualifiedName = new FullQualifiedName(tokenizer.getText());
+      EdmStructuredType structuredType = edm.getEntityType(fullQualifiedName);
+      if (structuredType == null) {
+        structuredType = edm.getComplexType(fullQualifiedName);
+      }
+
+      if (structuredType != null) {
+        if (tokenizer.next(TokenKind.SLASH)) {
+          // Leading type cast
+          checkStructuredTypeFilter(referringType, structuredType);
+          startTypeFilter = structuredType;
+
+          final TokenKind tokenKind = ParserHelper.next(tokenizer, TokenKind.QualifiedName, TokenKind.ODataIdentifier);
+          parseMemberExpression(tokenKind, uriInfo, new UriResourceStartingTypeFilterImpl(structuredType, false),
+              false);
+        } else {
+          // Type literal
+          checkStructuredTypeFilter(referringType, structuredType);
+          return new TypeLiteralImpl(structuredType);
+        }
+      } else {
+        // Must be bound or unbound function. // TODO: Is unbound function allowed?
+        parseFunction(fullQualifiedName, uriInfo, referringType, true);
+      }
+    }
+
+    return new MemberImpl(uriInfo, startTypeFilter);
+  }
+
+  private void parseDollarRoot(UriInfoImpl uriInfo) throws UriParserException, UriValidationException {
+    UriResourceRootImpl rootResource = new UriResourceRootImpl(referringType, true);
+    uriInfo.addResourcePart(rootResource);
+    ParserHelper.requireNext(tokenizer, TokenKind.SLASH);
+    ParserHelper.requireNext(tokenizer, TokenKind.ODataIdentifier);
+    final String name = tokenizer.getText();
+    UriResourcePartTyped resource = null;
+    final EdmEntitySet entitySet = edm.getEntityContainer().getEntitySet(name);
+    if (entitySet == null) {
+      final EdmSingleton singleton = edm.getEntityContainer().getSingleton(name);
+      if (singleton == null) {
+        throw new UriParserSemanticException("EntitySet or singleton expected.",
+            UriParserSemanticException.MessageKeys.UNKNOWN_PART, name);
+      } else {
+        resource = new UriResourceSingletonImpl(singleton);
+      }
+    } else {
+      ParserHelper.requireNext(tokenizer, TokenKind.OPEN);
+      final List<UriParameter> keyPredicates =
+          ParserHelper.parseKeyPredicate(tokenizer, entitySet.getEntityType(), null);
+      resource = new UriResourceEntitySetImpl(entitySet).setKeyPredicates(keyPredicates);
+    }
+    uriInfo.addResourcePart(resource);
+    parseSingleNavigationExpr(uriInfo, resource);
+  }
+
+  private void parseDollarIt(UriInfoImpl uriInfo) throws UriParserException, UriValidationException {
+    UriResourceItImpl itResource = new UriResourceItImpl(referringType,
+        referringType instanceof EdmEntityType); // TODO: Determine isCollection.
+    uriInfo.addResourcePart(itResource);
+    if (tokenizer.next(TokenKind.SLASH)) {
+      final TokenKind tokenKind = ParserHelper.next(tokenizer, TokenKind.QualifiedName, TokenKind.ODataIdentifier);
+      parseMemberExpression(tokenKind, uriInfo, itResource, true);
+    }
+  }
+
+  private void parseFirstMemberODataIdentifier(UriInfoImpl uriInfo) throws UriParserException, UriValidationException {
+    final String name = tokenizer.getText();
+
+    // For a crossjoin, the identifier must be an entity-set name.
+    if (crossjoinEntitySetNames != null && !crossjoinEntitySetNames.isEmpty()) {
+      if (crossjoinEntitySetNames.contains(name)) {
+        final UriResourceEntitySetImpl resource =
+            new UriResourceEntitySetImpl(edm.getEntityContainer().getEntitySet(name));
+        uriInfo.addResourcePart(resource);
+        if (tokenizer.next(TokenKind.SLASH)) {
+          final TokenKind tokenKind = ParserHelper.next(tokenizer, TokenKind.QualifiedName, TokenKind.ODataIdentifier);
+          parseMemberExpression(tokenKind, uriInfo, resource, true);
+        }
+        return;
+      } else {
+        throw new UriParserSemanticException("Unknown crossjoin entity set.",
+            UriParserSemanticException.MessageKeys.UNKNOWN_PART, name);
+      }
+    }
+
+    // Check if the OData identifier is a lambda variable, otherwise it must be a property.
+    UriResourceLambdaVariable lambdaVariable = null;
+    for (final UriResourceLambdaVariable variable : lambdaVariables) {
+      if (variable.getVariableName().equals(name)) {
+        lambdaVariable = variable;
+        break;
+      }
+    }
+    if (lambdaVariable != null) {
+      // Copy lambda variable into new resource, just in case ...
+      final UriResourceLambdaVariable lambdaResource =
+          new UriResourceLambdaVarImpl(lambdaVariable.getVariableName(), lambdaVariable.getType());
+      uriInfo.addResourcePart(lambdaResource);
+      if (tokenizer.next(TokenKind.SLASH)) {
+        final TokenKind tokenKind = ParserHelper.next(tokenizer, TokenKind.QualifiedName, TokenKind.ODataIdentifier);
+        parseMemberExpression(tokenKind, uriInfo, lambdaResource, true);
+      }
+    } else {
+      // Must be a property.
+      parseMemberExpression(TokenKind.ODataIdentifier, uriInfo, null, true); // TODO: Find last resource.
+    }
+  }
+
+  private void parseMemberExpression(final TokenKind lastTokenKind, UriInfoImpl uriInfo,
+      final UriResourcePartTyped lastResource, final boolean allowTypeFilter)
+          throws UriParserException, UriValidationException {
+
+    if (lastTokenKind == TokenKind.QualifiedName) {
+      // Type cast or bound function
+      final FullQualifiedName fullQualifiedName = new FullQualifiedName(tokenizer.getText());
+      final EdmEntityType edmEntityType = edm.getEntityType(fullQualifiedName);
+
+      if (edmEntityType != null) {
+        if (allowTypeFilter) {
+          setTypeFilter(lastResource, edmEntityType);
+        } else {
+          throw new UriParserSemanticException("Type filters are not chainable.",
+              UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE,
+              lastResource.getType().getFullQualifiedName().getFullQualifiedNameAsString(),
+              fullQualifiedName.getFullQualifiedNameAsString());
+        }
+      } else {
+        parseBoundFunction(fullQualifiedName, uriInfo, lastResource);
+      }
+    } else if (lastTokenKind == TokenKind.ODataIdentifier) {
+      parsePropertyPathExpr(uriInfo, lastResource);
+    } else {
+      throw new UriParserSyntaxException("Unexpected token.", UriParserSyntaxException.MessageKeys.SYNTAX);
+    }
+  }
+
+  private void setTypeFilter(UriResourcePartTyped lastResource, final EdmEntityType entityTypeFilter)
+      throws UriParserException {
+    checkStructuredTypeFilter(lastResource.getType(), entityTypeFilter);
+    if (lastResource instanceof UriResourceTypedImpl) {
+      ((UriResourceTypedImpl) lastResource).setTypeFilter(entityTypeFilter);
+    } else if (lastResource instanceof UriResourceWithKeysImpl) {
+      ((UriResourceWithKeysImpl) lastResource).setEntryTypeFilter(entityTypeFilter);
+    }
+  }
+
+  private void parsePropertyPathExpr(UriInfoImpl uriInfo, final UriResourcePartTyped lastResource)
+      throws UriParserException, UriValidationException {
+
+    final String oDataIdentifier = tokenizer.getText();
+
+    final EdmType lastType = lastResource == null ? referringType : ParserHelper.getTypeInformation(lastResource);
+    if (!(lastType instanceof EdmStructuredType)) {
+      throw new UriParserSemanticException("Property paths must follow a structured type.",
+          UriParserSemanticException.MessageKeys.ONLY_FOR_STRUCTURAL_TYPES, oDataIdentifier);
+    }
+
+    final EdmStructuredType structuredType = (EdmStructuredType) lastType;
+    final EdmElement property = structuredType.getProperty(oDataIdentifier);
+
+    if (property == null) {
+      throw new UriParserSemanticException("Unknown property.",
+          UriParserSemanticException.MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE, oDataIdentifier);
+    }
+
+    if (property.getType() instanceof EdmComplexType) {
+      final UriResourceComplexPropertyImpl complexResource =
+          new UriResourceComplexPropertyImpl((EdmProperty) property);
+      uriInfo.addResourcePart(complexResource);
+
+      if (property.isCollection()) {
+        parseCollectionPathExpr(uriInfo, complexResource);
+      } else {
+        parseComplexPathExpr(uriInfo, complexResource);
+      }
+    } else if (property instanceof EdmNavigationProperty) {
+      // Nav. property; maybe a collection
+      final UriResourceNavigationPropertyImpl navigationResource =
+          new UriResourceNavigationPropertyImpl((EdmNavigationProperty) property);
+      navigationResource.setKeyPredicates(
+          ParserHelper.parseNavigationKeyPredicate(tokenizer, (EdmNavigationProperty) property));
+      uriInfo.addResourcePart(navigationResource);
+
+      if (navigationResource.isCollection()) {
+        parseCollectionNavigationExpr(uriInfo, navigationResource);
+      } else {
+        parseSingleNavigationExpr(uriInfo, navigationResource);
+      }
+    } else {
+      // Primitive type or Enum type
+      final UriResourcePrimitivePropertyImpl primitiveResource =
+          new UriResourcePrimitivePropertyImpl((EdmProperty) property);
+      uriInfo.addResourcePart(primitiveResource);
+
+      if (property.isCollection()) {
+        parseCollectionPathExpr(uriInfo, primitiveResource);
+      } else {
+        parseSinglePathExpr(uriInfo, primitiveResource);
+      }
+    }
+  }
+
+  private void parseSingleNavigationExpr(UriInfoImpl uriInfo, final UriResourcePartTyped lastResource)
+      throws UriParserException, UriValidationException {
+    // TODO: Is that correct?
+    if (tokenizer.next(TokenKind.SLASH)) {
+      final TokenKind tokenKind = ParserHelper.next(tokenizer, TokenKind.QualifiedName, TokenKind.ODataIdentifier);
+      parseMemberExpression(tokenKind, uriInfo, lastResource, true);
+    }
+  }
+
+  private void parseCollectionNavigationExpr(UriInfoImpl uriInfo, UriResourcePartTyped lastResource)
+      throws UriParserException, UriValidationException {
+    // TODO: Is type cast missing?
+    if (tokenizer.next(TokenKind.OPEN)) {
+      if (lastResource instanceof UriResourceNavigation) {
+        ((UriResourceNavigationPropertyImpl) lastResource).setKeyPredicates(
+              ParserHelper.parseNavigationKeyPredicate(tokenizer,
+                  ((UriResourceNavigationPropertyImpl) lastResource).getProperty()));
+      } else if (lastResource instanceof UriResourceFunction
+          && ((UriResourceFunction) lastResource).getType() instanceof EdmEntityType) {
+        ((UriResourceFunctionImpl) lastResource).setKeyPredicates(
+            ParserHelper.parseKeyPredicate(tokenizer,
+                (EdmEntityType) ((UriResourceFunction) lastResource).getType(),
+                null));
+      } else {
+        throw new UriParserSemanticException("Unknown or wrong resource type.",
+            UriParserSemanticException.MessageKeys.NOT_IMPLEMENTED, lastResource.toString());
+      }
+      parseSingleNavigationExpr(uriInfo, lastResource);
+    }
+    parseCollectionPathExpr(uriInfo, lastResource);
+  }
+
+  private void parseSinglePathExpr(UriInfoImpl uriInfo, final UriResourcePartTyped lastResource)
+      throws UriParserException, UriValidationException {
+    if (tokenizer.next(TokenKind.SLASH)) {
+      ParserHelper.requireNext(tokenizer, TokenKind.QualifiedName);
+      parseBoundFunction(new FullQualifiedName(tokenizer.getText()), uriInfo, lastResource);
+    }
+  }
+
+  private void parseComplexPathExpr(UriInfoImpl uriInfo, final UriResourcePartTyped lastResource)
+      throws UriParserException, UriValidationException {
+
+    if (tokenizer.next(TokenKind.SLASH)) {
+      if (tokenizer.next(TokenKind.QualifiedName)) {
+        final FullQualifiedName fullQualifiedName = new FullQualifiedName(tokenizer.getText());
+        final EdmEntityType edmEntityType = edm.getEntityType(fullQualifiedName);
+
+        if (edmEntityType != null) {
+          setTypeFilter(lastResource, edmEntityType);
+          if (tokenizer.next(TokenKind.SLASH)) {
+            parseComplexPathRestExpr(uriInfo, lastResource);
+          }
+        } else {
+          // Must be a bound function.
+          parseBoundFunction(fullQualifiedName, uriInfo, lastResource);
+        }
+      } else {
+        parseComplexPathRestExpr(uriInfo, lastResource);
+      }
+    }
+  }
+
+  private void parseComplexPathRestExpr(UriInfoImpl uriInfo, final UriResourcePartTyped lastResource)
+      throws UriParserException, UriValidationException {
+    if (tokenizer.next(TokenKind.QualifiedName)) {
+      final FullQualifiedName fullQualifiedName = new FullQualifiedName(tokenizer.getText());
+      // Must be a bound function.
+      parseBoundFunction(fullQualifiedName, uriInfo, lastResource);
+    } else if (tokenizer.next(TokenKind.ODataIdentifier)) {
+      parsePropertyPathExpr(uriInfo, lastResource);
+    } else {
+      throw new UriParserSyntaxException("Unexpected token.", UriParserSyntaxException.MessageKeys.SYNTAX);
+    }
+  }
+
+  private void parseCollectionPathExpr(UriInfoImpl uriInfo, final UriResourcePartTyped lastResource)
+      throws UriParserException, UriValidationException {
+
+    if (tokenizer.next(TokenKind.SLASH)) {
+      if (tokenizer.next(TokenKind.COUNT)) {
+        uriInfo.addResourcePart(new UriResourceCountImpl());
+      } else if (tokenizer.next(TokenKind.ANY)) {
+        uriInfo.addResourcePart(parseLambdaRest(TokenKind.ANY, lastResource));
+      } else if (tokenizer.next(TokenKind.ALL)) {
+        uriInfo.addResourcePart(parseLambdaRest(TokenKind.ALL, lastResource));
+      } else if (tokenizer.next(TokenKind.QualifiedName)) {
+        final FullQualifiedName fullQualifiedName = new FullQualifiedName(tokenizer.getText());
+        parseBoundFunction(fullQualifiedName, uriInfo, lastResource);
+      }
+    }
+  }
+
+  private void parseFunction(final FullQualifiedName fullQualifiedName, UriInfoImpl uriInfo,
+      final EdmType lastType, final boolean lastIsCollection) throws UriParserException, UriValidationException {
+
+    final List<UriParameter> parameters = ParserHelper.parseFunctionParameters(tokenizer, true);
+    final List<String> parameterNames = ParserHelper.getParameterNames(parameters);
+    final EdmFunction boundFunction = edm.getBoundFunction(fullQualifiedName,
+        lastType.getFullQualifiedName(), lastIsCollection, parameterNames);
+
+    if (boundFunction != null) {
+      parseFunctionRest(uriInfo, boundFunction, parameters);
+      return;
+    }
+
+    final EdmFunction unboundFunction = edm.getUnboundFunction(fullQualifiedName, parameterNames);
+    if (unboundFunction != null) {
+      parseFunctionRest(uriInfo, unboundFunction, parameters);
+      return;
+    }
+
+    throw new UriParserSemanticException("No function found.",
+        UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND, fullQualifiedName.getFullQualifiedNameAsString());
+  }
+
+  private void parseBoundFunction(final FullQualifiedName fullQualifiedName, UriInfoImpl uriInfo,
+      final UriResourcePartTyped lastResource) throws UriParserException, UriValidationException {
+    final List<UriParameter> parameters = ParserHelper.parseFunctionParameters(tokenizer, true);
+    final List<String> parameterNames = ParserHelper.getParameterNames(parameters);
+    final EdmFunction boundFunction = edm.getBoundFunction(fullQualifiedName,
+        lastResource.getType().getFullQualifiedName(), lastResource.isCollection(), parameterNames);
+    if (boundFunction == null) {
+      throw new UriParserSemanticException("Bound function not found.",
+          UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND, fullQualifiedName.getFullQualifiedNameAsString());
+    }
+    parseFunctionRest(uriInfo, boundFunction, parameters);
+  }
+
+  private void parseFunctionRest(UriInfoImpl uriInfo, final EdmFunction function,
+      final List<UriParameter> parameters) throws UriParserException, UriValidationException {
+    final UriResourceFunction functionResource = new UriResourceFunctionImpl(null, function, parameters);
+    uriInfo.addResourcePart(functionResource);
+
+    final EdmReturnType edmReturnType = function.getReturnType();
+    final EdmType edmType = edmReturnType.getType();
+    final boolean isCollection = edmReturnType.isCollection();
+
+    if (function.isComposable()) {
+      if (edmType instanceof EdmEntityType ) {
+        if (isCollection) {
+          parseCollectionNavigationExpr(uriInfo, null); // TODO: Get navigation property.
+        } else {
+          parseSingleNavigationExpr(uriInfo, null); // TODO: Get navigation property.
+        }
+      } else if (edmType instanceof EdmComplexType) {
+        if (isCollection) {
+          parseCollectionPathExpr(uriInfo, functionResource);
+        } else {
+          parseComplexPathExpr(uriInfo, functionResource);
+        }
+      } else if (edmType instanceof EdmPrimitiveType) {
+        if (isCollection) {
+          parseCollectionPathExpr(uriInfo, functionResource);
+        } else {
+          parseSinglePathExpr(uriInfo, functionResource);
+        }
+      }
+    } else if (tokenizer.next(TokenKind.SLASH)) {
+      throw new UriValidationException("Function is not composable.",
+          UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH, "");
+    }
+  }
+
+  private UriResourcePartTyped parseLambdaRest(final TokenKind lastTokenKind, final UriResourcePartTyped lastResource)
+      throws UriParserException, UriValidationException {
+
+    ParserHelper.requireNext(tokenizer, TokenKind.OPEN);
+    if (lastTokenKind == TokenKind.ANY && tokenizer.next(TokenKind.CLOSE)) {
+      return new UriResourceLambdaAnyImpl(null, null);
+    }
+    ParserHelper.requireNext(tokenizer, TokenKind.ODataIdentifier);
+    final String lambbdaVariable = tokenizer.getText();
+    ParserHelper.requireNext(tokenizer, TokenKind.COLON);
+    lambdaVariables.addFirst(new UriResourceLambdaVarImpl(lambbdaVariable,
+        lastResource == null ? referringType : lastResource.getType()));
+    final Expression lambdaPredicateExpr = parseExpression();
+    lambdaVariables.removeFirst();
+    // TODO: The ABNF suggests that the "lambaPredicateExpr" must contain at least one lambdaVariable.
+    ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
+    if (lastTokenKind == TokenKind.ALL) {
+      return new UriResourceLambdaAllImpl(lambbdaVariable, lambdaPredicateExpr);
+    } else if (lastTokenKind == TokenKind.ANY) {
+      return new UriResourceLambdaAnyImpl(lambbdaVariable, lambdaPredicateExpr);
+    } else {
+      throw new UriParserSyntaxException("Unexpected token.", UriParserSyntaxException.MessageKeys.SYNTAX);
+    }
+  }
+
   private TokenKind nextMethod() {
     return ParserHelper.next(tokenizer,
         TokenKind.CeilingMethod,
@@ -580,9 +1044,9 @@ public class ExpressionParser {
     }
   }
 
-  private EdmPrimitiveType getEnumType(final String primitiveValueLiteral) throws UriParserException {
+  private EdmEnumType getEnumType(final String primitiveValueLiteral) throws UriParserException {
     final String enumTypeName = primitiveValueLiteral.substring(0, primitiveValueLiteral.indexOf('\''));
-    final EdmPrimitiveType type = edm.getEnumType(new FullQualifiedName(enumTypeName));
+    final EdmEnumType type = edm.getEnumType(new FullQualifiedName(enumTypeName));
     if (type == null) {
       throw new UriParserSemanticException("Unknown Enum type '" + enumTypeName + "'.",
           UriParserSemanticException.MessageKeys.UNKNOWN_TYPE, enumTypeName);
@@ -599,13 +1063,16 @@ public class ExpressionParser {
             EdmPrimitiveTypeKind.Byte, EdmPrimitiveTypeKind.SByte);
   }
 
-  private void checkEnumLiteral(final Expression expression) throws UriParserException {
-    if (expression == null
-        || !(expression instanceof Literal)
-        || ((Literal) expression).getType() == null
-        || ((Literal) expression).getType().getKind() != EdmTypeKind.ENUM) {
-      throw new UriParserSemanticException("Enum literal expected.",
-          UriParserSemanticException.MessageKeys.UNKNOWN_TYPE, ""); // TODO: better message
+  private Enumeration createEnumExpression(final String primitiveValueLiteral) throws UriParserException {
+    final EdmEnumType enumType = getEnumType(primitiveValueLiteral);
+    // TODO: Can the Enumeration interface be changed to handle the value as a whole?
+    try {
+      return new EnumerationImpl(enumType,
+          Arrays.asList(enumType.fromUriLiteral(primitiveValueLiteral).split(",")));
+    } catch (final EdmPrimitiveTypeException e) {
+      // TODO: Better error message.
+      throw new UriParserSemanticException("Wrong enumeration value.", e,
+          UriParserSemanticException.MessageKeys.UNKNOWN_PART, primitiveValueLiteral);
     }
   }
 
@@ -664,4 +1131,13 @@ public class ExpressionParser {
     throw new UriParserSemanticException("Incompatible types.",
         UriParserSemanticException.MessageKeys.UNKNOWN_TYPE, ""); // TODO: better message
   }
+
+  private void checkStructuredTypeFilter(final EdmType type, final EdmStructuredType filterType)
+      throws UriParserException {
+    if (!filterType.compatibleTo(type)) {
+      throw new UriParserSemanticException("Incompatible type filter.",
+          UriParserSemanticException.MessageKeys.INCOMPATIBLE_TYPE_FILTER,
+          filterType.getFullQualifiedName().getFullQualifiedNameAsString());
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java
new file mode 100644
index 0000000..a3376e0
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/FilterParser.java
@@ -0,0 +1,49 @@
+/*
+ * 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.parser;
+
+import java.util.Collection;
+
+import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.EdmStructuredType;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.uri.queryoption.FilterOption;
+import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
+import org.apache.olingo.server.core.uri.queryoption.FilterOptionImpl;
+import org.apache.olingo.server.core.uri.validator.UriValidationException;
+
+public class FilterParser {
+
+  private final Edm edm;
+  private final OData odata;
+
+  public FilterParser(final Edm edm, final OData odata) {
+    this.edm = edm;
+    this.odata = odata;
+  }
+
+  public FilterOption parse(UriTokenizer tokenizer, final EdmStructuredType referencedType,
+      final Collection<String> crossjoinEntitySetNames)
+      throws UriParserException, UriValidationException {
+    final Expression filterExpression = new ExpressionParser(edm, odata)
+        .parse(tokenizer, referencedType, crossjoinEntitySetNames);
+    // TODO: Check that the expression is boolean.
+    return new FilterOptionImpl().setExpression(filterExpression);
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/a8091658/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java
new file mode 100644
index 0000000..5ea8cb7
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/OrderByParser.java
@@ -0,0 +1,61 @@
+/*
+ * 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.parser;
+
+import java.util.Collection;
+
+import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.EdmStructuredType;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
+import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
+import org.apache.olingo.server.core.uri.parser.UriTokenizer.TokenKind;
+import org.apache.olingo.server.core.uri.queryoption.OrderByItemImpl;
+import org.apache.olingo.server.core.uri.queryoption.OrderByOptionImpl;
+import org.apache.olingo.server.core.uri.validator.UriValidationException;
+
+public class OrderByParser {
+
+  private final Edm edm;
+  private final OData odata;
+
+  public OrderByParser(final Edm edm, final OData odata) {
+    this.edm = edm;
+    this.odata = odata;
+  }
+
+  public OrderByOption parse(UriTokenizer tokenizer, final EdmStructuredType referencedType,
+      final Collection<String> crossjoinEntitySetNames)
+      throws UriParserException, UriValidationException {
+    OrderByOptionImpl orderByOption = new OrderByOptionImpl();
+    do {
+      final Expression orderByExpression = new ExpressionParser(edm, odata)
+          .parse(tokenizer, referencedType, crossjoinEntitySetNames);
+      OrderByItemImpl item = new OrderByItemImpl();
+      item.setExpression(orderByExpression);
+      if (tokenizer.next(TokenKind.AscSuffix)) {
+        item.setDescending(false);
+      } else if (tokenizer.next(TokenKind.DescSuffix)) {
+        item.setDescending(true);
+      }
+      orderByOption.addOrder(item);
+    } while (tokenizer.next(TokenKind.COMMA));
+    return orderByOption;
+  }
+}