Repository: olingo-odata2
Updated Branches:
  refs/heads/master 7d882075a -> 919d4ac0f


[OLINGO-1026] existence check of navigation target in filter/orderby

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


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

Branch: refs/heads/master
Commit: 919d4ac0f85f59295f7fde00a9f8cdc12085e441
Parents: 7d88207
Author: Klaus Straubinger <klaus.straubin...@sap.com>
Authored: Wed Sep 21 15:16:04 2016 +0200
Committer: Christian Amend <christian.am...@sap.com>
Committed: Wed Sep 21 15:23:18 2016 +0200

----------------------------------------------------------------------
 .../expression/ExpressionParserException.java   |  10 +-
 .../expression/FilterParserExceptionImpl.java   |  13 +-
 .../core/uri/expression/FilterParserImpl.java   | 108 ++----
 .../src/main/resources/i18n.properties          |   5 +-
 .../src/main/resources/i18n_en.properties       |   5 +-
 .../odata2/core/uri/expression/ParserTool.java  | 384 +++----------------
 .../odata2/core/uri/expression/TestBase.java    |  12 +-
 .../odata2/core/uri/expression/TestParser.java  | 233 +++++------
 .../odata2/ref/processor/ListsProcessor.java    |  84 ++--
 .../olingo/odata2/testutil/mock/TecEdmInfo.java |  22 +-
 .../mock/TechnicalScenarioEdmProvider.java      |  21 +-
 11 files changed, 289 insertions(+), 608 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/919d4ac0/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/expression/ExpressionParserException.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/expression/ExpressionParserException.java
 
b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/expression/ExpressionParserException.java
index c9b84a5..1ca309a 100644
--- 
a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/expression/ExpressionParserException.java
+++ 
b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/uri/expression/ExpressionParserException.java
@@ -45,10 +45,10 @@ public class ExpressionParserException extends 
ODataBadRequestException {
       ExpressionParserException.class, "COMMA_OR_END_EXPECTED_AT_POS");
   public static final MessageReference EXPRESSION_EXPECTED_AT_POS = 
createMessageReference(
       ExpressionParserException.class, "EXPRESSION_EXPECTED_AT_POS");
-  public static final MessageReference MISSING_CLOSING_PHARENTHESIS = 
createMessageReference(
-      ExpressionParserException.class, "MISSING_CLOSING_PHARENTHESIS");
-  public static final MessageReference 
COMMA_OR_CLOSING_PHARENTHESIS_EXPECTED_AFTER_POS = createMessageReference(
-      ExpressionParserException.class, 
"COMMA_OR_CLOSING_PHARENTHESIS_EXPECTED_AFTER_POS");
+  public static final MessageReference MISSING_CLOSING_PARENTHESIS = 
createMessageReference(
+      ExpressionParserException.class, "MISSING_CLOSING_PARENTHESIS");
+  public static final MessageReference 
COMMA_OR_CLOSING_PARENTHESIS_EXPECTED_AFTER_POS = createMessageReference(
+      ExpressionParserException.class, 
"COMMA_OR_CLOSING_PARENTHESIS_EXPECTED_AFTER_POS");
   public static final MessageReference INVALID_METHOD_CALL = 
createMessageReference(ExpressionParserException.class,
       "INVALID_METHOD_CALL");
   public static final MessageReference TYPE_EXPECTED_AT = 
createMessageReference(ExpressionParserException.class,
@@ -73,6 +73,8 @@ public class ExpressionParserException extends 
ODataBadRequestException {
       ExpressionParserException.class, "LEFT_SIDE_NOT_A_PROPERTY");
   public static final MessageReference PROPERTY_NAME_NOT_FOUND_IN_TYPE = 
createMessageReference(
       ExpressionParserException.class, "PROPERTY_NAME_NOT_FOUND_IN_TYPE");
+  public static final MessageReference INVALID_MULTIPLICITY = 
createMessageReference(
+      ExpressionParserException.class, "INVALID_MULTIPLICITY");
 
   // validation exceptions texts - binary
   public static final MessageReference INVALID_TYPES_FOR_BINARY_OPERATOR = 
createMessageReference(

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/919d4ac0/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/FilterParserExceptionImpl.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/FilterParserExceptionImpl.java
 
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/FilterParserExceptionImpl.java
index 403fe2f..25a4d36 100644
--- 
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/FilterParserExceptionImpl.java
+++ 
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/FilterParserExceptionImpl.java
@@ -22,7 +22,6 @@ import org.apache.olingo.odata2.api.edm.EdmException;
 import org.apache.olingo.odata2.api.edm.EdmStructuralType;
 import org.apache.olingo.odata2.api.edm.EdmType;
 import org.apache.olingo.odata2.api.exception.MessageReference;
-import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
 import org.apache.olingo.odata2.api.uri.expression.BinaryOperator;
 import org.apache.olingo.odata2.api.uri.expression.CommonExpression;
 import org.apache.olingo.odata2.api.uri.expression.ExpressionParserException;
@@ -39,10 +38,6 @@ import 
org.apache.olingo.odata2.api.uri.expression.PropertyExpression;
 public class FilterParserExceptionImpl extends ExpressionParserException {
   private static final long serialVersionUID = 77L;
 
-  static public ExpressionParserException createCOMMON() {
-    return new ExpressionParserException(ODataBadRequestException.COMMON);
-  }
-
   static public ExpressionParserException createERROR_IN_TOKENIZER(final 
TokenizerException exceptionTokenizer,
       final String expression) {
     Token token = exceptionTokenizer.getToken();
@@ -105,9 +100,9 @@ public class FilterParserExceptionImpl extends 
ExpressionParserException {
     return new ExpressionParserException(msgRef);
   }
 
-  static public ExpressionParserException 
createCOMMA_OR_CLOSING_PHARENTHESIS_EXPECTED_AFTER_POS(final Token token,
+  static public ExpressionParserException 
createCOMMA_OR_CLOSING_PARENTHESIS_EXPECTED_AFTER_POS(final Token token,
       final String expression) {
-    MessageReference msgRef = 
ExpressionParserException.COMMA_OR_CLOSING_PHARENTHESIS_EXPECTED_AFTER_POS.create();
+    MessageReference msgRef = 
ExpressionParserException.COMMA_OR_CLOSING_PARENTHESIS_EXPECTED_AFTER_POS.create();
 
     msgRef.addContent(Integer.toString(token.getPosition() + 
token.getUriLiteral().length()));
     msgRef.addContent(expression);
@@ -248,9 +243,9 @@ public class FilterParserExceptionImpl extends 
ExpressionParserException {
     return new ExpressionParserException(msgRef);
   }
 
-  public static ExpressionParserException 
createMISSING_CLOSING_PHARENTHESIS(final int position,
+  public static ExpressionParserException 
createMISSING_CLOSING_PARENTHESIS(final int position,
       final String expression, final TokenizerExpectError e) {
-    MessageReference msgRef = 
ExpressionParserException.MISSING_CLOSING_PHARENTHESIS.create();
+    MessageReference msgRef = 
ExpressionParserException.MISSING_CLOSING_PARENTHESIS.create();
 
     msgRef.addContent(position + 1);
     msgRef.addContent(expression);

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/919d4ac0/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/FilterParserImpl.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/FilterParserImpl.java
 
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/FilterParserImpl.java
index 47be745..fe54085 100644
--- 
a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/FilterParserImpl.java
+++ 
b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/expression/FilterParserImpl.java
@@ -27,10 +27,12 @@ import java.util.Map;
 import org.apache.olingo.odata2.api.edm.EdmComplexType;
 import org.apache.olingo.odata2.api.edm.EdmEntityType;
 import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
 import org.apache.olingo.odata2.api.edm.EdmSimpleType;
 import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
 import org.apache.olingo.odata2.api.edm.EdmStructuralType;
 import org.apache.olingo.odata2.api.edm.EdmType;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
 import org.apache.olingo.odata2.api.edm.EdmTyped;
 import org.apache.olingo.odata2.api.uri.expression.BinaryExpression;
 import org.apache.olingo.odata2.api.uri.expression.BinaryOperator;
@@ -209,7 +211,7 @@ public class FilterParserImpl implements FilterParser {
     } catch (TokenizerExpectError e) {
       // Internal parsing error, even if there are no more token (then there 
should be a different exception).
       // Tested with TestParserExceptions.TestPMreadParenthesis
-      throw 
FilterParserExceptionImpl.createMISSING_CLOSING_PHARENTHESIS(openParenthesis.getPosition(),
 curExpression,
+      throw 
FilterParserExceptionImpl.createMISSING_CLOSING_PARENTHESIS(openParenthesis.getPosition(),
 curExpression,
           e);
     }
     return parenthesisExpression;
@@ -246,7 +248,7 @@ public class FilterParserImpl implements FilterParser {
     while (token.getKind() != TokenKind.CLOSEPAREN) {
       if (readComma == false) {
         // Tested with TestParserExceptions.TestPMreadParameters CASE 12 e.g. 
"$filter=concat('a' 'b')"
-        throw 
FilterParserExceptionImpl.createCOMMA_OR_CLOSING_PHARENTHESIS_EXPECTED_AFTER_POS(tokenList
+        throw 
FilterParserExceptionImpl.createCOMMA_OR_CLOSING_PARENTHESIS_EXPECTED_AFTER_POS(tokenList
             .lookPrevToken(), curExpression);
       }
       expression = readElement(null);
@@ -264,7 +266,7 @@ public class FilterParserImpl implements FilterParser {
       token = tokenList.lookToken();
       if (token == null) {
         // Tested with TestParserExceptions.TestPMreadParameters CASE 2 e.g. 
"$filter=concat(123"
-        throw 
FilterParserExceptionImpl.createCOMMA_OR_CLOSING_PHARENTHESIS_EXPECTED_AFTER_POS(tokenList
+        throw 
FilterParserExceptionImpl.createCOMMA_OR_CLOSING_PARENTHESIS_EXPECTED_AFTER_POS(tokenList
             .lookPrevToken(), curExpression);
       }
 
@@ -444,7 +446,7 @@ public class FilterParserImpl implements FilterParser {
       final Token propertyToken, final ActualBinaryOperator actBinOp) throws 
ExpressionParserException,
       ExpressionParserInternalError {
 
-    // Exist if no edm provided
+    // Exit if no edm provided
     if (resourceEntityType == null) {
       return;
     }
@@ -504,6 +506,12 @@ public class FilterParserImpl implements FilterParser {
       if (edmProperty != null) {
         property.setEdmProperty(edmProperty);
         property.setEdmType(edmProperty.getType());
+        if (edmProperty.getMultiplicity() == EdmMultiplicity.MANY) {
+          throw new ExpressionParserException(
+              ExpressionParserException.INVALID_MULTIPLICITY.create()
+                  .addContent(propertyName)
+                  .addContent(propertyToken.getPosition() + 1));
+        }
       } else {
         // Tested with TestParserExceptions.TestPMvalidateEdmProperty CASE 3
         throw 
FilterParserExceptionImpl.createPROPERTY_NAME_NOT_FOUND_IN_TYPE(parentType, 
property, propertyToken,
@@ -516,58 +524,6 @@ public class FilterParserImpl implements FilterParser {
     }
   }
 
-  /*
-   * protected void validateEdmPropertyOfComplexType1(EdmComplexType 
parentType, PropertyExpressionImpl property, Token
-   * propertyToken) throws FilterParserException, FilterParserInternalError
-   * {
-   * try {
-   * String propertyName = property.getUriLiteral();
-   * EdmTyped edmProperty = parentType.getProperty(propertyName);
-   * 
-   * if (edmProperty != null)
-   * {
-   * property.setEdmProperty(edmProperty);
-   * property.setEdmType(edmProperty.getType());
-   * }
-   * else
-   * {
-   * //Tested with TestParserExceptions.TestPMvalidateEdmProperty CASE 3
-   * throw 
FilterParserExceptionImpl.createPROPERTY_NAME_NOT_FOUND_IN_TYPE(parentType, 
property, propertyToken,
-   * curExpression);
-   * }
-   * 
-   * } catch (EdmException e) {
-   * // not Tested, should not occur
-   * throw FilterParserInternalError.createERROR_ACCESSING_EDM(e);
-   * }
-   * }
-   * 
-   * protected void validateEdmPropertyOfEntityType1(EdmEntityType parentType, 
PropertyExpressionImpl property, Token
-   * propertyToken) throws FilterParserException, FilterParserInternalError
-   * {
-   * try {
-   * String propertyName = property.getUriLiteral();
-   * EdmTyped edmProperty = parentType.getProperty(propertyName);
-   * 
-   * if (edmProperty != null)
-   * {
-   * property.setEdmProperty(edmProperty);
-   * property.setEdmType(edmProperty.getType());
-   * }
-   * else
-   * {
-   * //Tested with TestParserExceptions.TestPMvalidateEdmProperty CASE 1
-   * throw 
FilterParserExceptionImpl.createPROPERTY_NAME_NOT_FOUND_IN_TYPE(parentType, 
property, propertyToken,
-   * curExpression);
-   * }
-   * 
-   * } catch (EdmException e) {
-   * // not Tested, should not occur
-   * throw FilterParserInternalError.createERROR_ACCESSING_EDM(e);
-   * }
-   * }
-   */
-
   protected void validateUnaryOperatorTypes(final UnaryExpression 
unaryExpression)
       throws ExpressionParserInternalError {
     InfoUnaryOperator unOpt = 
availableUnaryOperators.get(unaryExpression.getOperator().toUriLiteral());
@@ -591,21 +547,29 @@ public class FilterParserImpl implements FilterParser {
     InfoBinaryOperator binOpt = 
availableBinaryOperators.get(binaryExpression.getOperator().toUriLiteral());
 
     List<EdmType> actualParameterTypes = new ArrayList<EdmType>();
-    EdmType operand = binaryExpression.getLeftOperand().getEdmType();
-
-    if ((operand == null) && (resourceEntityType == null)) {
+    final EdmType leftType = binaryExpression.getLeftOperand().getEdmType();
+    if (leftType == null && resourceEntityType == null) {
       return;
     }
-    actualParameterTypes.add(operand);
+    actualParameterTypes.add(leftType);
 
-    operand = binaryExpression.getRightOperand().getEdmType();
+    final EdmType rightType = binaryExpression.getRightOperand().getEdmType();
+    if (rightType == null && resourceEntityType == null) {
+      return;
+    }
+    actualParameterTypes.add(rightType);
 
-    if ((operand == null) && (resourceEntityType == null)) {
+    // special case for navigation property (non-)equality comparison with null
+    if (binOpt.getCategory().equals("Equality")
+        && (leftType.getKind() == EdmTypeKind.ENTITY
+            && rightType == 
EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Null)
+            || leftType == 
EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Null)
+            && rightType.getKind() == EdmTypeKind.ENTITY)) {
+      
binaryExpression.setEdmType(EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Boolean));
       return;
     }
-    actualParameterTypes.add(operand);
 
-    ParameterSet parameterSet = 
binOpt.validateParameterSet(actualParameterTypes);
+    final ParameterSet parameterSet = 
binOpt.validateParameterSet(actualParameterTypes);
     if (parameterSet == null) {
       BinaryExpressionImpl binaryExpressionImpl = (BinaryExpressionImpl) 
binaryExpression;
 
@@ -624,7 +588,7 @@ public class FilterParserImpl implements FilterParser {
     List<EdmType> actualParameterTypes = new ArrayList<EdmType>();
 
     // If there are no parameter then don't perform a type check
-    if (methodExpression.getParameters().size() == 0) {
+    if (methodExpression.getParameters().isEmpty()) {
       return;
     }
 
@@ -632,7 +596,7 @@ public class FilterParserImpl implements FilterParser {
       // If there is not at parsing time its not possible to determine the 
type of eg myPropertyName.
       // Since this should not cause validation errors null type node 
arguments are leading to bypass
       // the validation
-      if ((parameter.getEdmType() == null) && (resourceEntityType == null)) {
+      if (parameter.getEdmType() == null && resourceEntityType == null) {
         return;
       }
       actualParameterTypes.add(parameter.getEdmType());
@@ -674,7 +638,7 @@ public class FilterParserImpl implements FilterParser {
     EdmSimpleType binary = 
EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Binary);
     EdmSimpleType null_ = 
EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Null);
 
-    // ---Memeber member access---
+    // ---Member member access---
     lAvailableBinaryOperators.put("/", new 
InfoBinaryOperator(BinaryOperator.PROPERTY_ACCESS, "Primary", 100,
         new ParameterSetCombination.PSCReturnTypeEqLastParameter()));// todo 
fix this
 
@@ -766,7 +730,7 @@ public class FilterParserImpl implements FilterParser {
     combination.add(new ParameterSet(boolean_, double_, double_));
     combination.add(new ParameterSet(boolean_, decimal, decimal));
     combination.add(new ParameterSet(boolean_, binary, binary));
-    
+
     combination.add(new ParameterSet(boolean_, string, null_));
     combination.add(new ParameterSet(boolean_, null_, string));
     
@@ -842,23 +806,23 @@ public class FilterParserImpl implements FilterParser {
     lAvailableBinaryOperators.put(BinaryOperator.NE.toUriLiteral(), new 
InfoBinaryOperator(BinaryOperator.NE,
         "Equality", 30, combination));
 
-    // "---Conditinal AND---
+    // "---Conditional AND---
     combination = new ParameterSetCombination.PSCflex();
     combination.add(new ParameterSet(boolean_, boolean_, boolean_));
     combination.add(new ParameterSet(boolean_, boolean_, null_));
     combination.add(new ParameterSet(boolean_, null_, boolean_));
 
     lAvailableBinaryOperators.put(BinaryOperator.AND.toUriLiteral(), new 
InfoBinaryOperator(BinaryOperator.AND,
-        "Conditinal", 20, combination));
+        "Conditional", 20, combination));
 
-    // ---Conditinal OR---
+    // ---Conditional OR---
     combination = new ParameterSetCombination.PSCflex();
     combination.add(new ParameterSet(boolean_, boolean_, boolean_));
     combination.add(new ParameterSet(boolean_, boolean_, null_));
     combination.add(new ParameterSet(boolean_, null_, boolean_));
 
     lAvailableBinaryOperators.put(BinaryOperator.OR.toUriLiteral(), new 
InfoBinaryOperator(BinaryOperator.OR,
-        "Conditinal", 10, combination));
+        "Conditional", 10, combination));
 
     // endswith
     combination = new ParameterSetCombination.PSCflex();

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/919d4ac0/odata2-lib/odata-core/src/main/resources/i18n.properties
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/resources/i18n.properties 
b/odata2-lib/odata-core/src/main/resources/i18n.properties
index 42311e4..2de9892 100644
--- a/odata2-lib/odata-core/src/main/resources/i18n.properties
+++ b/odata2-lib/odata-core/src/main/resources/i18n.properties
@@ -197,12 +197,12 @@ 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.COMMON=Err
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_TRAILING_TOKEN_DETECTED_AFTER_PARSING=Invalid
 token "%1$s" detected after parsing at position %2$s in "%3$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.TOKEN_UNDETERMINATED_STRING=Unterminated
 string literal at position %1$s in "%2$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_TYPES_FOR_BINARY_OPERATOR=Operator
 "%1$s" incompatible with operand types "%2$s" and "%3$s" at position %4$s in 
"%5$s".
-org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.MISSING_CLOSING_PHARENTHESIS=Missing
 closing parenthesis ")" for opening parenthesis "(" at position %1$s in "%2$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.MISSING_CLOSING_PARENTHESIS=Missing
 closing parenthesis ")" for opening parenthesis "(" at position %1$s in "%2$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.ERROR_IN_TOKENIZER=Error
 while tokenizing a ODATA expression on token "%1$s" at position %2$s in "%3$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.EXPRESSION_EXPECTED_AFTER_POS=Expression
 expected after position %1$s in "%2$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.COMMA_OR_END_EXPECTED_AT_POS=Comma
 or end of expression expected at position %1$s in "%2$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.EXPRESSION_EXPECTED_AT_POS=Expression
 expected at position %1$s in "%2$s".
-org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.COMMA_OR_CLOSING_PHARENTHESIS_EXPECTED_AFTER_POS=")"
 or "," expected after position %1$s in "%2$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.COMMA_OR_CLOSING_PARENTHESIS_EXPECTED_AFTER_POS=")"
 or "," expected after position %1$s in "%2$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_METHOD_CALL=Unknown
 function "%1$s" at position %2$s in "%3$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.METHOD_WRONG_ARG_EXACT=No
 applicable method found for "%1$s" at position %2$s in "%3$s" with the 
specified arguments. Method "%1$s" requires exact %4$s argument(s).
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.METHOD_WRONG_ARG_BETWEEN=No
 applicable method found for "%1$s" at position %2$s in "%3$s" with the 
specified arguments. Method "%1$s" requires between %4$s and %5$s arguments.
@@ -212,6 +212,7 @@ 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.METHOD_WRO
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.LEFT_SIDE_NOT_STRUCTURAL_TYPE=No
 property "%1$s" exists in type "%2$s" at position %3$s in "%4$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.LEFT_SIDE_NOT_A_PROPERTY=Leftside
 of method operator at position %1$s is not a property in "%2$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.PROPERTY_NAME_NOT_FOUND_IN_TYPE=No
 property "%1$s" exists in type "%2$s" at position %3$s in "%4$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_MULTIPLICITY=The
 property '%1$s' at position %2$s has the wrong multiplicity.
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_SORT_ORDER=Invalid
 sort order in OData orderby parser at position %1$s in "%2$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.TYPE_EXPECTED_AT=Expression
 of type "%1$s" expected at position %2$s in "%3$s" (actual type is "%4$s").
 
org.apache.olingo.odata2.core.uri.expression.ExpressionParserInternalError.ERROR_PARSING_METHOD=Internal
 error in OData filter parser while parsing a method expression.

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/919d4ac0/odata2-lib/odata-core/src/main/resources/i18n_en.properties
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/resources/i18n_en.properties 
b/odata2-lib/odata-core/src/main/resources/i18n_en.properties
index 7de9229..83fd9b0 100644
--- a/odata2-lib/odata-core/src/main/resources/i18n_en.properties
+++ b/odata2-lib/odata-core/src/main/resources/i18n_en.properties
@@ -139,11 +139,11 @@ 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.COMMON=Err
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_TRAILING_TOKEN_DETECTED_AFTER_PARSING=Invalid
 token "%1$s" detected after parsing at position %2$s in "%3$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.TOKEN_UNDETERMINATED_STRING=Unterminated
 string literal at position %1$s in "%2$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_TYPES_FOR_BINARY_OPERATOR=Operator
 "%1$s" incompatible with operand types "%2$s" and "%3$s" at position %4$s in 
"%5$s".
-org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.MISSING_CLOSING_PHARENTHESIS=Missing
 closing parenthesis ")" for opening parenthesis "(" at position %1$s in "%2$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.MISSING_CLOSING_PARENTHESIS=Missing
 closing parenthesis ")" for opening parenthesis "(" at position %1$s in "%2$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.ERROR_IN_TOKENIZER=Error
 while tokenizing a ODATA expression on token '%1$s' at position '%2$s'.
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.EXPRESSION_EXPECTED_AFTER_POS=Expression
 expected after position %1$s in "%2$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.EXPRESSION_EXPECTED_AT_POS=Expression
 expected at position %1$s.
-org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.COMMA_OR_CLOSING_PHARENTHESIS_EXPECTED_AFTER_POS=")"
 or "," expected after position %1$s.
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.COMMA_OR_CLOSING_PARENTHESIS_EXPECTED_AFTER_POS=")"
 or "," expected after position %1$s.
 
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.METHOD_WRONG_ARG_EXACT=No
 applicable method found for "%1$s" at position %2$s in "%3$s" with the 
specified arguments. Method "%1$s" requires exact %4$s argument(s).
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.METHOD_WRONG_ARG_BETWEEN=No
 applicable method found for "%1$s" at position %2$s in "%3$s" with the 
specified arguments. Method "%1$s" requires between %4$s and %5$s arguments.
@@ -152,6 +152,7 @@ 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.METHOD_WRO
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.LEFT_SIDE_NOT_STRUCTURAL_TYPE=No
 property "%1$s" exists in type "%2$s" at position %3$s in "%4$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.LEFT_SIDE_NOT_A_PROPERTY=Leftside
 of method operator at position %1$s is not a property in "%2$s".
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.PROPERTY_NAME_NOT_FOUND_IN_TYPE=No
 property "%1$s" exists in type "%2$s" at position %3$s in "%4$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_MULTIPLICITY=The
 property '%1$s' at position %2$s has the wrong multiplicity.
 
org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_SORT_ORDER=Invalid
 sort order in OData orderby parser at position %1$s in %2$s.
 
org.apache.olingo.odata2.core.uri.expression.ExpressionParserInternalError.ERROR_PARSING_METHOD=Internal
 error in OData filter parser while parsing a method expression.
 
org.apache.olingo.odata2.core.uri.expression.ExpressionParserInternalError.ERROR_PARSING_PARENTHESIS=Internal
 error in OData filter parser while parsing a parenthesis expression.

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/919d4ac0/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/ParserTool.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/ParserTool.java
 
b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/ParserTool.java
index 1c7d08b..7c2357e 100644
--- 
a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/ParserTool.java
+++ 
b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/ParserTool.java
@@ -19,13 +19,15 @@
 package org.apache.olingo.odata2.core.uri.expression;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.util.Locale;
 
-import org.apache.log4j.xml.DOMConfigurator;
 import org.apache.olingo.odata2.api.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.edm.EdmException;
 import org.apache.olingo.odata2.api.edm.EdmProperty;
 import org.apache.olingo.odata2.api.edm.EdmType;
 import org.apache.olingo.odata2.api.exception.MessageReference;
@@ -40,78 +42,31 @@ import 
org.apache.olingo.odata2.api.uri.expression.SortOrder;
 import org.apache.olingo.odata2.core.exception.MessageService;
 import org.apache.olingo.odata2.core.exception.MessageService.Message;
 import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
- *  
+ *  Helper for testing the expression parser.
  */
 public class ParserTool {
 
-  static {
-    DOMConfigurator.configureAndWatch("log4j.xml");
-  }
-
-  private static final Logger log = LoggerFactory.getLogger(ParserTool.class);
-
-  private static boolean debug = false;
-
   private String expression;
   private CommonExpression tree;
   private CommonExpression curNode;
   private Exception curException;
   private static final Locale DEFAULT_LANGUAGE = new Locale("test", "FOO");
 
-  public static void dout(final String out) {
-    if (debug) {
-      ParserTool.log.debug(out);
-    }
-  }
-
-  public static void out(final String out) {
-    ParserTool.log.debug(out);
-  }
-
-  public ParserTool(final String expression, final boolean isOrder, final 
boolean addTestfunctions,
-      final boolean allowOnlyBinary) {
-    dout("ParserTool - Testing: " + expression);
-    this.expression = expression;
-
-    try {
-      if (!isOrder) {
-        FilterParserImplTool parser = new FilterParserImplTool(null);
-        if (addTestfunctions) {
-          parser.addTestfunctions();
-        }
-        tree = parser.parseFilterString(expression, 
allowOnlyBinary).getExpression();
-      } else {
-        OrderByParserImpl parser = new OrderByParserImpl(null);
-        tree = parser.parseOrderByString(expression);
-      }
-    } catch (ExpressionParserException e) {
-      curException = e;
-    } catch (ExpressionParserInternalError e) {
-      curException = e;
-    }
-
-    curNode = tree;
-  }
-
   public ParserTool(final String expression, final boolean isOrder, final 
boolean addTestfunctions,
       final boolean allowOnlyBinary, final EdmEntityType resourceEntityType) {
-    dout("ParserTool - Testing: " + expression);
     this.expression = expression;
 
     try {
-      if (!isOrder) {
+      if (isOrder) {
+        tree = new 
OrderByParserImpl(resourceEntityType).parseOrderByString(expression);
+      } else {
         FilterParserImplTool parser = new 
FilterParserImplTool(resourceEntityType);
         if (addTestfunctions) {
           parser.addTestfunctions();
         }
         tree = parser.parseFilterString(expression, 
allowOnlyBinary).getExpression();
-      } else {
-        OrderByParserImpl parser = new OrderByParserImpl(resourceEntityType);
-        tree = parser.parseOrderByString(expression);
       }
     } catch (ExpressionParserException e) {
       curException = e;
@@ -124,16 +79,12 @@ public class ParserTool {
 
   ParserTool aKind(final ExpressionKind kind) {
     String info = "GetInfoKind(" + expression + ")-->";
-    dout("  " + info + "Expected: " + kind.toString() + " Actual: " + 
curNode.getKind().toString());
-
     assertEquals(info, kind, curNode.getKind());
     return this;
   }
 
   public ParserTool aUriLiteral(final String uriLiteral) {
     String info = "GetUriLiteral(" + expression + ")-->";
-    dout("  " + info + "Expected: " + uriLiteral + " Actual: " + 
curNode.getUriLiteral());
-
     assertEquals(info, uriLiteral, curNode.getUriLiteral());
     return this;
   }
@@ -148,15 +99,8 @@ public class ParserTool {
   public ParserTool aExType(final Class<? extends Exception> expected) {
     String info = "GetExceptionType(" + expression + ")-->";
 
-    if (curException == null) {
-      fail("Error in aExType: Expected exception " + expected.getName());
-    }
-
-    dout("  " + info + "Expected: " + expected.getName() + " Actual: " + 
curException.getClass().getName());
-
-    if (expected != curException.getClass()) {
-      fail("  " + info + "Expected: " + expected.getName() + " Actual: " + 
curException.getClass().getName());
-    }
+    assertNotNull(info, curException);
+    assertTrue(info, expected.isAssignableFrom(curException.getClass()));
     return this;
   }
 
@@ -169,24 +113,11 @@ public class ParserTool {
    */
   public ParserTool aExMsgText(final String messageText) {
     String info = "aExMessageText(" + expression + ")-->";
-    if (curException == null) {
-      fail("Error in aExMessageText: Expected exception.");
-    }
-
-    ODataMessageException messageException;
 
-    try {
-      messageException = (ODataMessageException) curException;
-    } catch (ClassCastException ex) {
-      fail("Error in aExNext: curException not an ODataMessageException");
-      return this;
-    }
-
-    Message ms = MessageService.getMessage(DEFAULT_LANGUAGE, 
messageException.getMessageReference());
-    info = "  " + info + "Expected: '" + messageText + "' Actual: '" + 
ms.getText() + "'";
+    aExType(ODataMessageException.class);
 
-    dout(info);
-    assertEquals(info, messageText, ms.getText());
+    info = "  " + info + "Expected: '" + messageText + "' Actual: '" + 
getExceptionText() + "'";
+    assertEquals(info, messageText, getExceptionText());
 
     return this;
   }
@@ -199,27 +130,12 @@ public class ParserTool {
    */
   public ParserTool aExMsgContentAllSet() {
     String info = "aExMessageTextNoEmptyTag(" + expression + ")-->";
-    if (curException == null) {
-      fail("Error in aExMessageText: Expected exception.");
-    }
-
-    ODataMessageException messageException;
-
-    try {
-      messageException = (ODataMessageException) curException;
-    } catch (ClassCastException ex) {
-      fail("Error in aExNext: curException not an ODataMessageException");
-      return this;
-    }
 
-    Message ms = MessageService.getMessage(DEFAULT_LANGUAGE, 
messageException.getMessageReference());
-    info = "  " + info + "Messagetext: '" + ms.getText() + "contains [%";
+    aExType(ODataMessageException.class);
 
-    dout(info);
+    info = "  " + info + "Messagetext: '" + getExceptionText() + "contains [%";
+    assertFalse(info, getExceptionText().contains("[%"));
 
-    if (ms.getText().contains("[%")) {
-      fail(info);
-    }
     return this;
   }
 
@@ -229,74 +145,23 @@ public class ParserTool {
    * @return ParserTool
    */
   public ParserTool aExMsgNotEmpty() {
-    String info = "aExTextNotEmpty(" + expression + ")-->";
-    if (curException == null) {
-      fail("Error in aExMessageText: Expected exception.");
-    }
+    String info = "aExMsgNotEmpty(" + expression + ")-->";
 
-    ODataMessageException messageException;
+    aExType(ODataMessageException.class);
 
-    try {
-      messageException = (ODataMessageException) curException;
-    } catch (ClassCastException ex) {
-      fail("Error in aExNext: curException not an ODataMessageException");
-      return this;
-    }
-
-    Message ms = MessageService.getMessage(DEFAULT_LANGUAGE, 
messageException.getMessageReference());
     info = "  " + info + "check if Messagetext is empty";
-    dout(info);
+    assertFalse(info, getExceptionText().isEmpty());
 
-    if (ms.getText().length() == 0) {
-      fail(info);
-    }
     return this;
   }
 
   public ParserTool aExKey(final MessageReference expressionExpectedAtPos) {
-    String expectedKey = expressionExpectedAtPos.getKey();
-    ODataMessageException messageException;
-
     String info = "GetExceptionType(" + expression + ")-->";
 
-    if (curException == null) {
-      fail("Error in aExType: Expected exception");
-    }
-
-    try {
-      messageException = (ODataMessageException) curException;
-    } catch (ClassCastException ex) {
-      fail("Error in aExNext: curException not an ODataMessageException");
-      return this;
-    }
-
-    String actualKey = messageException.getMessageReference().getKey();
-    dout("  " + info + "Expected key: " + expectedKey + " Actual: " + 
actualKey);
-
-    if (expectedKey != actualKey) {
-      fail("  " + info + "Expected: " + expectedKey + " Actual: " + actualKey);
-    }
-    return this;
-  }
-
-  public ParserTool printExMessage() {
-    ODataMessageException messageException;
-    if (curException == null) {
-      fail("Error in aExMsgPrint: Expected exception");
-    }
-
-    try {
-      messageException = (ODataMessageException) curException;
-    } catch (ClassCastException ex) {
-      fail("Error in aExNext: curException not an ODataMessageException");
-      return this;
-    }
-
-    Message ms = MessageService.getMessage(DEFAULT_LANGUAGE, 
messageException.getMessageReference());
-    out("Messge --> ");
-    out("  " + ms.getText());
-    out("Messge <-- ");
+    aExType(ODataMessageException.class);
 
+    assertEquals(info, expressionExpectedAtPos.getKey(),
+        ((ODataMessageException) curException).getMessageReference().getKey());
     return this;
   }
 
@@ -305,62 +170,13 @@ public class ParserTool {
     Message ms = MessageService.getMessage(DEFAULT_LANGUAGE, 
messageException.getMessageReference());
 
     return ms.getText();
-
-  }
-
-  public ParserTool printSerialized() {
-    String actual = null;
-    ExpressionVisitor visitor = new VisitorTool();
-    try {
-      actual = tree.accept(visitor).toString();
-    } catch (ExceptionVisitExpression e) {
-      fail("Error in visitor:" + e.getLocalizedMessage());
-    } catch (ODataApplicationException e) {
-      fail("Error in visitor:" + e.getLocalizedMessage());
-    }
-
-    out("Messge --> ");
-    out("  " + actual);
-    out("Messge <-- ");
-    return this;
-  }
-
-  public ParserTool exPrintStack() {
-    curException.printStackTrace();
-    return this;
-  }
-
-  public ParserTool exNext() {
-    try {
-      curException = (Exception) curException.getCause();
-    } catch (ClassCastException ex) {
-      fail("Error in aExNext: Cause not an Exception");
-    }
-    return this;
-  }
-
-  private void checkNoException(final String infoMethod) {
-    if (curException != null) {
-      fail("Error in " + infoMethod + ": exception '" + getExceptionText() + 
"' occured!");
-    }
   }
 
   public ParserTool aEdmType(final EdmType type) {
-    checkNoException("aEdmType");
+    assertNull("aEdmType", curException);
     String info = "GetEdmType(" + expression + ")-->";
 
-    try {
-      if (curNode.getEdmType() == null) {
-        dout("  " + info + "Expected: " + type.getName() + " Actual: " + 
"null");
-        fail("Error in aEdmType: type of curNode is null");
-      }
-
-      dout("  " + info + "Expected: " + type.getName() + " Actual: " + 
curNode.getEdmType().getName());
-
-    } catch (EdmException e) {
-      fail("Error in aEdmType:" + e.getLocalizedMessage());
-    }
-
+    assertNotNull(curNode.getEdmType());
     assertEquals(info, type, curNode.getEdmType());
     return this;
   }
@@ -368,59 +184,26 @@ public class ParserTool {
   public ParserTool aSortOrder(final SortOrder orderType) {
     String info = "GetSortOrder(" + expression + ")-->";
 
-    if (curNode.getKind() != ExpressionKind.ORDER) {
-      String out = info + "Expected: " + ExpressionKind.ORDER + " Actual: " + 
curNode.getKind().toString();
-      dout("  " + out);
-      fail(out);
-    }
-
-    OrderExpressionImpl orderExpression = (OrderExpressionImpl) curNode;
-    dout("  " + info + "Expected: " + orderType.toString() + " Actual: " + 
orderExpression.getSortOrder().toString());
-
-    assertEquals(info, orderType, orderExpression.getSortOrder());
+    aKind(ExpressionKind.ORDER);
+    assertEquals(info, orderType, ((OrderExpressionImpl) 
curNode).getSortOrder());
     return this;
   }
 
   public ParserTool aExpr() {
     String info = "GetExpr(" + expression + ")-->";
 
-    if ((curNode.getKind() != ExpressionKind.ORDER) && (curNode.getKind() != 
ExpressionKind.FILTER)) {
-      String out =
-          info + "Expected: " + ExpressionKind.ORDER + " or " + 
ExpressionKind.FILTER + " Actual: "
-              + curNode.getKind().toString();
-      dout("  " + out);
-      fail(out);
-    }
-
-    if (curNode.getKind() == ExpressionKind.FILTER) {
-      FilterExpressionImpl filterExpression = (FilterExpressionImpl) curNode;
-      curNode = filterExpression.getExpression();
-    } else {
-      OrderExpressionImpl orderByExpression = (OrderExpressionImpl) curNode;
-      curNode = orderByExpression.getExpression();
-    }
+    aKind(ExpressionKind.ORDER);
+    curNode = ((OrderExpressionImpl) curNode).getExpression();
+    assertNotNull(info, curNode);
 
     return this;
   }
 
-  public ParserTool aEdmProperty(final EdmProperty string) {
+  public ParserTool aEdmProperty(final EdmProperty property) {
     String info = "GetEdmProperty(" + expression + ")-->";
 
-    if (curNode.getKind() != ExpressionKind.PROPERTY) {
-      String out = info + "Expected: " + ExpressionKind.PROPERTY + " Actual: " 
+ curNode.getKind().toString();
-      dout("  " + out);
-      fail(out);
-    }
-
-    PropertyExpressionImpl propertyExpression = (PropertyExpressionImpl) 
curNode;
-    try {
-      dout("  " + info + "Expected: Property'" + string.getName() + "' Actual: 
"
-          + propertyExpression.getEdmProperty().getName());
-    } catch (EdmException e) {
-      fail("Error in aEdmProperty:" + e.getLocalizedMessage());
-    }
-
-    assertEquals(info, string, propertyExpression.getEdmProperty());
+    aKind(ExpressionKind.PROPERTY);
+    assertEquals(info, property, ((PropertyExpressionImpl) 
curNode).getEdmProperty());
     return this;
   }
 
@@ -430,7 +213,7 @@ public class ParserTool {
   }
 
   public ParserTool aSerialized(final String expected) {
-    checkNoException("aSerialized");
+    assertNull("aSerialized", curException);
 
     String actual = null;
     ExpressionVisitor visitor = new VisitorTool();
@@ -443,103 +226,61 @@ public class ParserTool {
     }
 
     String info = "GetSerialized(" + expression + ")-->";
-    dout("  " + info + "Expected: " + expected + " Actual: " + actual);
-
     assertEquals(info, expected, actual);
     return this;
   }
 
   public ParserTool left() {
-    switch (curNode.getKind()) {
-    case BINARY:
+    String info = "param(" + expression + ")-->";
+
+    assertTrue(info, curNode.getKind() == ExpressionKind.BINARY
+        || curNode.getKind() == ExpressionKind.UNARY
+        || curNode.getKind() == ExpressionKind.MEMBER);
+
+    if (curNode.getKind() == ExpressionKind.BINARY) {
       curNode = ((BinaryExpressionImpl) curNode).getLeftOperand();
-      break;
-    case MEMBER:
-      curNode = ((MemberExpressionImpl) curNode).getPath();
-      break;
-    case LITERAL:
-    case METHOD:
-    case PROPERTY:
-      String info = "param(" + expression + ")-->";
-      info =
-          "  " + info + "Expected: " + ExpressionKind.BINARY.toString() + " or 
" + ExpressionKind.MEMBER.toString()
-              + " Actual: " + curNode.getKind();
-      dout(info);
-      fail(info);
-      break;
-    case UNARY:
+    } else if (curNode.getKind() == ExpressionKind.UNARY) {
       curNode = ((UnaryExpressionImpl) curNode).getOperand();
-      break;
-    default:
-      break;
+    } else if (curNode.getKind() == ExpressionKind.MEMBER) {
+      curNode = ((MemberExpressionImpl) curNode).getPath();
     }
     return this;
   }
 
   public ParserTool right() {
-    switch (curNode.getKind()) {
-    case BINARY:
+    String info = "param(" + expression + ")-->";
+
+    assertTrue(info, curNode.getKind() == ExpressionKind.BINARY
+        || curNode.getKind() == ExpressionKind.UNARY
+        || curNode.getKind() == ExpressionKind.MEMBER);
+
+    if (curNode.getKind() == ExpressionKind.BINARY) {
       curNode = ((BinaryExpressionImpl) curNode).getRightOperand();
-      break;
-    case MEMBER:
-      curNode = ((MemberExpressionImpl) curNode).getProperty();
-      break;
-    case LITERAL:
-    case METHOD:
-    case PROPERTY:
-      String info = "param(" + expression + ")-->";
-      info =
-          "  " + info + "Expected: " + ExpressionKind.BINARY.toString() + " or 
" + ExpressionKind.MEMBER.toString()
-              + " Actual: " + curNode.getKind();
-      dout(info);
-      fail(info);
-      break;
-    case UNARY:
+    } else if (curNode.getKind() == ExpressionKind.UNARY) {
       curNode = ((UnaryExpressionImpl) curNode).getOperand();
-      break;
-    default:
-      break;
+    } else if (curNode.getKind() == ExpressionKind.MEMBER) {
+      curNode = ((MemberExpressionImpl) curNode).getProperty();
     }
     return this;
   }
 
   public ParserTool order(final int i) {
-    if (curNode.getKind() != ExpressionKind.ORDERBY) {
-      String info = "param(" + expression + ")-->";
-      info = "  " + info + "Expected: " + ExpressionKind.ORDERBY.toString() + 
" Actual: " + curNode.getKind();
-      dout(info);
-      fail(info);
-    }
+    String info = "param(" + expression + ")-->";
+    aKind(ExpressionKind.ORDERBY);
 
     OrderByExpressionImpl orderByExpressionImpl = (OrderByExpressionImpl) 
curNode;
-    if (i >= orderByExpressionImpl.getOrdersCount()) {
-      String info = "param(" + expression + ")-->";
-      info = "  " + info + "Too wrong index! Expected max: " + 
orderByExpressionImpl.getOrdersCount() + " Actual: " + i;
-      dout(info);
-      fail(info);
-    }
+    assertTrue(info, i < orderByExpressionImpl.getOrdersCount());
 
     curNode = orderByExpressionImpl.getOrders().get(i);
     return this;
-
   }
 
   public ParserTool param(final int i) {
-    if (curNode.getKind() != ExpressionKind.METHOD) {
-      String info = "param(" + expression + ")-->";
-      info = "  " + info + "Expected: " + ExpressionKind.METHOD.toString() + " 
Actual: " + curNode.getKind();
-      dout(info);
-      fail(info);
-    }
+    String info = "param(" + expression + ")-->";
+    aKind(ExpressionKind.METHOD);
 
     MethodExpressionImpl methodExpressionImpl = (MethodExpressionImpl) curNode;
-    if (i >= methodExpressionImpl.getParameterCount()) {
-      String info = "param(" + expression + ")-->";
-      info =
-          "  " + info + "Too wrong index! Expected max: " + 
methodExpressionImpl.getParameterCount() + " Actual: " + i;
-      dout(info);
-      fail(info);
-    }
+    assertTrue(info, i < methodExpressionImpl.getParameterCount());
 
     curNode = methodExpressionImpl.getParameters().get(i);
     return this;
@@ -569,7 +310,7 @@ public class ParserTool {
   public static class testParserTool {
     @Test
     public void testCompr() {
-      // leading and trainling spaces
+      // leading and trailing spaces
       assertEquals("Error in parsertool", compress("   a"), "a");
       assertEquals("Error in parsertool", compress("a    "), "a");
       assertEquals("Error in parsertool", compress("   a    "), "a");
@@ -588,9 +329,4 @@ public class ParserTool {
       assertEquals("Error in parsertool", compress("   {   a { }  a   }   "), 
"{a {} a}");
     }
   }
-
-  public ParserTool exRoot() {
-    return this;
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/919d4ac0/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestBase.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestBase.java
 
b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestBase.java
index 5a636fe..cdb92a3 100644
--- 
a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestBase.java
+++ 
b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestBase.java
@@ -37,15 +37,15 @@ public class TestBase {
   }
 
   static public ParserTool GetPTF(final String expression) {
-    return new ParserTool(expression, false, true, false);
+    return new ParserTool(expression, false, true, false, null);
   }
 
   static public ParserTool GetPTF_onlyBinary(final String expression) {
-    return new ParserTool(expression, false, true, true);
+    return new ParserTool(expression, false, true, true, null);
   }
 
   static public ParserTool GetPTFE(final String expression) {
-    return new ParserTool(expression, false, true, false);
+    return new ParserTool(expression, false, true, false, null);
   }
 
   static public ParserTool GetPTF(final EdmEntityType resourceEntityType, 
final String expression) {
@@ -53,7 +53,7 @@ public class TestBase {
   }
 
   static public ParserTool GetPTO(final String expression) {
-    return new ParserTool(expression, true, true, false);
+    return new ParserTool(expression, true, true, false, null);
   }
 
   static public ParserTool GetPTO(final EdmEntityType resourceEntityType, 
final String expression) {
@@ -61,7 +61,7 @@ public class TestBase {
   }
 
   static public ParserTool GetPTF_noTEST(final String expression) {
-    return new ParserTool(expression, false, false, false);
+    return new ParserTool(expression, false, false, false, null);
   }
 
   static public ParserTool GetPTF_noTEST(final EdmEntityType 
resourceEntityType, final String expression) {
@@ -69,7 +69,7 @@ public class TestBase {
   }
 
   static public ParserTool GetPTO_noTEST(final String expression) {
-    return new ParserTool(expression, true, false, true);
+    return new ParserTool(expression, true, false, true, null);
   }
 
   static public ParserTool GetPTO_noTEST(final EdmEntityType 
resourceEntityType, final String expression) {

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/919d4ac0/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestParser.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestParser.java
 
b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestParser.java
index 84a48e8..bbec5d9 100644
--- 
a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestParser.java
+++ 
b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/expression/TestParser.java
@@ -18,15 +18,8 @@
  
******************************************************************************/
 package org.apache.olingo.odata2.core.uri.expression;
 
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 import org.apache.olingo.odata2.api.edm.EdmComplexType;
 import org.apache.olingo.odata2.api.edm.EdmEntityType;
-import org.apache.olingo.odata2.api.edm.EdmException;
 import org.apache.olingo.odata2.api.edm.EdmProperty;
 import org.apache.olingo.odata2.api.edm.EdmSimpleType;
 import org.apache.olingo.odata2.api.uri.expression.ExpressionKind;
@@ -44,6 +37,7 @@ import org.apache.olingo.odata2.core.edm.EdmGuid;
 import org.apache.olingo.odata2.core.edm.EdmInt16;
 import org.apache.olingo.odata2.core.edm.EdmInt32;
 import org.apache.olingo.odata2.core.edm.EdmInt64;
+import org.apache.olingo.odata2.core.edm.EdmNull;
 import org.apache.olingo.odata2.core.edm.EdmSByte;
 import org.apache.olingo.odata2.core.edm.EdmSingle;
 import org.apache.olingo.odata2.core.edm.EdmString;
@@ -58,39 +52,39 @@ import org.junit.Test;
 public class TestParser extends TestBase {
 
   @Test
-  public void testQuick() {
+  public void quick() {
     GetPTF("substring('Test', 1 add 2)").aSerialized("{substring('Test',{1 add 
2})}");
   }
 
   @Test
-  public void testOrderBy() {
+  public void orderBy() {
 
-    GetPTO("sven").aSerialized("{oc({o(sven, asc)})}");
-    GetPTO("sven asc").aSerialized("{oc({o(sven, asc)})}");
-    GetPTO("sven desc").aSerialized("{oc({o(sven, desc)})}");
-    GetPTO("sven     asc").aSerialized("{oc({o(sven, asc)})}");
-    GetPTO("sven     desc").aSerialized("{oc({o(sven, desc)})}");
+    GetPTO("name").aSerialized("{oc({o(name, asc)})}");
+    GetPTO("name asc").aSerialized("{oc({o(name, asc)})}");
+    GetPTO("name desc").aSerialized("{oc({o(name, desc)})}");
+    GetPTO("name     asc").aSerialized("{oc({o(name, asc)})}");
+    GetPTO("name     desc").aSerialized("{oc({o(name, desc)})}");
 
-    GetPTO("sven, test").aSerialized("{oc({o(sven, asc)},{o(test, asc)})}");
-    GetPTO("sven   ,    test").aSerialized("{oc({o(sven, asc)},{o(test, 
asc)})}");
+    GetPTO("name, test").aSerialized("{oc({o(name, asc)},{o(test, asc)})}");
+    GetPTO("name   ,    test").aSerialized("{oc({o(name, asc)},{o(test, 
asc)})}");
 
-    GetPTO("sven, test asc").aSerialized("{oc({o(sven, asc)},{o(test, 
asc)})}");
+    GetPTO("name, test asc").aSerialized("{oc({o(name, asc)},{o(test, 
asc)})}");
 
-    GetPTO("sven asc, test").aSerialized("{oc({o(sven, asc)},{o(test, 
asc)})}");
+    GetPTO("name asc, test").aSerialized("{oc({o(name, asc)},{o(test, 
asc)})}");
 
-    GetPTO("sven asc, test asc").aSerialized("{oc({o(sven, asc)},{o(test, 
asc)})}");
-    GetPTO("sven, test desc").aSerialized("{oc({o(sven, asc)},{o(test, 
desc)})}");
-    GetPTO("sven desc, test").aSerialized("{oc({o(sven, desc)},{o(test, 
asc)})}");
-    GetPTO("sven desc, test desc").aSerialized("{oc({o(sven, desc)},{o(test, 
desc)})}");
+    GetPTO("name asc, test asc").aSerialized("{oc({o(name, asc)},{o(test, 
asc)})}");
+    GetPTO("name, test desc").aSerialized("{oc({o(name, asc)},{o(test, 
desc)})}");
+    GetPTO("name desc, test").aSerialized("{oc({o(name, desc)},{o(test, 
asc)})}");
+    GetPTO("name desc, test desc").aSerialized("{oc({o(name, desc)},{o(test, 
desc)})}");
 
-    GetPTO("'sven', 77").order(1).aSortOrder(SortOrder.asc);
-    GetPTO("'sven', 77 
desc").root().order(0).aSortOrder(SortOrder.asc).aExpr().aEdmType(EdmString.getInstance())
+    GetPTO("'name', 77").order(1).aSortOrder(SortOrder.asc);
+    GetPTO("'name', 77 
desc").root().order(0).aSortOrder(SortOrder.asc).aExpr().aEdmType(EdmString.getInstance())
         
.root().order(1).aSortOrder(SortOrder.desc).aExpr().aEdmType(Uint7.getInstance());
 
   }
 
   @Test
-  public void testPromotion() {
+  public void promotion() {
     // SByte <--> SByte
     GetPTF("-10").aEdmType(EdmSByte.getInstance());
     GetPTF("-10 add -10").aEdmType(EdmSByte.getInstance());
@@ -126,17 +120,16 @@ public class TestParser extends TestBase {
     GetPTF("concat('a','b')").aEdmType(EdmString.getInstance());
     GetPTF("concat('a','b','c')").aEdmType(EdmString.getInstance());
   }
-  
-   @Test
-  public void testProperties() {
-    // GetPTF("sven").aSerialized("sven").aKind(ExpressionKind.PROPERTY);
-    GetPTF("sven1 add sven2").aSerialized("{sven1 add 
sven2}").aKind(ExpressionKind.BINARY).root().left().aKind(
-        
ExpressionKind.PROPERTY).aUriLiteral("sven1").root().right().aKind(ExpressionKind.PROPERTY)
-        .aUriLiteral("sven2");
+
+  @Test
+  public void properties() {
+    GetPTF("name1 add name2").aSerialized("{name1 add 
name2}").aKind(ExpressionKind.BINARY).root().left().aKind(
+        
ExpressionKind.PROPERTY).aUriLiteral("name1").root().right().aKind(ExpressionKind.PROPERTY)
+        .aUriLiteral("name2");
   }
 
   @Test
-  public void testDeepProperties() {
+  public void deepProperties() {
     GetPTF("a/b").aSerialized("{a/b}").aKind(ExpressionKind.MEMBER);
     
GetPTF("a/b/c").aSerialized("{{a/b}/c}").root().aKind(ExpressionKind.MEMBER).root().left().aKind(
         
ExpressionKind.MEMBER).root().left().left().aKind(ExpressionKind.PROPERTY).aUriLiteral("a").root().left()
@@ -145,88 +138,79 @@ public class TestParser extends TestBase {
   }
 
   @Test
-  public void testPropertiesWithEdm() {
-    try {
-      EdmEntityType edmEtAllTypes = edmInfo.getTypeEtAllTypes();
-      EdmProperty string = (EdmProperty) edmEtAllTypes.getProperty("String");
-      EdmSimpleType stringType = (EdmSimpleType) string.getType();
-      EdmComplexPropertyImplProv complex = (EdmComplexPropertyImplProv) 
edmEtAllTypes.getProperty("Complex");
-      EdmComplexType complexType = (EdmComplexType) complex.getType();
-      EdmProperty complexString = (EdmProperty) 
complexType.getProperty("String");
-      EdmSimpleType complexStringType = (EdmSimpleType) 
complexString.getType();
-      EdmComplexPropertyImplProv complexAddress = (EdmComplexPropertyImplProv) 
complexType.getProperty("Address");
-      EdmComplexType complexAddressType = (EdmComplexType) 
complexAddress.getType();
-      EdmProperty complexAddressCity = (EdmProperty) 
complexAddressType.getProperty("City");
-      EdmSimpleType complexAddressCityType = (EdmSimpleType) 
complexAddressCity.getType();
-
-      GetPTF(edmEtAllTypes, 
"String").aEdmProperty(string).aEdmType(stringType);
-
-      GetPTF(edmEtAllTypes, "'text' eq 
String").root().aKind(ExpressionKind.BINARY);
-
-      GetPTF(edmEtAllTypes, 
"Complex/String").root().left().aEdmProperty(complex).aEdmType(complexType).root().right()
-          
.aEdmProperty(complexString).aEdmType(complexStringType).root().aKind(ExpressionKind.MEMBER).aEdmType(
-              complexStringType);
-
-      GetPTF(edmEtAllTypes, 
"Complex/Address/City").root().aKind(ExpressionKind.MEMBER).root().left().aKind(
-          
ExpressionKind.MEMBER).root().left().left().aKind(ExpressionKind.PROPERTY).aEdmProperty(complex).aEdmType(
-          
complexType).root().left().right().aKind(ExpressionKind.PROPERTY).aEdmProperty(complexAddress).aEdmType(
-          
complexAddressType).root().left().aEdmType(complexAddressType).root().right().aKind(ExpressionKind.PROPERTY)
-          
.aEdmProperty(complexAddressCity).aEdmType(complexAddressCityType).root().aEdmType(complexAddressCityType);
-
-      EdmProperty boolean_ = (EdmProperty) 
edmEtAllTypes.getProperty("Boolean");
-      EdmSimpleType boolean_Type = (EdmSimpleType) boolean_.getType();
-
-      GetPTF(edmEtAllTypes, "not 
Boolean").aKind(ExpressionKind.UNARY).aEdmType(boolean_Type).right().aEdmProperty(
-          boolean_).aEdmType(boolean_Type);
-
-    } catch (EdmException e) {
-      fail("Error in testPropertiesWithEdm:" + e.getLocalizedMessage());
-      e.printStackTrace();
-    }
+  public void propertiesWithEdm() throws Exception {
+    EdmEntityType edmEtAllTypes = edmInfo.getTypeEtAllTypes();
+    EdmProperty string = (EdmProperty) edmEtAllTypes.getProperty("String");
+    EdmSimpleType stringType = (EdmSimpleType) string.getType();
+    EdmComplexPropertyImplProv complex = (EdmComplexPropertyImplProv) 
edmEtAllTypes.getProperty("Complex");
+    EdmComplexType complexType = (EdmComplexType) complex.getType();
+    EdmProperty complexString = (EdmProperty) 
complexType.getProperty("String");
+    EdmSimpleType complexStringType = (EdmSimpleType) complexString.getType();
+    EdmComplexPropertyImplProv complexAddress = (EdmComplexPropertyImplProv) 
complexType.getProperty("Address");
+    EdmComplexType complexAddressType = (EdmComplexType) 
complexAddress.getType();
+    EdmProperty complexAddressCity = (EdmProperty) 
complexAddressType.getProperty("City");
+    EdmSimpleType complexAddressCityType = (EdmSimpleType) 
complexAddressCity.getType();
+
+    GetPTF(edmEtAllTypes, "String").aEdmProperty(string).aEdmType(stringType);
+
+    GetPTF(edmEtAllTypes, "'text' eq 
String").root().aKind(ExpressionKind.BINARY);
+
+    GetPTF(edmEtAllTypes, 
"Complex/String").root().left().aEdmProperty(complex).aEdmType(complexType).root().right()
+        
.aEdmProperty(complexString).aEdmType(complexStringType).root().aKind(ExpressionKind.MEMBER).aEdmType(
+            complexStringType);
+
+    GetPTF(edmEtAllTypes, 
"Complex/Address/City").root().aKind(ExpressionKind.MEMBER).root().left().aKind(
+        
ExpressionKind.MEMBER).root().left().left().aKind(ExpressionKind.PROPERTY).aEdmProperty(complex).aEdmType(
+            complexType)
+        
.root().left().right().aKind(ExpressionKind.PROPERTY).aEdmProperty(complexAddress).aEdmType(
+            complexAddressType)
+        
.root().left().aEdmType(complexAddressType).root().right().aKind(ExpressionKind.PROPERTY)
+        
.aEdmProperty(complexAddressCity).aEdmType(complexAddressCityType).root().aEdmType(complexAddressCityType);
+
+    EdmProperty boolean_ = (EdmProperty) edmEtAllTypes.getProperty("Boolean");
+    EdmSimpleType boolean_Type = (EdmSimpleType) boolean_.getType();
+
+    GetPTF(edmEtAllTypes, "not 
Boolean").aKind(ExpressionKind.UNARY).aEdmType(boolean_Type).right().aEdmProperty(
+        boolean_).aEdmType(boolean_Type);
   }
 
   @Test
-  public void testSimpleMethod() {
+  public void simpleMethod() {
     GetPTF("startswith('Test','Te')").aSerialized("{startswith('Test','Te')}");
-
-    GetPTF("startswith('Test','Te')").aSerialized("{startswith('Test','Te')}");
-
     GetPTF("startswith('Test', 
concat('A','B'))").aSerialized("{startswith('Test',{concat('A','B')})}");
-
     GetPTF("substring('Test', 1 add 2)").aSerialized("{substring('Test',{1 add 
2})}");
   }
 
   @Test
-  public void testMethodVariableParameters() {
+  public void methodVariableParameters() {
     GetPTF("concat('Test', 'A' )").aSerialized("{concat('Test','A')}");
     GetPTF("concat('Test', 'A', 'B' 
)").aSerialized("{concat('Test','A','B')}");
     GetPTF("concat('Test', 'A', 'B', 'C' 
)").aSerialized("{concat('Test','A','B','C')}");
   }
 
   @Test
-  public void testSimpleSameBinary() {
+  public void simpleSameBinary() {
     GetPTF("1d add 2d").aSerialized("{1d add 2d}");
     GetPTF("1d div 2d").aSerialized("{1d div 2d}");
 
     GetPTF("1d add 2d").aSerialized("{1d add 
2d}").aKind(ExpressionKind.BINARY).root().left().aKind(
         ExpressionKind.LITERAL).root().right().aKind(ExpressionKind.LITERAL);
-
   }
 
   @Test
-  public void testSimpleSameBinaryBinary() {
+  public void simpleSameBinaryBinary() {
     GetPTF("1d add 2d add 3d").aSerialized("{{1d add 2d} add 3d}");
     GetPTF("1d div 2d div 3d").aSerialized("{{1d div 2d} div 3d}");
   }
 
   @Test
-  public void testSimpleSameBinaryBinaryPriority() {
+  public void simpleSameBinaryBinaryPriority() {
     GetPTF("1d add 2d div 3d").aSerialized("{1d add {2d div 3d}}");
     GetPTF("1d div 2d add 3d").aSerialized("{{1d div 2d} add 3d}");
   }
 
   @Test
-  public void testSimpleSameBinaryBinaryBinaryPriority() {
+  public void simpleSameBinaryBinaryBinaryPriority() {
     GetPTF("1d add 2d add 3d add 4d").aSerialized("{{{1d add 2d} add 3d} add 
4d}");
     GetPTF("1d add 2d add 3d div 4d").aSerialized("{{1d add 2d} add {3d div 
4d}}");
     GetPTF("1d add 2d div 3d add 4d").aSerialized("{{1d add {2d div 3d}} add 
4d}");
@@ -238,7 +222,7 @@ public class TestParser extends TestBase {
   }
 
   @Test
-  public void testComplexMixedPriority() {
+  public void complexMixedPriority() {
     GetPTF("a      or c      and e     ").aSerializedCompr("{ a       or { c   
    and  e      }}");
     GetPTF("a      or c      and e eq f").aSerializedCompr("{ a       or { c   
    and {e eq f}}}");
     GetPTF("a      or c eq d and e     ").aSerializedCompr("{ a       or {{c 
eq d} and  e      }}");
@@ -253,7 +237,7 @@ public class TestParser extends TestBase {
   }
 
   @Test
-  public void testDeepParenthesis() {
+  public void deepParenthesis() {
     GetPTF("2d").aSerialized("2d");
     GetPTF("(2d)").aSerialized("2d");
     GetPTF("((2d))").aSerialized("2d");
@@ -261,7 +245,7 @@ public class TestParser extends TestBase {
   }
 
   @Test
-  public void testParenthesisWithBinaryBinary() {
+  public void parenthesisWithBinaryBinary() {
     GetPTF("1d add 2d add 3d").aSerialized("{{1d add 2d} add 3d}");
     GetPTF("1d add (2d add 3d)").aSerialized("{1d add {2d add 3d}}");
     GetPTF("(1d add 2d) add 3d").aSerialized("{{1d add 2d} add 3d}");
@@ -279,7 +263,7 @@ public class TestParser extends TestBase {
   }
 
   @Test
-  public void testSimpleUnaryOperator() {
+  public void simpleUnaryOperator() {
     GetPTF("not true").aSerialized("{not true}");
     GetPTF("- 2d").aSerialized("{- 2d}");
 
@@ -291,7 +275,7 @@ public class TestParser extends TestBase {
   }
 
   @Test
-  public void testDeepUnaryOperator() {
+  public void deepUnaryOperator() {
     GetPTF("not not true").aSerialized("{not {not true}}");
     GetPTF("not not not true").aSerialized("{not {not {not true}}}");
     GetPTF("-- 2d").aSerialized("{- {- 2d}}");
@@ -304,19 +288,19 @@ public class TestParser extends TestBase {
   }
 
   @Test
-  public void testMixedUnaryOperators() {
+  public void mixedUnaryOperators() {
     GetPTF("not - true").aSerialized("{not {- true}}");
     GetPTF("- not true").aSerialized("{- {not true}}");
   }
 
   @Test
-  public void testDeepMixedUnaryOperators() {
+  public void deepMixedUnaryOperators() {
     GetPTF("- not - true").aSerialized("{- {not {- true}}}");
     GetPTF("not - not true").aSerialized("{not {- {not true}}}");
   }
 
   @Test
-  public void testString() {
+  public void strings() {
     GetPTF("'TEST'").aSerialized("'TEST'");
     //old GetPTF("'TE''ST'").aSerialized("'TE'ST'");
     GetPTF("'TE''ST'").aSerialized("'TE''ST'");
@@ -325,7 +309,7 @@ public class TestParser extends TestBase {
   }
 
   @Test
-  public void testSinglePlainLiterals() {
+  public void singlePlainLiterals() {
     // assertEquals("Hier", 44, 33);
     // ---
     // Checks from EdmSimpleType test
@@ -398,53 +382,28 @@ public class TestParser extends TestBase {
 
     
GetPTF("'abc'").aUriLiteral("'abc'").aKind(ExpressionKind.LITERAL).aEdmType(stringInst);
     
GetPTF("time'PT120S'").aUriLiteral("time'PT120S'").aKind(ExpressionKind.LITERAL).aEdmType(timeInst);
-
-    // The EdmSimpleTypeSamples contains a well formatted list of all
-    // possible
-    // UriLiterals for SimpleTypes, instances for their Type classes and
-    // their Values in java notation
-    /*
-     * for ( EdmSimpleTypeSamples.UriTypeValueSet [] utvSetSet :
-     * EdmSimpleTypeSamples.someAll ) { for(
-     * EdmSimpleTypeSamples.UriTypeValueSet utvSet : utvSetSet) {
-     * GetPTF(utvSet
-     * .uri).aKind(ExpressionKind.LITERAL).aEdmType(utvSet.type)
-     * .aUriLiteral(utvSet.uri); } }
-     */
-
-  }
-
-  ExpressionParserException GetException() {
-    ExpressionParserException ex = new 
ExpressionParserException(ExpressionParserException.COMMON_ERROR);
-    List<StackTraceElement> stack = new 
ArrayList<StackTraceElement>(Arrays.asList(ex.getStackTrace()));
-    stack.remove(0);
-    ex.setStackTrace(stack.toArray(new StackTraceElement[stack.size()]));
-    return ex;
-  }
-
-  void LevelB() throws ExpressionParserException {
-    ExpressionParserException ex = GetException();
-    throw ex;
-  }
-
-  void LevelA() throws ExpressionParserException {
-    try {
-      LevelB();
-    } catch (ExpressionParserException e) {
-      e.printStackTrace();
-      throw e;
-      // throw new
-      // ExceptionParseExpression(ExceptionParseExpression.COMMON);
-    }
   }
 
-  // @Test
-  public void testExceptionStack() {
-    try {
-      LevelA();
-    } catch (ExpressionParserException e) {
-      e.printStackTrace();
-    }
+  @Test
+  public void navigationProperties() {
+    final EdmEntityType entityType = edmInfo.getTypeEtKeyTypeInteger();
+    final EdmEntityType entityType2 = edmInfo.getTypeEtKeyTypeString();
+    GetPTF_noTEST(entityType, 
"navProperty").aExKey(ExpressionParserException.TYPE_EXPECTED_AT);
+    GetPTF_noTEST(entityType, 
"navProperty/navProperty").aExKey(ExpressionParserException.INVALID_MULTIPLICITY);
+    GetPTF_noTEST(entityType, "navProperty/KeyString eq 'a'")
+        .root().left().left().aEdmType(entityType2)
+        .root().left().right().aEdmType(EdmString.getInstance());
+    GetPTF_noTEST(entityType2, "navProperty/KeyInteger eq 
1").aExKey(ExpressionParserException.INVALID_MULTIPLICITY);
+    GetPTF_noTEST(entityType, "navProperty ne 
null").root().left().aEdmType(entityType2);
+    GetPTF_noTEST(entityType, "navProperty ne null and not (navProperty eq 
null)")
+        .root().aKind(ExpressionKind.BINARY)
+        .left().aKind(ExpressionKind.BINARY).left().aEdmType(entityType2)
+        .root().left().right().aEdmType(EdmNull.getInstance())
+        
.root().right().aKind(ExpressionKind.UNARY).left().aKind(ExpressionKind.BINARY)
+        .left().aEdmType(entityType2)
+        .root().right().left().right().aEdmType(EdmNull.getInstance());
+    GetPTF_noTEST(entityType2, "navProperty eq 
null").aExKey(ExpressionParserException.INVALID_MULTIPLICITY);
+    GetPTF_noTEST(entityType, "navProperty lt null")
+        .aExKey(ExpressionParserException.INVALID_TYPES_FOR_BINARY_OPERATOR);
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/919d4ac0/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ListsProcessor.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ListsProcessor.java
 
b/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ListsProcessor.java
index fb48d5f..a64ab9a 100644
--- 
a/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ListsProcessor.java
+++ 
b/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ListsProcessor.java
@@ -317,17 +317,16 @@ public class ListsProcessor extends ODataSingleProcessor {
         mapFunctionParameters(uriInfo.getFunctionImportParameters()),
         uriInfo.getNavigationSegments());
 
-    if (!appliesFilter(data, uriInfo.getFilter())) {
+    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+    if (!appliesFilter(entitySet, data, uriInfo.getFilter())) {
       throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
     }
 
     final ExpandSelectTreeNode expandSelectTreeNode =
         UriParser.createExpandSelectTree(uriInfo.getSelect(), 
uriInfo.getExpand());
-    ODataResponse odr =
-        ODataResponse.fromResponse(writeEntry(uriInfo.getTargetEntitySet(), 
expandSelectTreeNode, data, contentType))
-            .build();
 
-    return odr;
+    return ODataResponse.fromResponse(writeEntry(entitySet, 
expandSelectTreeNode, data, contentType))
+        .build();
   }
 
   @Override
@@ -340,7 +339,8 @@ public class ListsProcessor extends ODataSingleProcessor {
         mapFunctionParameters(uriInfo.getFunctionImportParameters()),
         uriInfo.getNavigationSegments());
 
-    return 
ODataResponse.fromResponse(EntityProvider.writeText(appliesFilter(data, 
uriInfo.getFilter()) ? "1" : "0"))
+    return ODataResponse.fromResponse(EntityProvider.writeText(
+        appliesFilter(uriInfo.getTargetEntitySet(), data, uriInfo.getFilter()) 
? "1" : "0"))
         .build();
   }
 
@@ -411,11 +411,11 @@ public class ListsProcessor extends ODataSingleProcessor {
         mapFunctionParameters(uriInfo.getFunctionImportParameters()),
         uriInfo.getNavigationSegments());
 
-    if (!appliesFilter(data, uriInfo.getFilter())) {
+    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+    if (!appliesFilter(entitySet, data, uriInfo.getFilter())) {
       throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
     }
 
-    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
     final EdmEntityType entityType = entitySet.getEntityType();
     final EntityProviderReadProperties properties = 
EntityProviderReadProperties.init()
         .mergeSemantic(merge)
@@ -543,7 +543,7 @@ public class ListsProcessor extends ODataSingleProcessor {
 
     final Object targetData = dataSource.readRelatedData(entitySet, 
sourceData, targetEntitySet, keys);
 
-    if (!appliesFilter(targetData, uriInfo.getFilter())) {
+    if (!appliesFilter(targetEntitySet, targetData, uriInfo.getFilter())) {
       throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
     }
 
@@ -652,7 +652,7 @@ public class ListsProcessor extends ODataSingleProcessor {
         mapFunctionParameters(uriInfo.getFunctionImportParameters()),
         uriInfo.getNavigationSegments());
 
-    if (!appliesFilter(data, uriInfo.getFilter())) {
+    if (!appliesFilter(uriInfo.getTargetEntitySet(), data, 
uriInfo.getFilter())) {
       throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
     }
 
@@ -704,7 +704,7 @@ public class ListsProcessor extends ODataSingleProcessor {
         mapFunctionParameters(uriInfo.getFunctionImportParameters()),
         uriInfo.getNavigationSegments());
 
-    if (!appliesFilter(data, uriInfo.getFilter())) {
+    if (!appliesFilter(uriInfo.getTargetEntitySet(), data, 
uriInfo.getFilter())) {
       throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
     }
 
@@ -741,11 +741,11 @@ public class ListsProcessor extends ODataSingleProcessor {
         mapFunctionParameters(uriInfo.getFunctionImportParameters()),
         uriInfo.getNavigationSegments());
 
-    if (!appliesFilter(data, uriInfo.getFilter())) {
+    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+    if (!appliesFilter(entitySet, data, uriInfo.getFilter())) {
       throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
     }
 
-    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
     final BinaryData binaryData = dataSource.readBinaryData(entitySet, data);
     if (binaryData == null) {
       throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
@@ -786,7 +786,8 @@ public class ListsProcessor extends ODataSingleProcessor {
         mapFunctionParameters(uriInfo.getFunctionImportParameters()),
         uriInfo.getNavigationSegments());
 
-    if (!appliesFilter(data, uriInfo.getFilter())) {
+    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+    if (!appliesFilter(entitySet, data, uriInfo.getFilter())) {
       throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
     }
 
@@ -797,7 +798,6 @@ public class ListsProcessor extends ODataSingleProcessor {
 
     context.stopRuntimeMeasurement(timingHandle);
 
-    final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
     dataSource.writeBinaryData(entitySet, data, new BinaryData(value, 
requestContentType));
 
     return ODataResponse.newBuilder().eTag(constructETag(entitySet, 
data)).build();
@@ -1184,7 +1184,7 @@ public class ListsProcessor extends ODataSingleProcessor {
       // Remove all elements the filter does not apply for.
       // A for-each loop would not work with "remove", see Java documentation.
       for (Iterator<T> iterator = data.iterator(); iterator.hasNext();) {
-        if (!appliesFilter(iterator.next(), filter)) {
+        if (!appliesFilter(entitySet, iterator.next(), filter)) {
           iterator.remove();
         }
       }
@@ -1193,7 +1193,7 @@ public class ListsProcessor extends ODataSingleProcessor {
     final Integer count = inlineCount == InlineCount.ALLPAGES ? data.size() : 
null;
 
     if (orderBy != null) {
-      sort(data, orderBy);
+      sort(entitySet, data, orderBy);
     } else if (skipToken != null || skip != null || top != null) {
       sortInDefaultOrder(entitySet, data);
     }
@@ -1225,15 +1225,15 @@ public class ListsProcessor extends 
ODataSingleProcessor {
     return count;
   }
 
-  private <T> void sort(final List<T> data, final OrderByExpression orderBy) {
+  private <T> void sort(final EdmEntitySet entitySet, final List<T> data, 
final OrderByExpression orderBy) {
     Collections.sort(data, new Comparator<T>() {
       @Override
       public int compare(final T entity1, final T entity2) {
         try {
           int result = 0;
           for (final OrderExpression expression : orderBy.getOrders()) {
-            String first = evaluateExpression(entity1, 
expression.getExpression());
-            String second = evaluateExpression(entity2, 
expression.getExpression());
+            String first = evaluateExpression(entitySet, entity1, 
expression.getExpression());
+            String second = evaluateExpression(entitySet, entity2, 
expression.getExpression());
 
             if (first != null && second != null) {
               result = first.compareTo(second);
@@ -1272,12 +1272,14 @@ public class ListsProcessor extends 
ODataSingleProcessor {
     });
   }
 
-  private <T> boolean appliesFilter(final T data, final FilterExpression 
filter) throws ODataException {
+  private <T> boolean appliesFilter(final EdmEntitySet entitySet, final T 
data, final FilterExpression filter)
+      throws ODataException {
     ODataContext context = getContext();
     final int timingHandle = 
context.startRuntimeMeasurement(getClass().getSimpleName(), "appliesFilter");
 
     try {
-      return data != null && (filter == null || evaluateExpression(data, 
filter.getExpression()).equals("true"));
+      return data != null
+          && (filter == null || evaluateExpression(entitySet, data, 
filter.getExpression()).equals("true"));
     } catch (final RuntimeException e) {
       return false;
     } finally {
@@ -1285,11 +1287,12 @@ public class ListsProcessor extends 
ODataSingleProcessor {
     }
   }
 
-  private <T> String evaluateExpression(final T data, final CommonExpression 
expression) throws ODataException {
+  private <T> String evaluateExpression(final EdmEntitySet entitySet, final T 
data, final CommonExpression expression)
+      throws ODataException {
     switch (expression.getKind()) {
     case UNARY:
       final UnaryExpression unaryExpression = (UnaryExpression) expression;
-      final String operand = evaluateExpression(data, 
unaryExpression.getOperand());
+      final String operand = evaluateExpression(entitySet, data, 
unaryExpression.getOperand());
 
       switch (unaryExpression.getOperator()) {
       case NOT:
@@ -1302,9 +1305,9 @@ public class ListsProcessor extends ODataSingleProcessor {
 
     case BINARY:
       final BinaryExpression binaryExpression = (BinaryExpression) expression;
-      final EdmSimpleType type = (EdmSimpleType) 
binaryExpression.getLeftOperand().getEdmType();
-      final String left = evaluateExpression(data, 
binaryExpression.getLeftOperand());
-      final String right = evaluateExpression(data, 
binaryExpression.getRightOperand());
+      final EdmType type = binaryExpression.getLeftOperand().getEdmType();
+      final String left = evaluateExpression(entitySet, data, 
binaryExpression.getLeftOperand());
+      final String right = evaluateExpression(entitySet, data, 
binaryExpression.getRightOperand());
 
       switch (binaryExpression.getOperator()) {
       case ADD:
@@ -1347,9 +1350,9 @@ public class ListsProcessor extends ODataSingleProcessor {
       case OR:
         return Boolean.toString(left.equals("true") || right.equals("true"));
       case EQ:
-        return Boolean.toString(left.equals(right));
+        return Boolean.toString(left == null && right == null || 
left.equals(right));
       case NE:
-        return Boolean.toString(!left.equals(right));
+        return Boolean.toString(!(left == null && right == null || 
left.equals(right)));
       case LT:
         if (type == EdmSimpleTypeKind.String.getEdmSimpleTypeInstance()
             || type == EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()
@@ -1397,10 +1400,19 @@ public class ListsProcessor extends 
ODataSingleProcessor {
       }
 
     case PROPERTY:
-      final EdmProperty property = (EdmProperty) ((PropertyExpression) 
expression).getEdmProperty();
-      final EdmSimpleType propertyType = (EdmSimpleType) property.getType();
-      return propertyType.valueToString(valueAccess.getPropertyValue(data, 
property), EdmLiteralKind.DEFAULT,
-          property.getFacets());
+      final EdmTyped property = ((PropertyExpression) 
expression).getEdmProperty();
+      final EdmType propertyType = property.getType();
+      if (propertyType.getKind() == EdmTypeKind.ENTITY) {
+        try {
+          dataSource.readRelatedData(entitySet, data,
+              entitySet.getRelatedEntitySet((EdmNavigationProperty) property), 
null);
+        } catch (final ODataNotFoundException e) {
+          return null;
+        }
+        return property.getName();
+      }
+      return ((EdmSimpleType) 
propertyType).valueToString(valueAccess.getPropertyValue(data, (EdmProperty) 
property),
+          EdmLiteralKind.DEFAULT, ((EdmProperty) property).getFacets());
 
     case MEMBER:
       final MemberExpression memberExpression = (MemberExpression) expression;
@@ -1436,11 +1448,11 @@ public class ListsProcessor extends 
ODataSingleProcessor {
 
     case METHOD:
       final MethodExpression methodExpression = (MethodExpression) expression;
-      final String first = evaluateExpression(data, 
methodExpression.getParameters().get(0));
+      final String first = evaluateExpression(entitySet, data, 
methodExpression.getParameters().get(0));
       final String second = methodExpression.getParameterCount() > 1 ?
-          evaluateExpression(data, methodExpression.getParameters().get(1)) : 
"";
+          evaluateExpression(entitySet, data, 
methodExpression.getParameters().get(1)) : "";
       final String third = methodExpression.getParameterCount() > 2 ?
-          evaluateExpression(data, methodExpression.getParameters().get(2)) : 
"";
+          evaluateExpression(entitySet, data, 
methodExpression.getParameters().get(2)) : "";
 
       switch (methodExpression.getMethod()) {
         case ENDSWITH:

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/919d4ac0/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/mock/TecEdmInfo.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/mock/TecEdmInfo.java
 
b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/mock/TecEdmInfo.java
index 4592ee3..e3da2dd 100644
--- 
a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/mock/TecEdmInfo.java
+++ 
b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/mock/TecEdmInfo.java
@@ -23,6 +23,7 @@ import static org.junit.Assert.fail;
 import org.apache.olingo.odata2.api.edm.Edm;
 import org.apache.olingo.odata2.api.edm.EdmEntityType;
 import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.FullQualifiedName;
 
 /**
  * Helper for the entity data model used as technical reference scenario.
@@ -36,14 +37,23 @@ public class TecEdmInfo {
   }
 
   public EdmEntityType getTypeEtAllTypes() {
+    return getEntityType(TechnicalScenarioEdmProvider.ET_ALL_TYPES);
+  }
+
+  public EdmEntityType getTypeEtKeyTypeInteger() {
+    return getEntityType(TechnicalScenarioEdmProvider.ET_KEY_IS_INTEGER);
+  }
+
+  public EdmEntityType getTypeEtKeyTypeString() {
+    return getEntityType(TechnicalScenarioEdmProvider.ET_KEY_IS_STRING);
+  }
+
+  private EdmEntityType getEntityType(final FullQualifiedName name) {
     try {
-      return edm
-          .getEntityContainer(TechnicalScenarioEdmProvider.ENTITY_CONTAINER_1)
-          .getEntitySet(TechnicalScenarioEdmProvider.ES_ALL_TYPES)
-          .getEntityType();
+      return edm.getEntityType(name.getNamespace(), name.getName());
     } catch (final EdmException e) {
-      fail("Error in test setup" + e.getLocalizedMessage());
+      fail("Error in test setup: " + e.getLocalizedMessage());
+      return null;
     }
-    return null;
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/919d4ac0/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/mock/TechnicalScenarioEdmProvider.java
----------------------------------------------------------------------
diff --git 
a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/mock/TechnicalScenarioEdmProvider.java
 
b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/mock/TechnicalScenarioEdmProvider.java
index 0b8b4d7..755f48f 100644
--- 
a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/mock/TechnicalScenarioEdmProvider.java
+++ 
b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/mock/TechnicalScenarioEdmProvider.java
@@ -223,17 +223,18 @@ public class TechnicalScenarioEdmProvider extends 
EdmProvider {
   }
 
   @Override
-  public Association getAssociation(final FullQualifiedName edmFQName) throws 
ODataMessageException {
-    if (NAMESPACE_1.equals(edmFQName.getNamespace())) {
-      if (ASSOCIATION_ET1_ET2.getName().equals(edmFQName.getName())) {
-        final AssociationEnd end1 =
-            new 
AssociationEnd().setMultiplicity(EdmMultiplicity.ONE).setRole(ROLE_1).setType(ET_KEY_IS_STRING);
-        final AssociationEnd end2 =
-            new 
AssociationEnd().setMultiplicity(EdmMultiplicity.ONE).setRole(ROLE_2).setType(ET_KEY_IS_INTEGER);
-        return new 
Association().setName("Association").setEnd1(end1).setEnd2(end2);
-      }
+  public Association getAssociation(final FullQualifiedName association) 
throws ODataMessageException {
+    if (ASSOCIATION_ET1_ET2.equals(association)) {
+      return new Association().setName(ASSOCIATION_ET1_ET2.getName())
+          .setEnd1(new AssociationEnd()
+              .setMultiplicity(EdmMultiplicity.ZERO_TO_ONE)
+              .setRole(ROLE_1)
+              .setType(ET_KEY_IS_STRING))
+          .setEnd2(new AssociationEnd()
+              .setMultiplicity(EdmMultiplicity.MANY)
+              .setRole(ROLE_2)
+              .setType(ET_KEY_IS_INTEGER));
     }
-
     return null;
   }
 

Reply via email to