http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/927ecb93/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
new file mode 100644
index 0000000..87e09ad
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriTokenizer.java
@@ -0,0 +1,592 @@
+/*
+ * 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;
+
+/**
+ * <p>Simple OData URI tokenizer that works on a given string by keeping an 
index.</p>
+ * <p>As far as feasible, it tries to work on character basis, assuming this 
to be faster than string operations.
+ * Since only the index is "moved", backing out while parsing a token is easy 
and used throughout.
+ * There is intentionally no method to push back tokens (although it would be 
easy to add such a method)
+ * because this tokenizer should behave like a classical token-consuming 
tokenizer.</p>
+ */
+public class UriTokenizer {
+
+  public enum TokenKind {
+    EOF, // signals the end of the string to be parsed
+
+    // constant-value tokens (convention: uppercase)
+    REF,
+    VALUE,
+    COUNT,
+    CROSSJOIN,
+    OPEN,
+    CLOSE,
+    COMMA,
+    SEMI,
+    EQ,
+    NULL,
+
+    // variable-value tokens (convention: mixed case)
+    ODataIdentifier,
+    QualifiedName,
+    ParameterAliasName,
+
+    PrimitiveBooleanValue,
+    PrimitiveStringValue,
+    PrimitiveIntegerValue,
+    PrimitiveGuidValue,
+    PrimitiveDateValue,
+    PrimitiveDateTimeOffsetValue,
+    PrimitiveTimeOfDayValue,
+    PrimitiveDecimalValue,
+    PrimitiveDoubleValue,
+    PrimitiveDurationValue,
+    PrimitiveBinaryValue,
+    PrimitiveEnumValue,
+
+    jsonArrayOrObject
+  }
+
+  private final String pathSegment;
+
+  private int startIndex = 0;
+  private int index = 0;
+
+  public UriTokenizer(final String pathSegment) {
+    this.pathSegment = pathSegment == null ? "" : pathSegment;
+  }
+
+  /** Returns the string value corresponding to the last successful {@link 
#next(TokenKind)} call. */
+  public String getText() {
+    return pathSegment.substring(startIndex, index);
+  }
+
+  /**
+   * Tries to find a token of the given token kind at the current index.
+   * The order in which this method is called with different token kinds is 
important,
+   * not only for performance reasons but also if tokens can start with the 
same characters
+   * (e.g., a qualified name starts with an OData identifier).
+   * @param allowedTokenKind the kind of token to expect
+   * @return <code>true</code> if the token is found; <code>false</code> 
otherwise
+   * @see #getText()
+   */
+  public boolean next(final TokenKind allowedTokenKind) {
+    if (allowedTokenKind == null) {
+      return false;
+    }
+
+    boolean found = false;
+    final int previousIndex = index;
+    switch (allowedTokenKind) {
+    // Constants
+    case REF:
+      found = nextConstant("$ref");
+      break;
+    case VALUE:
+      found = nextConstant("$value");
+      break;
+    case COUNT:
+      found = nextConstant("$count");
+      break;
+    case CROSSJOIN:
+      found = nextConstant("$crossjoin");
+      break;
+    case OPEN:
+      found = nextCharacter('(');
+      break;
+    case CLOSE:
+      found = nextCharacter(')');
+      break;
+    case COMMA:
+      found = nextCharacter(',');
+      break;
+    case SEMI:
+      found = nextCharacter(';');
+      break;
+    case EQ:
+      found = nextCharacter('=');
+      break;
+    case NULL:
+      found = nextConstant("null");
+      break;
+    case EOF:
+      found = index >= pathSegment.length();
+      break;
+
+    // Identifiers
+    case ODataIdentifier:
+      found = nextODataIdentifier();
+      break;
+    case QualifiedName:
+      found = nextQualifiedName();
+      break;
+    case ParameterAliasName:
+      found = nextParameterAliasName();
+      break;
+
+    // Primitive Values
+    case PrimitiveBooleanValue:
+      found = nextBooleanValue();
+      break;
+    case PrimitiveStringValue:
+      found = nextStringValue();
+      break;
+    case PrimitiveIntegerValue:
+      found = nextIntegerValue(true);
+      break;
+    case PrimitiveGuidValue:
+      found = nextGuidValue();
+      break;
+    case PrimitiveDateValue:
+      found = nextDateValue();
+      break;
+    case PrimitiveDateTimeOffsetValue:
+      found = nextDateTimeOffsetValue();
+      break;
+    case PrimitiveTimeOfDayValue:
+      found = nextTimeOfDayValue();
+      break;
+    case PrimitiveDecimalValue:
+      found = nextDecimalValue();
+      break;
+    case PrimitiveDoubleValue:
+      found = nextDoubleValue();
+      break;
+    case PrimitiveDurationValue:
+      found = nextDurationValue();
+      break;
+    case PrimitiveBinaryValue:
+      found = nextBinaryValue();
+      break;
+    case PrimitiveEnumValue:
+      found = nextEnumValue();
+      break;
+
+    // Primitive Values
+    case jsonArrayOrObject:
+      found = nextJsonArrayOrObject();
+      break;
+    }
+
+    if (found) {
+      startIndex = previousIndex;
+    } else {
+      index = previousIndex;
+    }
+    return found;
+  }
+
+  private boolean nextConstant(final String constant) {
+    if (pathSegment.startsWith(constant, index)) {
+      index += constant.length();
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  private boolean nextConstantIgnoreCase(final String constant) {
+    final int length = constant.length();
+    if (index + length <= pathSegment.length()
+        && constant.equalsIgnoreCase(pathSegment.substring(index, index + 
length))) {
+      index += length;
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  /**
+   * Moves past the given character if found; otherwise leaves the index 
unchanged.
+   * @return whether the given character has been found at the current index
+   */
+  private boolean nextCharacter(final char character) {
+    if (index < pathSegment.length() && pathSegment.charAt(index) == 
character) {
+      index++;
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  /**
+   * Moves past the next character if it is in the given character range;
+   * otherwise leaves the index unchanged.
+   * @return whether the given character has been found at the current index
+   */
+  private boolean nextCharacterRange(final char from, final char to) {
+    if (index < pathSegment.length()) {
+      final char code = pathSegment.charAt(index);
+      if (code >= from && code <= to) {
+        index++;
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Moves past a digit character ('0' to '9') if found; otherwise leaves the 
index unchanged.
+   * @return whether a digit character has been found at the current index
+   */
+  private boolean nextDigit() {
+    return nextCharacterRange('0', '9');
+  }
+
+  /**
+   * Moves past a hexadecimal digit character ('0' to '9', 'A' to 'F', or 'a' 
to 'f') if found;
+   * otherwise leaves the index unchanged.
+   * @return whether a hexadecimal digit character has been found at the 
current index
+   */
+  private boolean nextHexDigit() {
+    return nextCharacterRange('0', '9') || nextCharacterRange('A', 'F') || 
nextCharacterRange('a', 'f');
+  }
+
+  /**
+   * Moves past a base64 character ('0' to '9', 'A' to 'Z', 'a' to 'z', '-', 
or '_') if found;
+   * otherwise leaves the index unchanged.
+   * @return whether a base64 character has been found at the current index
+   */
+  private boolean nextBase64() {
+    return nextCharacterRange('0', '9') || nextCharacterRange('A', 'Z') || 
nextCharacterRange('a', 'z')
+        || nextCharacter('-') || nextCharacter('_');
+  }
+
+  /**
+   * Moves past a sign character ('+' or '-') if found; otherwise leaves the 
index unchanged.
+   * @return whether a sign character has been found at the current index
+   */
+  private boolean nextSign() {
+    return nextCharacter('+') || nextCharacter('-');
+  }
+
+  private boolean nextODataIdentifier() {
+    int count = 0;
+    if (index < pathSegment.length()) {
+      int code = pathSegment.codePointAt(index);
+      if (Character.isUnicodeIdentifierStart(code) || code == '_') {
+        count++;
+        // Unicode characters outside of the Basic Multilingual Plane are 
represented as two Java characters.
+        index += Character.isSupplementaryCodePoint(code) ? 2 : 1;
+        while (index < pathSegment.length() && count < 128) {
+          code = pathSegment.codePointAt(index);
+          if (Character.isUnicodeIdentifierPart(code) && 
!Character.isISOControl(code)) {
+            count++;
+            // Unicode characters outside of the Basic Multilingual Plane are 
represented as two Java characters.
+            index += Character.isSupplementaryCodePoint(code) ? 2 : 1;
+          } else {
+            break;
+          }
+        }
+      }
+    }
+    return count > 0;
+  }
+
+  private boolean nextQualifiedName() {
+    int count = 0;
+    do {
+      if (nextODataIdentifier()) {
+        count++;
+      } else {
+        return false;
+      }
+    } while (nextCharacter('.'));
+    return count >= 2;
+  }
+
+  private boolean nextParameterAliasName() {
+    return nextCharacter('@') && nextODataIdentifier();
+  }
+
+  private boolean nextBooleanValue() {
+    return nextConstantIgnoreCase("true") || nextConstantIgnoreCase("false");
+  }
+
+  private boolean nextStringValue() {
+    if (!nextCharacter('\'')) {
+      return false;
+    }
+    while (index < pathSegment.length()) {
+      if (pathSegment.charAt(index) == '\'') {
+        // If a single quote is followed by another single quote,
+        // it represents one single quote within the string literal,
+        // otherwise it marks the end of the string literal.
+        if (index + 1 < pathSegment.length() && pathSegment.charAt(index + 1) 
== '\'') {
+          index++;
+        } else {
+          break;
+        }
+      }
+      index++;
+    }
+    return nextCharacter('\'');
+  }
+
+  private boolean nextIntegerValue(final boolean signed) {
+    if (signed) {
+      nextSign();
+    }
+    boolean hasDigits = false;
+    while (nextDigit()) {
+      hasDigits = true;
+    }
+    return hasDigits;
+  }
+
+  /** Finds and returns only decimal-number tokens with a fractional part.
+   *  Whole numbers must be found with {@link #nextIntegerValue()}.
+   */
+  private boolean nextDecimalValue() {
+    return nextIntegerValue(true) && nextCharacter('.') && 
nextIntegerValue(false);
+  }
+
+  /**
+   * Finds and returns only floating-point-number tokens with an exponential 
part
+   * and the special three constants "NaN", "-INF", and "INF".
+   *  Whole numbers must be found with {@link #nextIntegerValue()}.
+   *  Decimal numbers must be found with {@link #nextDecimalValue()}.
+   */
+  private boolean nextDoubleValue() {
+    if (nextConstant("NaN") || nextConstant("-INF") || nextConstant("INF")) {
+      return true;
+    } else {
+      if (!nextIntegerValue(true)) {
+        return false;
+      }
+      if (nextCharacter('.') && !nextIntegerValue(false)) {
+        return false;
+      }
+      return (nextCharacter('E') || nextCharacter('e')) && 
nextIntegerValue(true);
+    }
+  }
+
+  private boolean nextGuidValue() {
+    return nextHexDigit() && nextHexDigit() && nextHexDigit() && nextHexDigit()
+        && nextHexDigit() && nextHexDigit() && nextHexDigit() && nextHexDigit()
+        && nextCharacter('-')
+        && nextHexDigit() && nextHexDigit() && nextHexDigit() && nextHexDigit()
+        && nextCharacter('-')
+        && nextHexDigit() && nextHexDigit() && nextHexDigit() && nextHexDigit()
+        && nextCharacter('-')
+        && nextHexDigit() && nextHexDigit() && nextHexDigit() && nextHexDigit()
+        && nextCharacter('-')
+        && nextHexDigit() && nextHexDigit() && nextHexDigit() && nextHexDigit()
+        && nextHexDigit() && nextHexDigit() && nextHexDigit() && nextHexDigit()
+        && nextHexDigit() && nextHexDigit() && nextHexDigit() && 
nextHexDigit();
+  }
+
+  private boolean nextYear() {
+    nextCharacter('-');
+    if (nextCharacter('0')) {
+      return nextDigit() && nextDigit() && nextDigit();
+    } else if (nextCharacterRange('1', '9')) {
+      int count = 0;
+      while (nextDigit()) {
+        count++;
+      }
+      return count >= 3;
+    } else {
+      return false;
+    }
+  }
+
+  private boolean nextDateValue() {
+    return nextYear()
+        && nextCharacter('-')
+        && (nextCharacter('0') && nextCharacterRange('1', '9')
+        || nextCharacter('1') && nextCharacterRange('0', '2'))
+        && nextCharacter('-')
+        && (nextCharacter('0') && nextCharacterRange('1', '9')
+            || nextCharacterRange('1', '2') && nextDigit()
+            || nextCharacter('3') && nextCharacterRange('0', '1'));
+  }
+
+  private boolean nextHours() {
+    return nextCharacterRange('0', '1') && nextDigit()
+        || nextCharacter('2') && nextCharacterRange('0', '3');
+  }
+
+  private boolean nextMinutesOrSeconds() {
+    return nextCharacterRange('0', '5') && nextDigit();
+  }
+
+  private boolean nextDateTimeOffsetValue() {
+    return nextDateValue()
+        && (nextCharacter('T') || nextCharacter('t'))
+        && nextTimeOfDayValue()
+        && (nextCharacter('Z')
+            || nextCharacter('z')
+            || nextSign() && nextHours() && nextCharacter(':') && 
nextMinutesOrSeconds());
+  }
+
+  private boolean nextTimeOfDayValue() {
+    if (nextHours() && nextCharacter(':') && nextMinutesOrSeconds()) {
+      if (nextCharacter(':')) {
+        if (nextMinutesOrSeconds()) {
+          if (nextCharacter('.') && !nextIntegerValue(false)) {
+            return false;
+          }
+        } else {
+          return false;
+        }
+      }
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  private boolean nextDurationValue() {
+    if (nextConstantIgnoreCase("duration") && nextCharacter('\'')) {
+      nextSign();
+      if (nextCharacter('P') || nextCharacter('p')) {
+        if (nextIntegerValue(false)) {
+          if (!(nextCharacter('D') || nextCharacter('d'))) {
+            return false;
+          }
+        }
+        if (nextCharacter('T') || nextCharacter('t')) {
+          boolean hasNumber = false;
+          if (nextIntegerValue(false)) {
+            hasNumber = true;
+            if (nextCharacter('H') || nextCharacter('h')) {
+              hasNumber = false;
+            }
+          }
+          if (hasNumber || nextIntegerValue(false)) {
+            hasNumber = true;
+            if (nextCharacter('M') || nextCharacter('m')) {
+              hasNumber = false;
+            }
+          }
+          if (hasNumber || nextIntegerValue(false)) {
+            if (nextCharacter('.')) {
+              if (!nextIntegerValue(false)) {
+                return false;
+              }
+            }
+            if (!(nextCharacter('S') || nextCharacter('s'))) {
+              return false;
+            }
+          }
+        }
+        return nextCharacter('\'');
+      }
+    }
+    return false;
+  }
+
+  private boolean nextBinaryValue() {
+    if (nextConstantIgnoreCase("binary") && nextCharacter('\'')) {
+      int lastGoodIndex = index;
+      while (nextBase64() && nextBase64() && nextBase64() && nextBase64()) {
+        lastGoodIndex += 4;
+      }
+      index = lastGoodIndex;
+      if (nextBase64() && nextBase64()
+          && (nextCharacter('A') || nextCharacter('E') || nextCharacter('I') 
|| nextCharacter('M')
+              || nextCharacter('Q') || nextCharacter('U') || 
nextCharacter('Y') || nextCharacter('c')
+              || nextCharacter('g') || nextCharacter('k') || 
nextCharacter('o') || nextCharacter('s')
+              || nextCharacter('w') || nextCharacter('0') || 
nextCharacter('4') || nextCharacter('8'))) {
+        nextCharacter('=');
+      } else {
+        index = lastGoodIndex;
+        if (nextBase64()) {
+          if (nextCharacter('A') || nextCharacter('Q') || nextCharacter('g') 
|| nextCharacter('w')) {
+            nextConstant("==");
+          } else {
+            return false;
+          }
+        }
+      }
+      return nextCharacter('\'');
+    }
+    return false;
+  }
+
+  private boolean nextEnumValue() {
+    if (nextQualifiedName() && nextCharacter('\'')) {
+      do {
+        if (!(nextODataIdentifier() || nextIntegerValue(true))) {
+          return false;
+        }
+      } while (nextCharacter(','));
+      return nextCharacter('\'');
+    }
+    return false;
+  }
+
+  private boolean nextJsonString() {
+    if (nextCharacter('"')) {
+      do {
+        if (nextCharacter('\\')) {
+          if (!(nextCharacter('b') || nextCharacter('t')
+              || nextCharacter('n') || nextCharacter('f') || nextCharacter('r')
+              || nextCharacter('"') || nextCharacter('/') || 
nextCharacter('\\')
+              || nextCharacter('u') && nextHexDigit() && nextHexDigit() && 
nextHexDigit() && nextHexDigit())) {
+            return false;
+          }
+        } else if (nextCharacter('"')) {
+          return true;
+        } else {
+          index++;
+        }
+      } while (index < pathSegment.length());
+      return false;
+    }
+    return false;
+  }
+
+  private boolean nextJsonValue() {
+    return nextConstant("null") || nextConstant("true") || 
nextConstant("false")
+        // If a double or decimal number is not found, the index must be 
reset; the internal methods don't do that.
+        || next(TokenKind.PrimitiveDoubleValue) || 
next(TokenKind.PrimitiveDecimalValue) || nextIntegerValue(true)
+        || nextJsonString()
+        || nextJsonArrayOrObject();
+  }
+
+  private boolean nextJsonMember() {
+    return nextJsonString() && nextCharacter(':') && nextJsonValue();
+  }
+
+  private boolean nextJsonArrayOrObject() {
+    if (nextCharacter('[')) {
+      if (nextJsonValue()) {
+        while (nextCharacter(',')) {
+          if (!nextJsonValue()) {
+            return false;
+          }
+        }
+      }
+      return nextCharacter(']');
+    } else if (nextCharacter('{')) {
+      if (nextJsonMember()) {
+        while (nextCharacter(',')) {
+          if (!nextJsonMember()) {
+            return false;
+          }
+        }
+      }
+      return nextCharacter('}');
+    } else {
+      return false;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/927ecb93/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
index f840e8e..3ccd97a 100644
--- 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java
@@ -24,7 +24,6 @@ import java.util.Map;
 
 import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.commons.api.edm.EdmFunction;
-import org.apache.olingo.commons.api.edm.EdmFunctionImport;
 import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
@@ -223,14 +222,7 @@ public class UriValidator {
 
   private RowIndexForUriType rowIndexForResourceKind(final UriInfo uriInfo) 
throws UriValidationException {
     RowIndexForUriType idx;
-    
-    final int nonComposableFunctionIndex = 
getIndexOfLastNonComposableFunction(uriInfo);
-    if(nonComposableFunctionIndex != -1 && 
(uriInfo.getUriResourceParts().size() - 1) > nonComposableFunctionIndex) {
-      throw new UriValidationException("Non composable functions followed by 
further resource parts are not allowed", 
-          UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH, 
-          uriInfo.getUriResourceParts().get(nonComposableFunctionIndex + 
1).getSegmentValue());
-    }
-    
+
     int lastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 1;
     UriResource lastPathSegment = 
uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
 
@@ -249,11 +241,7 @@ public class UriValidator {
       idx = rowIndexForEntitySet(lastPathSegment);
       break;
     case function:
-      if(nonComposableFunctionIndex == -1) {
-        idx = rowIndexForFunction(lastPathSegment);
-      } else {
-        idx = RowIndexForUriType.none;
-      }
+      idx = rowIndexForFunction(lastPathSegment);
       break;
     case primitiveProperty:
       idx = rowIndexForPrimitiveProperty(lastPathSegment);
@@ -278,21 +266,6 @@ public class UriValidator {
     return idx;
   }
 
-  private int getIndexOfLastNonComposableFunction(final UriInfo uriInfo) {
-    for(int i = 0; i < uriInfo.getUriResourceParts().size(); i++) {
-      final UriResource resourcePath = uriInfo.getUriResourceParts().get(i);
-      
-      if(resourcePath instanceof UriResourceFunction) {
-        final UriResourceFunction resourceFuntion = (UriResourceFunction) 
resourcePath;
-        if(!resourceFuntion.getFunction().isComposable()) {
-          return i;
-        }
-      }
-    }
-    
-    return -1;
-  }
-
   private RowIndexForUriType rowIndexForValue(final UriInfo uriInfo) throws 
UriValidationException {
     RowIndexForUriType idx;
     int secondLastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 2;
@@ -309,9 +282,7 @@ public class UriValidator {
       break;
     case function:
       UriResourceFunction uriFunction = (UriResourceFunction) 
secondLastPathSegment;
-      final EdmFunctionImport functionImport = uriFunction.getFunctionImport();
-      final EdmFunction function = functionImport == null ?
-          uriFunction.getFunction() : 
functionImport.getUnboundFunctions().get(0);
+      final EdmFunction function = uriFunction.getFunction();
       idx = function.getReturnType().getType().getKind() == EdmTypeKind.ENTITY 
?
           RowIndexForUriType.mediaStream : 
RowIndexForUriType.propertyPrimitiveValue;
       break;
@@ -351,32 +322,33 @@ public class UriValidator {
   }
 
   private RowIndexForUriType rowIndexForFunction(final UriResource 
lastPathSegment) throws UriValidationException {
-    RowIndexForUriType idx;
-    UriResourceFunction urf = (UriResourceFunction) lastPathSegment;
-    EdmReturnType rt = urf.getFunction().getReturnType();
+    final UriResourceFunction uriFunction = (UriResourceFunction) 
lastPathSegment;
+    final EdmReturnType returnType = uriFunction.getFunction().getReturnType();
 
-    if(!urf.getFunction().isComposable()) {
+    if (!uriFunction.getFunction().isComposable()) {
       return RowIndexForUriType.none;
     }
-    
-    
-    switch (rt.getType().getKind()) {
+
+    RowIndexForUriType idx;
+    switch (returnType.getType().getKind()) {
     case ENTITY:
-      idx = rt.isCollection() && urf.getKeyPredicates().isEmpty() ?
+      idx = returnType.isCollection() && 
uriFunction.getKeyPredicates().isEmpty() ?
           RowIndexForUriType.entitySet : RowIndexForUriType.entity;
       break;
     case PRIMITIVE:
     case ENUM:
     case DEFINITION:
-      idx = rt.isCollection() ? RowIndexForUriType.propertyPrimitiveCollection 
: RowIndexForUriType.propertyPrimitive;
+      idx = returnType.isCollection() ? 
RowIndexForUriType.propertyPrimitiveCollection :
+                                        RowIndexForUriType.propertyPrimitive;
       break;
     case COMPLEX:
-      idx = rt.isCollection() ? RowIndexForUriType.propertyComplexCollection : 
RowIndexForUriType.propertyComplex;
+      idx = returnType.isCollection() ? 
RowIndexForUriType.propertyComplexCollection :
+                                        RowIndexForUriType.propertyComplex;
       break;
     default:
-      throw new UriValidationException("Unsupported function return type: " + 
rt.getType().getKind(),
+      throw new UriValidationException("Unsupported function return type: " + 
returnType.getType().getKind(),
           UriValidationException.MessageKeys.UNSUPPORTED_FUNCTION_RETURN_TYPE,
-          rt.getType().getKind().toString());
+          returnType.getType().getKind().toString());
     }
 
     return idx;
@@ -447,9 +419,7 @@ public class UriValidator {
       break;
     case function:
       final UriResourceFunction uriFunction = (UriResourceFunction) 
secondLastPathSegment;
-      final EdmFunctionImport functionImport = uriFunction.getFunctionImport();
-      final EdmFunction function = functionImport == null ?
-          uriFunction.getFunction() : 
functionImport.getUnboundFunctions().get(0);
+      final EdmFunction function = uriFunction.getFunction();
       final EdmType returnType = function.getReturnType().getType();
       switch (returnType.getKind()) {
       case ENTITY:
@@ -560,8 +530,8 @@ public class UriValidator {
   private void validateParameters(final UriInfo uriInfo) throws 
UriValidationException {
     for (UriResource pathSegment : uriInfo.getUriResourceParts()) {
       final boolean isFunction = pathSegment.getKind() == 
UriResourceKind.function;
-      
-      if(isFunction) {
+
+      if (isFunction) {
         final UriResourceFunction functionPathSegement = (UriResourceFunction) 
pathSegment;
         final EdmFunction edmFuntion = functionPathSegement.getFunction();
         
@@ -613,7 +583,7 @@ public class UriValidator {
     for (UriResource pathSegment : uriInfo.getUriResourceParts()) {
       final boolean isEntitySet = pathSegment.getKind() == 
UriResourceKind.entitySet;
       final boolean isEntityColFunction = isEntityColFunction(pathSegment);
-      
+
       if (isEntitySet || pathSegment.getKind() == 
UriResourceKind.navigationProperty || isEntityColFunction) {
         final List<UriParameter> keyPredicates = isEntitySet ?
             ((UriResourceEntitySet) pathSegment).getKeyPredicates() :
@@ -680,7 +650,7 @@ public class UriValidator {
   }
 
   private boolean isEntityColFunction(final UriResource pathSegment) {
-    if(pathSegment.getKind() == UriResourceKind.function) {
+    if (pathSegment.getKind() == UriResourceKind.function) {
       final UriResourceFunction resourceFunction = (UriResourceFunction) 
pathSegment;
       final EdmReturnType returnType = 
resourceFunction.getFunction().getReturnType();
       
@@ -689,7 +659,7 @@ public class UriValidator {
       return false;
     }
   }
-  
+
   private void validatePropertyOperations(final UriInfo uriInfo, final 
HttpMethod method)
       throws UriValidationException {
     final List<UriResource> parts = uriInfo.getUriResourceParts();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/927ecb93/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/UriTokenizerTest.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/UriTokenizerTest.java
 
b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/UriTokenizerTest.java
new file mode 100644
index 0000000..a9e97ce
--- /dev/null
+++ 
b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/UriTokenizerTest.java
@@ -0,0 +1,369 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.olingo.server.core.uri.parser.UriTokenizer.TokenKind;
+import org.junit.Test;
+
+public class UriTokenizerTest {
+
+  @Test
+  public void nullOK() {
+    assertFalse(new UriTokenizer(null).next(null));
+    assertTrue(new UriTokenizer(null).next(TokenKind.EOF));
+  }
+
+  @Test
+  public void constants() {
+    final UriTokenizer tokenizer = new UriTokenizer("$ref");
+    assertTrue(tokenizer.next(TokenKind.REF));
+    assertEquals("$ref", tokenizer.getText());
+    assertTrue(tokenizer.next(TokenKind.EOF));
+    assertTrue(tokenizer.next(TokenKind.EOF));
+
+    assertTrue(new UriTokenizer("$value").next(TokenKind.VALUE));
+    assertTrue(new UriTokenizer("$count").next(TokenKind.COUNT));
+    assertTrue(new UriTokenizer("$crossjoin").next(TokenKind.CROSSJOIN));
+    assertTrue(new UriTokenizer("null").next(TokenKind.NULL));
+
+    wrongToken(TokenKind.REF, "$ref", 'x');
+  }
+
+  @Test
+  public void sequence() {
+    final UriTokenizer tokenizer = new UriTokenizer("(A=1,B=2);");
+    assertTrue(tokenizer.next(TokenKind.OPEN));
+    assertFalse(tokenizer.next(TokenKind.OPEN));
+    assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
+    assertEquals("A", tokenizer.getText());
+    assertTrue(tokenizer.next(TokenKind.EQ));
+    assertTrue(tokenizer.next(TokenKind.PrimitiveIntegerValue));
+    assertEquals("1", tokenizer.getText());
+    assertTrue(tokenizer.next(TokenKind.COMMA));
+    assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
+    assertEquals("B", tokenizer.getText());
+    assertTrue(tokenizer.next(TokenKind.EQ));
+    assertTrue(tokenizer.next(TokenKind.PrimitiveIntegerValue));
+    assertEquals("2", tokenizer.getText());
+    assertFalse(tokenizer.next(TokenKind.EOF));
+    assertTrue(tokenizer.next(TokenKind.CLOSE));
+    assertTrue(tokenizer.next(TokenKind.SEMI));
+    assertTrue(tokenizer.next(TokenKind.EOF));
+  }
+
+  @Test
+  public void identifier() {
+    assertTrue(new UriTokenizer("name").next(TokenKind.ODataIdentifier));
+    assertTrue(new UriTokenizer("_name").next(TokenKind.ODataIdentifier));
+    assertFalse(new UriTokenizer("1name").next(TokenKind.ODataIdentifier));
+    assertFalse(new UriTokenizer("").next(TokenKind.ODataIdentifier));
+
+    final String outsideBmpLetter = String.valueOf(Character.toChars(0x10330));
+    UriTokenizer tokenizer = new UriTokenizer(
+        outsideBmpLetter + "name1\u0300a\u0600b\uFE4F" + outsideBmpLetter + 
"end\b");
+    assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
+    assertEquals(outsideBmpLetter + "name1\u0300a\u0600b\uFE4F" + 
outsideBmpLetter + "end", tokenizer.getText());
+
+    // Identifiers consist of up to 128 characters.  Check that the identifier 
does not have more characters.
+    final String name = 
"Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch"; // Do you know 
this village?
+    tokenizer = new UriTokenizer(name + '_' + name + "_0123456789X");
+    assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
+    assertEquals(name + '_' + name + "_0123456789", tokenizer.getText());
+    tokenizer.next(TokenKind.ODataIdentifier);
+    assertEquals("X", tokenizer.getText());
+
+    wrongToken(TokenKind.ODataIdentifier, "_", '.');
+    wrongToken(TokenKind.ODataIdentifier, "_", ',');
+  }
+
+  @Test
+  public void qualifiedName() {
+    assertTrue(new 
UriTokenizer("namespace.name").next(TokenKind.QualifiedName));
+
+    final UriTokenizer tokenizer = new 
UriTokenizer("multi.part.namespace.name");
+    assertTrue(tokenizer.next(TokenKind.QualifiedName));
+    assertTrue(tokenizer.next(TokenKind.EOF));
+
+    assertFalse(new UriTokenizer("name").next(TokenKind.QualifiedName));
+    assertFalse(new 
UriTokenizer("namespace..name").next(TokenKind.QualifiedName));
+    assertFalse(new UriTokenizer("").next(TokenKind.QualifiedName));
+    wrongToken(TokenKind.QualifiedName, "namespace._", ',');
+  }
+
+  @Test
+  public void alias() {
+    assertTrue(new UriTokenizer("@name").next(TokenKind.ParameterAliasName));
+    assertTrue(new UriTokenizer("@_name").next(TokenKind.ParameterAliasName));
+    assertFalse(new UriTokenizer("name").next(TokenKind.ParameterAliasName));
+    assertFalse(new UriTokenizer("@").next(TokenKind.ParameterAliasName));
+    assertFalse(new UriTokenizer("@1").next(TokenKind.ParameterAliasName));
+  }
+
+  @Test
+  public void booleanValue() {
+    assertTrue(new UriTokenizer("true").next(TokenKind.PrimitiveBooleanValue));
+    assertTrue(new UriTokenizer("tRuE").next(TokenKind.PrimitiveBooleanValue));
+    assertTrue(new 
UriTokenizer("false").next(TokenKind.PrimitiveBooleanValue));
+    assertTrue(new 
UriTokenizer("False").next(TokenKind.PrimitiveBooleanValue));
+
+    wrongToken(TokenKind.PrimitiveBooleanValue, "true", 'x');
+  }
+
+  @Test
+  public void string() {
+    assertTrue(new UriTokenizer("'ABC'").next(TokenKind.PrimitiveStringValue));
+    assertTrue(new 
UriTokenizer("'€\uFDFC'").next(TokenKind.PrimitiveStringValue));
+    assertTrue(new UriTokenizer('\'' + 
String.valueOf(Character.toChars(0x1F603)) + '\'')
+        .next(TokenKind.PrimitiveStringValue));
+
+    final UriTokenizer tokenizer = new UriTokenizer("'AB''''C'''D");
+    assertTrue(tokenizer.next(TokenKind.PrimitiveStringValue));
+    assertEquals("'AB''''C'''", tokenizer.getText());
+    assertTrue(tokenizer.next(TokenKind.ODataIdentifier));
+    assertEquals("D", tokenizer.getText());
+
+    assertFalse(new UriTokenizer("A").next(TokenKind.PrimitiveStringValue));
+    assertFalse(new UriTokenizer("'A").next(TokenKind.PrimitiveStringValue));
+  }
+
+  @Test
+  public void integer() {
+    assertTrue(new UriTokenizer("1").next(TokenKind.PrimitiveIntegerValue));
+    assertTrue(new UriTokenizer("1.").next(TokenKind.PrimitiveIntegerValue));
+    assertFalse(new UriTokenizer(".1").next(TokenKind.PrimitiveIntegerValue));
+    assertTrue(new UriTokenizer("-1").next(TokenKind.PrimitiveIntegerValue));
+    assertTrue(new 
UriTokenizer("1234567890").next(TokenKind.PrimitiveIntegerValue));
+  }
+
+  @Test
+  public void guid() {
+    assertTrue(new 
UriTokenizer("12345678-abcd-ef12-1234-567890ABCDEF").next(TokenKind.PrimitiveGuidValue));
+    wrongToken(TokenKind.PrimitiveGuidValue, 
"12345678-1234-1234-1234-123456789ABC", 'G');
+  }
+
+  @Test
+  public void date() {
+    assertTrue(new 
UriTokenizer("12345-12-25").next(TokenKind.PrimitiveDateValue));
+    assertTrue(new 
UriTokenizer("-0001-12-24").next(TokenKind.PrimitiveDateValue));
+    assertFalse(new 
UriTokenizer("1234-13-01").next(TokenKind.PrimitiveDateValue));
+    assertFalse(new 
UriTokenizer("1234-12-32").next(TokenKind.PrimitiveDateValue));
+    assertFalse(new 
UriTokenizer("123-01-01").next(TokenKind.PrimitiveDateValue));
+    assertFalse(new 
UriTokenizer("1234-00-01").next(TokenKind.PrimitiveDateValue));
+    assertFalse(new 
UriTokenizer("1234-01-00").next(TokenKind.PrimitiveDateValue));
+    wrongToken(TokenKind.PrimitiveDateValue, "2000-12-29", 'A');
+    wrongToken(TokenKind.PrimitiveDateValue, "0001-01-01", 'A');
+    wrongToken(TokenKind.PrimitiveDateValue, "-12345-01-31", 'A');
+  }
+
+  @Test
+  public void dateTimeOffset() {
+    assertTrue(new 
UriTokenizer("1234-12-25T11:12:13.456Z").next(TokenKind.PrimitiveDateTimeOffsetValue));
+    assertTrue(new 
UriTokenizer("-1234-12-25t01:12z").next(TokenKind.PrimitiveDateTimeOffsetValue));
+    assertTrue(new 
UriTokenizer("-1234-12-25T21:22:23+01:00").next(TokenKind.PrimitiveDateTimeOffsetValue));
+    assertTrue(new 
UriTokenizer("1234-12-25T11:12:13-00:30").next(TokenKind.PrimitiveDateTimeOffsetValue));
+    assertFalse(new 
UriTokenizer("1234-10-01").next(TokenKind.PrimitiveDateTimeOffsetValue));
+    wrongToken(TokenKind.PrimitiveDateTimeOffsetValue, 
"-1234-12-25T11:12:13.456+01:00", 'P');
+  }
+
+  @Test
+  public void timeOfDay() {
+    assertTrue(new 
UriTokenizer("11:12:13").next(TokenKind.PrimitiveTimeOfDayValue));
+    assertTrue(new 
UriTokenizer("11:12:13.456").next(TokenKind.PrimitiveTimeOfDayValue));
+    assertFalse(new 
UriTokenizer("24:00:00").next(TokenKind.PrimitiveTimeOfDayValue));
+    assertFalse(new 
UriTokenizer("01:60:00").next(TokenKind.PrimitiveTimeOfDayValue));
+    assertFalse(new 
UriTokenizer("01:00:60").next(TokenKind.PrimitiveTimeOfDayValue));
+    assertFalse(new 
UriTokenizer("01:00:00.").next(TokenKind.PrimitiveTimeOfDayValue));
+    assertFalse(new 
UriTokenizer("0:02:03").next(TokenKind.PrimitiveTimeOfDayValue));
+    assertFalse(new 
UriTokenizer("01:0:03").next(TokenKind.PrimitiveTimeOfDayValue));
+    assertFalse(new 
UriTokenizer("01:02:0").next(TokenKind.PrimitiveTimeOfDayValue));
+    wrongToken(TokenKind.PrimitiveTimeOfDayValue, "11:12", '-');
+  }
+
+  @Test
+  public void decimal() {
+    assertTrue(new UriTokenizer("1.2").next(TokenKind.PrimitiveDecimalValue));
+    assertFalse(new UriTokenizer(".1").next(TokenKind.PrimitiveDecimalValue));
+    assertTrue(new 
UriTokenizer("-12.34").next(TokenKind.PrimitiveDecimalValue));
+    assertTrue(new 
UriTokenizer("1234567890.0123456789").next(TokenKind.PrimitiveDecimalValue));
+    assertFalse(new UriTokenizer("0,1").next(TokenKind.PrimitiveDecimalValue));
+    assertFalse(new 
UriTokenizer("0..1").next(TokenKind.PrimitiveDecimalValue));
+  }
+
+  @Test
+  public void doubleValue() {
+    assertTrue(new UriTokenizer("NaN").next(TokenKind.PrimitiveDoubleValue));
+    assertTrue(new UriTokenizer("-INF").next(TokenKind.PrimitiveDoubleValue));
+    assertTrue(new UriTokenizer("INF").next(TokenKind.PrimitiveDoubleValue));
+    assertFalse(new UriTokenizer("inf").next(TokenKind.PrimitiveDoubleValue));
+    assertTrue(new UriTokenizer("1.2E3").next(TokenKind.PrimitiveDoubleValue));
+    assertTrue(new 
UriTokenizer("-12.34e-05").next(TokenKind.PrimitiveDoubleValue));
+    assertTrue(new UriTokenizer("1E2").next(TokenKind.PrimitiveDoubleValue));
+    assertFalse(new UriTokenizer("1.E2").next(TokenKind.PrimitiveDoubleValue));
+    wrongToken(TokenKind.PrimitiveDoubleValue, "-12.34E+5", 'i');
+  }
+
+  @Test
+  public void duration() {
+    assertTrue(new 
UriTokenizer("duration'P'").next(TokenKind.PrimitiveDurationValue));
+    assertTrue(new 
UriTokenizer("DURATION'P1D'").next(TokenKind.PrimitiveDurationValue));
+    assertTrue(new 
UriTokenizer("duration'PT'").next(TokenKind.PrimitiveDurationValue));
+    assertTrue(new 
UriTokenizer("duration'PT1H'").next(TokenKind.PrimitiveDurationValue));
+    assertTrue(new 
UriTokenizer("duration'pt1M'").next(TokenKind.PrimitiveDurationValue));
+    assertTrue(new 
UriTokenizer("duration'PT1S'").next(TokenKind.PrimitiveDurationValue));
+    assertTrue(new 
UriTokenizer("duration'PT1.2s'").next(TokenKind.PrimitiveDurationValue));
+    assertTrue(new 
UriTokenizer("duration'-p1dt2h3m4.5s'").next(TokenKind.PrimitiveDurationValue));
+    assertFalse(new 
UriTokenizer("-p1dt2h3m4.5s").next(TokenKind.PrimitiveDurationValue));
+    assertFalse(new 
UriTokenizer("duration'-p1dt2h3m4.5s").next(TokenKind.PrimitiveDurationValue));
+    assertFalse(new 
UriTokenizer("duration'2h3m4s'").next(TokenKind.PrimitiveDurationValue));
+    wrongToken(TokenKind.PrimitiveDurationValue, "duration'P1DT2H3M4.5S'", 
':');
+  }
+
+  @Test
+  public void binary() {
+    assertTrue(new 
UriTokenizer("binary''").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("Binary'bm93'").next(TokenKind.PrimitiveBinaryValue));
+
+    // all cases with three base64 characters (and one fill character) at the 
end
+    assertTrue(new 
UriTokenizer("binary'QUA='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'QUE='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'QUI='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'QUM='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'QUQ='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'QUU='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'QUY='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'QUc='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'QUg='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'QUk='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'QUo='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'QUs='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'QUw='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'QU0='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'QU4='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'QU8='").next(TokenKind.PrimitiveBinaryValue));
+    assertFalse(new 
UriTokenizer("binary'QUB='").next(TokenKind.PrimitiveBinaryValue));
+
+    // all cases with two base64 characters (and two fill characters) at the 
end
+    assertTrue(new 
UriTokenizer("BINARY'VGVzdA=='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'U-RnZQ=='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'Yg=='").next(TokenKind.PrimitiveBinaryValue));
+    assertTrue(new 
UriTokenizer("binary'Yw=='").next(TokenKind.PrimitiveBinaryValue));
+
+    // without optional fill character
+    assertTrue(new 
UriTokenizer("binary'T0RhdGE'").next(TokenKind.PrimitiveBinaryValue));
+
+    // special character '_' (the other, '-', already has been used above)
+    assertTrue(new 
UriTokenizer("binary'V_ZydGVy'").next(TokenKind.PrimitiveBinaryValue));
+
+    wrongToken(TokenKind.PrimitiveBinaryValue, "binary'VGVzdA=='", '+');
+  }
+
+  @Test
+  public void enumValue() {
+    assertTrue(new 
UriTokenizer("namespace.name'value'").next(TokenKind.PrimitiveEnumValue));
+    assertTrue(new 
UriTokenizer("namespace.name'flag1,flag2,-3'").next(TokenKind.PrimitiveEnumValue));
+    assertFalse(new 
UriTokenizer("namespace.name'1flag'").next(TokenKind.PrimitiveEnumValue));
+    assertFalse(new 
UriTokenizer("namespace.name'flag1,,flag2'").next(TokenKind.PrimitiveEnumValue));
+    assertFalse(new 
UriTokenizer("namespace.name',value'").next(TokenKind.PrimitiveEnumValue));
+    assertFalse(new 
UriTokenizer("namespace.name'value,'").next(TokenKind.PrimitiveEnumValue));
+    assertFalse(new 
UriTokenizer("namespace.name''").next(TokenKind.PrimitiveEnumValue));
+    assertFalse(new UriTokenizer("'1'").next(TokenKind.PrimitiveEnumValue));
+    assertFalse(new UriTokenizer("1").next(TokenKind.PrimitiveEnumValue));
+    wrongToken(TokenKind.PrimitiveEnumValue, "namespace.name'_1,_2,3'", ';');
+  }
+
+  @Test
+  public void json() {
+    // Empty string or JSON values are not allowed.
+    assertFalse(new UriTokenizer("").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new UriTokenizer("1").next(TokenKind.jsonArrayOrObject));
+
+    // object with values
+    assertTrue(new UriTokenizer("{}").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new 
UriTokenizer("{\"name\":0}").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new 
UriTokenizer("{\"name\":true}").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new 
UriTokenizer("{\"name\":false}").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new 
UriTokenizer("{\"name\":null}").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new 
UriTokenizer("{\"name\":\"value\"}").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new 
UriTokenizer("{\"name\":\"value\",\"name2\":null}").next(TokenKind.jsonArrayOrObject));
+
+    // array with values
+    assertTrue(new UriTokenizer("[]").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new UriTokenizer("[1]").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new UriTokenizer("[true]").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new UriTokenizer("[false]").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new UriTokenizer("[null]").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new 
UriTokenizer("[\"value\"]").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new UriTokenizer("[\"\"]").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new 
UriTokenizer("[\"\\b\\t\\f\\r\\nn\\/\\\\x\\uFE4Fu\\\"\"]").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new 
UriTokenizer("[1,2.0,3.4E5]").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new 
UriTokenizer("[\"value\",null]").next(TokenKind.jsonArrayOrObject));
+
+    // nesting
+    assertTrue(new 
UriTokenizer("[{\"name\":\"value\"},{\"name\":\"value2\"}]").next(TokenKind.jsonArrayOrObject));
+    assertTrue(new 
UriTokenizer("{\"name\":{\"name2\":\"value\"}}").next(TokenKind.jsonArrayOrObject));
+
+    // unbalanced opening and closing
+    assertFalse(new UriTokenizer("{").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new UriTokenizer("}").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new UriTokenizer("[").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new UriTokenizer("]").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new UriTokenizer("{]").next(TokenKind.jsonArrayOrObject));
+
+    // missing values
+    assertFalse(new UriTokenizer("[1,]").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new UriTokenizer("[,1]").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new UriTokenizer("[1,,2]").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new UriTokenizer("[1,x]").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new 
UriTokenizer("{\"name\":1,}").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new 
UriTokenizer("{,\"name\":1}").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new 
UriTokenizer("{\"name\":1,,\"name2\":2}").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new 
UriTokenizer("{\"name\":1,x}").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new 
UriTokenizer("{\"name\":1,\"name2\"}").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new 
UriTokenizer("{\"name\":1,\"name2\":}").next(TokenKind.jsonArrayOrObject));
+
+    // wrong JSON strings
+    assertFalse(new UriTokenizer("[\"a").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new UriTokenizer("[\"a]").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new 
UriTokenizer("[\"a\"\"]").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new 
UriTokenizer("[\"\\x\"]").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new 
UriTokenizer("[\"\\ux\"]").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new 
UriTokenizer("[\"\\u1\"]").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new 
UriTokenizer("[\"\\u12x\"]").next(TokenKind.jsonArrayOrObject));
+    assertFalse(new 
UriTokenizer("[\"\\u123x\"]").next(TokenKind.jsonArrayOrObject));
+  }
+
+  private void wrongToken(final TokenKind kind, final String value, final char 
disturbCharacter) {
+    assertFalse(new UriTokenizer(disturbCharacter + value).next(kind));
+
+    final UriTokenizer tokenizer = new UriTokenizer(value + disturbCharacter);
+    assertTrue(tokenizer.next(kind));
+    assertEquals(value, tokenizer.getText());
+
+    // Place the disturbing character at every position in the value string
+    // and check that this leads to a failed token recognition.
+    for (int index = 0; index < value.length(); index++) {
+      assertFalse("Error at index " + index,
+          new UriTokenizer(value.substring(0, index) + disturbCharacter + 
value.substring(index + 1)).next(kind));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/927ecb93/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/search/SearchTokenizerTest.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/search/SearchTokenizerTest.java
 
b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/search/SearchTokenizerTest.java
index c2a390a..7547687 100644
--- 
a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/search/SearchTokenizerTest.java
+++ 
b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/parser/search/SearchTokenizerTest.java
@@ -31,7 +31,6 @@ import java.util.Iterator;
 import java.util.List;
 
 import org.junit.Assert;
-import org.junit.Ignore;
 import org.junit.Test;
 
 public class SearchTokenizerTest {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/927ecb93/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
----------------------------------------------------------------------
diff --git 
a/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
 
b/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
index 93c3c9a..6bd6463 100644
--- 
a/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
+++ 
b/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java
@@ -29,7 +29,6 @@ import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmEntityContainer;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
-import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.edmx.EdmxReference;
 import org.apache.olingo.server.api.uri.UriParameter;
@@ -44,8 +43,7 @@ public class DataProviderTest {
   private final Edm edm =
       oData.createServiceMetadata(new EdmTechProvider(), 
Collections.<EdmxReference> emptyList())
       .getEdm();
-  private final EdmEntityContainer entityContainer = edm.getEntityContainer(
-      new FullQualifiedName("olingo.odata.test1", "Container"));
+  private final EdmEntityContainer entityContainer = edm.getEntityContainer();
 
   private final EdmEntitySet esAllPrim = 
entityContainer.getEntitySet("ESAllPrim");
   private final EdmEntitySet esAllKey = 
entityContainer.getEntitySet("ESAllKey");

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/927ecb93/lib/server-test/src/test/java/org/apache/olingo/server/core/PreconditionsValidatorTest.java
----------------------------------------------------------------------
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/PreconditionsValidatorTest.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/PreconditionsValidatorTest.java
index 5e3499c..bf68fb3 100644
--- 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/PreconditionsValidatorTest.java
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/PreconditionsValidatorTest.java
@@ -41,7 +41,7 @@ import org.apache.olingo.server.api.uri.UriResourceValue;
 import org.apache.olingo.server.core.etag.PreconditionsValidator;
 import org.apache.olingo.server.core.uri.parser.Parser;
 import org.apache.olingo.server.core.uri.parser.UriParserException;
-import org.apache.olingo.server.core.uri.parser.UriParserSemanticException;
+import org.apache.olingo.server.core.uri.validator.UriValidationException;
 import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
 import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
@@ -49,7 +49,8 @@ import org.mockito.stubbing.Answer;
 
 public class PreconditionsValidatorTest {
 
-  private static final Edm edm = OData.newInstance().createServiceMetadata(
+  private static final OData odata = OData.newInstance();
+  private static final Edm edm = odata.createServiceMetadata(
       new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
 
   // -------------- POSITIVE TESTS 
--------------------------------------------------------------------------------
@@ -140,7 +141,7 @@ public class PreconditionsValidatorTest {
 
   @Test
   public void simpleEntityValueValidationNotActiveForMedia() throws Exception {
-    final UriInfo uriInfo = new Parser().parseUri("ESMedia(1)/$value", null, 
null, edm);
+    final UriInfo uriInfo = new Parser(edm, 
odata).parseUri("ESMedia(1)/$value", null, null);
 
     CustomETagSupport support = mock(CustomETagSupport.class);
     when(support.hasETag(any(EdmBindingTarget.class))).thenReturn(true);
@@ -185,21 +186,17 @@ public class PreconditionsValidatorTest {
     assertFalse(mustValidate("SINav/NavPropertyETKeyNavOne/$ref", "ESKeyNav"));
   }
 
-  @Test(expected = UriParserSemanticException.class)
-  public void resourceSegmentAfterActionMustLeadToUriParserException() throws 
Exception {
-    
mustValidate("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav/PropertyInt16",
 "ESKeyNav");
-  }
-
-  @Test(expected = UriParserSemanticException.class)
-  public void valueMustBeLastSegment() throws Exception {
-    mustValidate("ESMedia(1)/$value/PropertyInt16", "ESMedia");
+  @Test
+  public void nonResourceMustBeIgnored() throws Exception {
+    assertFalse(mustValidate("$all", null));
   }
 
   private boolean mustValidate(final String uri, final String entitySetName)
-      throws UriParserException, PreconditionException {
-    final UriInfo uriInfo = new Parser().parseUri(uri, null, null, edm);
+      throws UriParserException, UriValidationException, PreconditionException 
{
+    final UriInfo uriInfo = new Parser(edm, odata).parseUri(uri, null, null);
     final List<UriResource> parts = uriInfo.getUriResourceParts();
-    final boolean isMedia = parts.get(parts.size() - 1) instanceof 
UriResourceValue
+    final boolean isMedia = parts.size() >= 2
+        && parts.get(parts.size() - 1) instanceof UriResourceValue
         && parts.get(parts.size() - 2) instanceof UriResourceEntitySet;
 
     CustomETagSupport support = mock(CustomETagSupport.class);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/927ecb93/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java
----------------------------------------------------------------------
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java
index fe86896..92b069d 100644
--- 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java
@@ -28,7 +28,6 @@ import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmEntityContainer;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
 import org.apache.olingo.commons.api.edm.EdmProperty;
-import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.edmx.EdmxReference;
 import org.apache.olingo.server.api.uri.UriParameter;
@@ -45,8 +44,7 @@ public class ContextURLHelperTest {
 
   private static final Edm edm = OData.newInstance().createServiceMetadata(
       new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
-  private static final EdmEntityContainer entityContainer = 
edm.getEntityContainer(
-      new FullQualifiedName("olingo.odata.test1", "Container"));
+  private static final EdmEntityContainer entityContainer = 
edm.getEntityContainer();
 
   @Test
   public void buildSelect() throws Exception {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/927ecb93/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriHelperTest.java
----------------------------------------------------------------------
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriHelperTest.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriHelperTest.java
index 781f48d..d3dba46 100644
--- 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriHelperTest.java
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriHelperTest.java
@@ -25,7 +25,6 @@ import org.apache.olingo.commons.api.data.ValueType;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmEntityContainer;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
-import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.edmx.EdmxReference;
 import org.apache.olingo.server.api.serializer.SerializerException;
@@ -40,8 +39,7 @@ public class UriHelperTest {
   private static final OData odata = OData.newInstance();
   private static final Edm edm = odata.createServiceMetadata(
       new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
-  private static final EdmEntityContainer container = edm.getEntityContainer(
-      new FullQualifiedName("olingo.odata.test1", "Container"));
+  private static final EdmEntityContainer container = edm.getEntityContainer();
   private static final UriHelper helper = odata.createUriHelper();
   private final DataProvider data = new DataProvider(odata, edm);
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/927ecb93/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriResourceImplTest.java
----------------------------------------------------------------------
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriResourceImplTest.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriResourceImplTest.java
index 27b879d..a5d0ea3 100644
--- 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriResourceImplTest.java
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriResourceImplTest.java
@@ -86,7 +86,7 @@ public class UriResourceImplTest {
 
     // action import
     impl = new UriResourceActionImpl();
-    EdmActionImport actionImport = 
edm.getEntityContainer(null).getActionImport("AIRTCTTwoPrimParam");
+    EdmActionImport actionImport = 
edm.getEntityContainer().getActionImport("AIRTCTTwoPrimParam");
     impl.setActionImport(actionImport);
     assertEquals(actionImport, impl.getActionImport());
     assertEquals(actionImport.getUnboundAction(), impl.getAction());
@@ -94,7 +94,7 @@ public class UriResourceImplTest {
     assertEquals("AIRTCTTwoPrimParam", impl.toString());
     assertEquals(actionImport.getUnboundAction().getReturnType().getType(), 
impl.getType());
 
-    actionImport = edm.getEntityContainer(null).getActionImport("AIRT");
+    actionImport = edm.getEntityContainer().getActionImport("AIRT");
     impl.setActionImport(actionImport);
     assertFalse(impl.isCollection());
     assertNull(impl.getType());
@@ -184,7 +184,7 @@ public class UriResourceImplTest {
     UriResourceEntitySetImpl impl = new UriResourceEntitySetImpl();
     assertEquals(UriResourceKind.entitySet, impl.getKind());
 
-    EdmEntitySet entitySet = 
edm.getEntityContainer(null).getEntitySet("ESAllPrim");
+    EdmEntitySet entitySet = 
edm.getEntityContainer().getEntitySet("ESAllPrim");
     impl.setEntitSet(entitySet);
 
     assertEquals("ESAllPrim", impl.toString());
@@ -207,7 +207,7 @@ public class UriResourceImplTest {
     assertEquals("", impl.toString());
 
     // function
-    EdmFunction function = 
edm.getEntityContainer(null).getFunctionImport("FINRTInt16")
+    EdmFunction function = 
edm.getEntityContainer().getFunctionImport("FINRTInt16")
         .getUnboundFunction(Collections.<String> emptyList());
     assertNotNull(function);
     impl.setFunction(function);
@@ -219,14 +219,14 @@ public class UriResourceImplTest {
 
     // function import
     impl = new UriResourceFunctionImpl();
-    EdmFunctionImport functionImport = 
edm.getEntityContainer(null).getFunctionImport("FINRTInt16");
+    EdmFunctionImport functionImport = 
edm.getEntityContainer().getFunctionImport("FINRTInt16");
     impl.setFunctionImport(functionImport, Collections.<UriParameter> 
emptyList());
     assertEquals(functionImport, impl.getFunctionImport());
     assertEquals("FINRTInt16", impl.toString());
 
     // function collection
     impl = new UriResourceFunctionImpl();
-    functionImport = 
edm.getEntityContainer(null).getFunctionImport("FICRTCollESTwoKeyNavParam");
+    functionImport = 
edm.getEntityContainer().getFunctionImport("FICRTCollESTwoKeyNavParam");
     assertNotNull(function);
     UriParameter parameter = new UriParameterImpl().setName("ParameterInt16");
     impl.setFunctionImport(functionImport, 
Collections.singletonList(parameter));
@@ -414,7 +414,7 @@ public class UriResourceImplTest {
     UriResourceSingletonImpl impl = new UriResourceSingletonImpl();
     assertEquals(UriResourceKind.singleton, impl.getKind());
 
-    EdmSingleton singleton = 
edm.getEntityContainer(null).getSingleton("SINav");
+    EdmSingleton singleton = edm.getEntityContainer().getSingleton("SINav");
     EdmEntityType entityTypeBaseColl = 
edm.getEntityType(EntityTypeProvider.nameETBaseTwoKeyNav);
     impl.setSingleton(singleton);
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/927ecb93/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
----------------------------------------------------------------------
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
index 379345e..11acede 100644
--- 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
@@ -34,12 +34,10 @@ import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.core.Encoder;
 import org.apache.olingo.server.api.OData;
-import org.apache.olingo.server.api.ODataApplicationException;
 import org.apache.olingo.server.api.edmx.EdmxReference;
 import org.apache.olingo.server.api.uri.UriInfoKind;
 import org.apache.olingo.server.api.uri.UriResourceKind;
 import 
org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
-import 
org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
 import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind;
 import org.apache.olingo.server.core.uri.parser.UriParserException;
 import org.apache.olingo.server.core.uri.parser.UriParserSemanticException;
@@ -934,14 +932,20 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void runCrossjoin() throws Exception {
+  public void crossjoin() throws Exception {
     testUri.run("$crossjoin(ESKeyNav)")
         .isKind(UriInfoKind.crossjoin)
         .isCrossJoinEntityList(Arrays.asList("ESKeyNav"));
 
-    testUri.run("$crossjoin(ESKeyNav, ESTwoKeyNav)")
+    testUri.run("$crossjoin(ESKeyNav,ESTwoKeyNav)")
         .isKind(UriInfoKind.crossjoin)
         .isCrossJoinEntityList(Arrays.asList("ESKeyNav", "ESTwoKeyNav"));
+
+    testUri.run("$crossjoin(ESTwoPrim,ESMixPrimCollComp)",
+        "$filter=ESTwoPrim/PropertyString eq 
ESMixPrimCollComp/PropertyComp/PropertyString")
+        .goFilter()
+        .isBinary(BinaryOperatorKind.EQ)
+        .is("<<ESTwoPrim/PropertyString> eq 
<ESMixPrimCollComp/PropertyComp/PropertyString>>");
   }
 
   @Test
@@ -951,6 +955,8 @@ public class TestFullResourcePath {
     
testUri.runEx("$crossjoin()").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
     testUri.runEx("$crossjoin(ESKeyNav, ESTwoKeyNav)/invalid")
         .isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
+    testUri.runEx("$crossjoin(ESKeyNav)/$ref")
+        .isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
   }
 
   @Test
@@ -982,15 +988,16 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void runEsNameError() {
+  public void esNameError() {
 
-    
testUri.runEx("ESAllPrim/$count/$ref").isExSemantic(MessageKeys.ONLY_FOR_TYPED_PROPERTIES);
-    
testUri.runEx("ESAllPrim/$ref/$count").isExSemantic(MessageKeys.ONLY_FOR_TYPED_PARTS);
-    
testUri.runEx("ESAllPrim/$ref/invalid").isExSemantic(MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS);
-    
testUri.runEx("ESAllPrim/$count/invalid").isExSemantic(MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS);
+    
testUri.runEx("ESAllPrim/$count/$ref").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
+    
testUri.runEx("ESAllPrim/$ref/$count").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
+    
testUri.runEx("ESAllPrim/$ref/invalid").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
+    
testUri.runEx("ESAllPrim/$count/invalid").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
     
testUri.runEx("ESAllPrim/PropertyString").isExSemantic(MessageKeys.PROPERTY_AFTER_COLLECTION);
     
testUri.runEx("ESAllPrim(1)/whatever").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
-    
testUri.runEx("ESAllPrim(PropertyInt16)").isExSemantic(MessageKeys.INVALID_KEY_VALUE);
+    
testUri.runEx("ESAllPrim('1')").isExSemantic(MessageKeys.INVALID_KEY_VALUE);
+    
testUri.runEx("ESAllPrim(PropertyInt16)").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
     
testUri.runEx("ESAllPrim(PropertyInt16=)").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
     
testUri.runEx("ESAllPrim(PropertyInt16=1,Invalid='1')").isExSemantic(MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES);
 
@@ -1023,8 +1030,7 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void runResourcePathWithApostrophe() {
-    // TODO Currently "'" is not allowed in OData identifiers, but the 
specification allows this character (Unicode Cf)
+  public void resourcePathWithApostrophe() {
     
testUri.runEx("ESAllPrim'").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
     
testUri.runEx("ESAllPrim'InvalidStuff").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
 
@@ -1070,7 +1076,7 @@ public class TestFullResourcePath {
         .isKeyPredicate(0, "PropertyInt16", "0");
 
     
testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterString='1',ParameterInt16=1)(PropertyInt16
 eq 0)")
-        .isExSemantic(MessageKeys.INVALID_KEY_VALUE);
+        .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
 
     // PropertyInt32 does not exist
     
testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterString='1',ParameterInt16=1)(PropertyInt32=0)")
@@ -1078,7 +1084,7 @@ public class TestFullResourcePath {
 
     
testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterString='1',ParameterInt16=1)"
         + "(PropertyInt16=0,PropertyInt16=1)")
-        .isExSemantic(MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES);
+        
.isExValidation(UriValidationException.MessageKeys.DOUBLE_KEY_PROPERTY);
 
     
testUri.run("FICRTCollCTTwoPrimTwoParam(ParameterString='1',ParameterInt16=1)")
         .isKind(UriInfoKind.resource)
@@ -1117,13 +1123,13 @@ public class TestFullResourcePath {
         .isKeyPredicate(1, "PropertyString", "'1'");
 
     testUri.runEx("FICRTCollESTwoKeyNavParam(ParameterInt16=1)(PropertyInt16 
eq 1)")
-        .isExSemantic(MessageKeys.INVALID_KEY_VALUE);
+        .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
 
     
testUri.runEx("FICRTCollESTwoKeyNavParam(ParameterInt16=1)(PropertyInt16=1)")
         .isExSemantic(MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES);
 
     
testUri.runEx("FICRTCollESTwoKeyNavParam(ParameterInt16=1)(PropertyInt16=1,PropertyInt32=1,PropertyString='1')")
-        .isExSemantic(MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES);
+        
.isExValidation(UriValidationException.MessageKeys.INVALID_KEY_PROPERTY);
 
     testUri.runEx("FICRTCollESTwoKeyNavParam(ParameterInt16=1)()")
         .isExSemantic(MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES);
@@ -1193,11 +1199,9 @@ public class TestFullResourcePath {
     
testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterInt16=1,ParameterString='1')",
 "$skiptoken=5")
         
.isExValidation(UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED);
 
-    // $search is currently not implemented. Please change this exception if 
the implementation is done.
-    // FIXME (151106:mibo): check after finish of OLINGO-568
-//    
testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterInt16=1,ParameterString='1')",
 "$search=test")
-//      .isExSemantic(MessageKeys.NOT_IMPLEMENTED);
-    
+    
testUri.runEx("FICRTCollETMixPrimCollCompTwoParam(ParameterInt16=1,ParameterString='1')",
 "$search=test")
+        
.isExValidation(UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED);
+
     testUri.run("ESAllPrim/olingo.odata.test1.BFNESAllPrimRTCTAllPrim()")
         .isKind(UriInfoKind.resource)
         .goPath().first()
@@ -1296,8 +1300,8 @@ public class TestFullResourcePath {
         .isKeyPredicate(2, "KeyAlias2", "'3'")
         .isKeyPredicate(3, "KeyAlias3", "'4'");
 
-    
testUri.runEx("ESTwoPrim(wrong)").isExSemantic(MessageKeys.INVALID_KEY_VALUE);
-    
testUri.runEx("ESTwoPrim(PropertyInt16=wrong)").isExSemantic(MessageKeys.INVALID_KEY_VALUE);
+    
testUri.runEx("ESTwoPrim('wrong')").isExSemantic(MessageKeys.INVALID_KEY_VALUE);
+    
testUri.runEx("ESTwoPrim(PropertyInt16='wrong')").isExSemantic(MessageKeys.INVALID_KEY_VALUE);
   }
 
   @Test
@@ -1794,7 +1798,7 @@ public class TestFullResourcePath {
 
   @Test
   public void runEsNamePpNpRc() throws Exception {
-    // checks for using referential constrains to fill missing keys
+    // checks for using referential constraints to fill missing keys
     testUri.run("ESKeyNav(1)/NavPropertyETTwoKeyNavMany('2')").goPath()
         .first()
         .isEntitySet("ESKeyNav")
@@ -2037,7 +2041,6 @@ public class TestFullResourcePath {
 
   @Test
   public void runFunctionImpEs() throws Exception {
-    /**/
     
testUri.run("FICRTESMixPrimCollCompTwoParam(ParameterInt16=1,ParameterString='2')")
         .isKind(UriInfoKind.resource).goPath()
         .first()
@@ -2805,8 +2808,8 @@ public class TestFullResourcePath {
   }
 
   @Test
-  @Ignore("$search currently not implemented")
-  public void runDuplicatedSearchExpand() throws UriParserException, 
UriValidationException {
+  @Ignore("$search in expand currently not implemented")
+  public void duplicatedSearchExpand() throws Exception {
     testUri.runEx("ESKeyNav", 
"$expand=NavPropertyETKeyNavOne($search=Test;$search=Test)")
         
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
   }
@@ -2931,13 +2934,8 @@ public class TestFullResourcePath {
     testUri.run("$batch")
         .isKind(UriInfoKind.batch);
 
-    testUri.run("$crossjoin(ESKeyNav)")
-        .isKind(UriInfoKind.crossjoin)
-        .isCrossJoinEntityList(Arrays.asList("ESKeyNav"));
-
     
testUri.runEx("$metadata/$ref").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
     
testUri.runEx("$batch/$ref").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
-    
testUri.runEx("$crossjoin(ESKeyNav)/$ref").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
     
testUri.runEx("$all/$ref").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
     testUri.runEx("$entity/olingo.odata.test1.ETKeyNav/$ref")
         .isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);
@@ -3142,7 +3140,7 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void testFilter() throws UriParserException {
+  public void filter() throws Exception {
 
     testFilter.runOnETTwoKeyNav("PropertyString")
         .is("<PropertyString>")
@@ -3684,7 +3682,7 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void testFilterProperties() throws UriParserException {
+  public void filterProperties() throws Exception {
     testFilter.runOnETAllPrim("PropertyByte mod 0")
         .is("<<PropertyByte> mod <0>>");
 
@@ -3849,7 +3847,7 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void testFilterPMethods() throws ExpressionVisitException, 
ODataApplicationException, UriParserException {
+  public void filterPMethods() throws Exception {
 
     testFilter.runOnETKeyNav("indexof(PropertyString,'47') eq 5")
         .is("<<indexof(<PropertyString>,<'47'>)> eq <5>>")
@@ -4465,7 +4463,7 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void runLamdbaFunctions() throws ExpressionVisitException, 
ODataApplicationException, UriParserException {
+  public void lambdaFunctions() throws Exception {
 
     testFilter.runOnETKeyNav("any(d:d/PropertyInt16 eq 1)")
         .is("<<ANY;<<d/PropertyInt16> eq <1>>>>")
@@ -4612,7 +4610,7 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void runIsOf() throws ExpressionVisitException, 
ODataApplicationException, UriParserException {
+  public void runIsOf() throws Exception {
 
     testFilter.runOnETKeyNav("isof(olingo.odata.test1.ETTwoKeyNav)")
         .is("<isof(<olingo.odata.test1.ETTwoKeyNav>)>")
@@ -4757,7 +4755,7 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void testHas() throws ExpressionVisitException, 
ODataApplicationException, UriParserException {
+  public void has() throws Exception {
 
     testFilter.runOnETMixEnumDefCollComp("PropertyEnumString has 
olingo.odata.test1.ENString'String1'")
         .is("<<PropertyEnumString> has 
<olingo.odata.test1.ENString<String1>>>")
@@ -5086,7 +5084,7 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void testOrderby() throws UriParserException, 
UnsupportedEncodingException {
+  public void orderby() throws Exception {
 
     
testFilter.runOrderByOnETTwoKeyNav("olingo.odata.test1.UFCRTETAllPrimTwoParam("
         + 
"ParameterString=@ParamStringAlias,ParameterInt16=@ParamInt16Alias)/PropertyString
 eq 'SomeString'")
@@ -5429,7 +5427,7 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void testSearch() throws Exception {
+  public void search() throws Exception {
     testUri.run("ESTwoKeyNav", "$search=abc");
     testUri.run("ESTwoKeyNav", "$search=NOT abc");
 
@@ -5462,6 +5460,9 @@ public class TestFullResourcePath {
     testUri.run("ESTwoKeyNav", "$search=abc AND (def    OR  ghi)");
     testUri.run("ESTwoKeyNav", "$search=abc AND (def        ghi)");
 
+    // search in function-import return value
+    testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=1)", "$search=test");
+
     // percent encoded characters
     testUri.run("ESTwoKeyNav", "$search=%41%42%43");
     testUri.run("ESTwoKeyNav", "$search=\"100%25\"");
@@ -5484,7 +5485,6 @@ public class TestFullResourcePath {
 
   /**
    * 
https://tools.oasis-open.org/version-control/browse/wsvn/odata/trunk/spec/ABNF/odata-abnf-testcases.xml
-   * @throws Exception
    */
   @Test
   public void searchQueryPhraseAbnfTestcases() throws Exception {
@@ -5568,10 +5568,10 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void testErrors() {
+  public void errors() {
     
testUri.runEx("FICRTString(wrong1='ABC')/olingo.odata.test1.BFCStringRTESTwoKeyNav()")
         .isExSemantic(MessageKeys.FUNCTION_NOT_FOUND);
-    testUri.runEx("FICRTString(wrong1='ABC', 
wrong2=1)/olingo.odata.test1.BFCStringRTESTwoKeyNav()")
+    
testUri.runEx("FICRTString(wrong1='ABC',wrong2=1)/olingo.odata.test1.BFCStringRTESTwoKeyNav()")
         .isExSemantic(MessageKeys.FUNCTION_NOT_FOUND);
 
     // type filter for entity incompatible
@@ -5620,14 +5620,14 @@ public class TestFullResourcePath {
 
     // Actions must not be followed by anything.
     testUri.runEx(ContainerProvider.AIRT_STRING + "/$value")
-        
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_KIND_BEFORE_VALUE);
+        
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
     testUri.runEx(ContainerProvider.AIRTCT_TWO_PRIM_PARAM + "/PropertyInt16")
-        .isExSemantic(MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS);
+        
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
     testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/"
         + 
"olingo.odata.test1.BAETTwoKeyNavRTETTwoKeyNav/olingo.odata.test1.ETTwoKeyNav")
-        .isExSemantic(MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS);
+        
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
     
testUri.runEx("ESTwoKeyNav/olingo.odata.test1.BAESTwoKeyNavRTESTwoKeyNav/$count")
-        
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_KIND_BEFORE_COUNT);
+        
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
   }
 
   @Test
@@ -5646,7 +5646,7 @@ public class TestFullResourcePath {
   @Test
   public void multipleKeysInResourcePath() throws Exception {
     // See OLINGO-730
-    
testUri.runEx("ESAllPrim(32767)(1)(2)").isExSemantic(MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES);
+    
testUri.runEx("ESAllPrim(32767)(1)(2)").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
   }
 
   @Test
@@ -5705,9 +5705,9 @@ public class TestFullResourcePath {
 
   @Test
   public void navigationWithMoreThanOneKey() throws Exception {
-    
testUri.runEx("ESKeyNav(1)/NavPropertyETTwoKeyNavMany(PropertyInt=1,PropertyString='2')"
-        + "(PropertyInt=1,PropertyString='2')")
-        .isExSemantic(MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES);
+    
testUri.runEx("ESKeyNav(1)/NavPropertyETTwoKeyNavMany(PropertyInt16=1,PropertyString='2')"
+        + "(PropertyInt16=1,PropertyString='2')")
+        .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
   }
 
   @Test
@@ -5724,10 +5724,14 @@ public class TestFullResourcePath {
     
testUri.runEx("FICRTETKeyNav()/SINav").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
     
testUri.runEx("FICRTETKeyNav()/FICRTString()").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
     
testUri.runEx("FICRTETKeyNav()/AIRTString").isExSemantic(MessageKeys.PROPERTY_NOT_IN_TYPE);
-    
testUri.runEx("AIRTESAllPrimParam/ESAllPrim(0)").isExSemantic(MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS);
-    
testUri.runEx("AIRTESAllPrimParam/SINav").isExSemantic(MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS);
-    
testUri.runEx("AIRTESAllPrimParam/FICRTString()").isExSemantic(MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS);
-    
testUri.runEx("AIRTESAllPrimParam/AIRTString").isExSemantic(MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS);
+    testUri.runEx("AIRTESAllPrimParam/ESAllPrim(0)")
+        
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
+    testUri.runEx("AIRTESAllPrimParam/SINav")
+        
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
+    testUri.runEx("AIRTESAllPrimParam/FICRTString()")
+        
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
+    testUri.runEx("AIRTESAllPrimParam/AIRTString")
+        
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_RESOURCE_PATH);
   }
 
   @Test
@@ -5737,7 +5741,7 @@ public class TestFullResourcePath {
   }
 
   @Test
-  public void testFirstResourcePathWithNamespace() {
+  public void firstResourcePathWithNamespace() {
     
testUri.runEx("olingo.odata.test1.ESAllPrim").isExSemantic(MessageKeys.NAMESPACE_NOT_ALLOWED_AT_FIRST_ELEMENT);
     
testUri.runEx("olingo.odata.test1.ESAllPrim(0)").isExSemantic(MessageKeys.NAMESPACE_NOT_ALLOWED_AT_FIRST_ELEMENT);
     
testUri.runEx("olingo.odata.test1.FINRTInt16()").isExSemantic(MessageKeys.NAMESPACE_NOT_ALLOWED_AT_FIRST_ELEMENT);
@@ -5764,7 +5768,7 @@ public class TestFullResourcePath {
     Mockito.when(entityType.getFullQualifiedName()).thenReturn(nameETNavProp);
     
Mockito.when(entityType.getKeyPredicateNames()).thenReturn(Collections.singletonList(keyPropertyName));
     
Mockito.when(entityType.getKeyPropertyRefs()).thenReturn(Collections.singletonList(keyPropertyRef));
-    
Mockito.when(entityType.getProperty(entitySetName)).thenReturn(navProperty);
+    
Mockito.when(entityType.getNavigationProperty(entitySetName)).thenReturn(navProperty);
     Mockito.when(navProperty.getType()).thenReturn(entityType);
     EdmEntitySet entitySet = Mockito.mock(EdmEntitySet.class);
     Mockito.when(entitySet.getName()).thenReturn(entitySetName);
@@ -5772,7 +5776,7 @@ public class TestFullResourcePath {
     EdmEntityContainer container = Mockito.mock(EdmEntityContainer.class);
     Mockito.when(container.getEntitySet(entitySetName)).thenReturn(entitySet);
     Edm mockedEdm = Mockito.mock(Edm.class);
-    Mockito.when(mockedEdm.getEntityContainer(null)).thenReturn(container);
+    Mockito.when(mockedEdm.getEntityContainer()).thenReturn(container);
     new TestUriValidator().setEdm(mockedEdm)
         .run("ESNavProp(1)/ESNavProp(2)/ESNavProp(3)/ESNavProp")
         .goPath()
@@ -5886,11 +5890,11 @@ public class TestFullResourcePath {
   @Test
   public void functionsWithComplexParameters() throws Exception {
     testUri.run("ESTwoKeyNav/olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
-        + "(ParameterComp=@p1)", 
"@p1={\"PropertyInt16\":1,\"ProperyString\":\"1\"}")
+        + "(ParameterComp=@p1)", 
"@p1={\"PropertyInt16\":1,\"PropertyString\":\"1\"}")
         .goPath()
         .at(0).isEntitySet("ESTwoKeyNav")
         .at(1).isFunction("BFCESTwoKeyNavRTStringParam").isParameterAlias(0, 
"ParameterComp", "@p1")
-        .isInAliasToValueMap("@p1", 
"{\"PropertyInt16\":1,\"ProperyString\":\"1\"}");
+        .isInAliasToValueMap("@p1", 
"{\"PropertyInt16\":1,\"PropertyString\":\"1\"}");
 
     // Test JSON String lexer rule 
=\"3,Int16=abc},\\\nabc&test%test\b\f\r\t\u0022\\}\\{\\)\\(\\]\\[}
     final String stringValueEncoded = 
"=\\\"3,Int16=abc},\\\\\\nabc%26test%25test\\b\\f\\r\\t\\u0022\\\\}\\\\{\\\\)"
@@ -5899,11 +5903,11 @@ public class TestFullResourcePath {
         + "\\\\(\\\\]\\\\[}";
 
     testUri.run("ESTwoKeyNav/olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
-        + "(ParameterComp=@p1)", 
"@p1={\"PropertyInt16\":1,\"ProperyString\":\"" + stringValueEncoded + "\"}")
+        + "(ParameterComp=@p1)", 
"@p1={\"PropertyInt16\":1,\"PropertyString\":\"" + stringValueEncoded + "\"}")
         .goPath()
         .at(0).isEntitySet("ESTwoKeyNav")
         .at(1).isFunction("BFCESTwoKeyNavRTStringParam").isParameterAlias(0, 
"ParameterComp", "@p1")
-        .isInAliasToValueMap("@p1", 
"{\"PropertyInt16\":1,\"ProperyString\":\"" + stringValueDecoded + "\"}");
+        .isInAliasToValueMap("@p1", 
"{\"PropertyInt16\":1,\"PropertyString\":\"" + stringValueDecoded + "\"}");
 
     testUri.run("ESTwoKeyNav", 
"$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
         + "(ParameterComp={\"PropertyString\":\"Test\",\"PropertyInt16\":1}) 
eq 'Test'")
@@ -5916,24 +5920,24 @@ public class TestFullResourcePath {
         .isParameterText(0, "{\"PropertyString\":\"" + stringValueDecoded + 
"\",\"PropertyInt16\":1}");
 
     testUri.run("ESTwoKeyNav", 
"$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
-        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":1,\"ProperyString\":\"1\"}");
+        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":1,\"PropertyString\":\"1\"}");
 
     testUri.run("ESTwoKeyNav", 
"$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
-        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":1,\"ProperyString\":null}")
+        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":1,\"PropertyString\":null}")
         .goFilter().left().isParameterText(0, null);
 
     testUri.run("ESTwoKeyNav", 
"$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
         + "(ParameterComp=@p1) eq 0&@p1={}");
 
     testUri.run("ESTwoKeyNav", 
"$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
-        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":[1,2,3],\"ProperyString\":\"1\"}");
+        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":[1,2,3],\"PropertyString\":\"1\"}");
 
     testUri.run("ESTwoKeyNav", 
"$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
-        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":[\"1\",\"2\",\"3\"],\"ProperyString\":\"1\"}");
+        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":[\"1\",\"2\",\"3\"],\"PropertyString\":\"1\"}");
 
     testUri.run("ESTwoKeyNav", 
"$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
         + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":[{\"Prop1\":123,\"Prop2\":\"Test\",\"Prop3\":[1,2,3]},"
-        + 
"{\"Prop1\":{\"Prop1\":[\"Prop\\\":{]\"]}}],\"ProperyString\":\"1\"}");
+        + 
"{\"Prop1\":{\"Prop1\":[\"Prop\\\":{]\"]}}],\"PropertyString\":\"1\"}");
 
     
testUri.run("FINRTByteNineParam(ParameterEnum=null,ParameterDef='x',ParameterComp=@c,"
         + 
"ParameterETTwoPrim=@c,CollParameterByte=@e,CollParameterEnum=@e,CollParameterDef=@e,"
@@ -5941,12 +5945,12 @@ public class TestFullResourcePath {
         "@c={}&@e=[]");
 
     testUri.runEx("ESTwoKeyNav/olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
-        + "(ParameterComp=@p1)", 
"@p1={\"PropertyInt16\":1,\"ProperyString\":'1'}")
+        + "(ParameterComp=@p1)", 
"@p1={\"PropertyInt16\":1,\"PropertyString\":'1'}")
         .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
 
     testUri.runEx("ESTwoKeyNav/olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
         + "(ParameterComp={\"PropertyInt16\":1,\"PropertyString\":\"Test\"})")
-        
.isExSemantic(UriParserSemanticException.MessageKeys.COMPLEX_PARAMETER_IN_RESOURCE_PATH);
+        
.isExSemantic(UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE);
 
     
testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=null)")
         .isExValidation(UriValidationException.MessageKeys.MISSING_PARAMETER);
@@ -5959,7 +5963,7 @@ public class TestFullResourcePath {
 
     
testUri.run("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)", 
"@test='null'");
 
-    
testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test, 
UnknownParam=1)", "@test='null'")
+    
testUri.runEx("FICRTCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test,UnknownParam=1)",
 "@test='null'")
         
.isExSemantic(UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND);
 
     
testUri.run("FICRTCollCTTwoPrimTwoParam(ParameterInt16=1,ParameterString=@test)",
 "@test='null'");
@@ -5974,23 +5978,23 @@ public class TestFullResourcePath {
         
.isExSemantic(UriParserSemanticException.MessageKeys.FUNCTION_IMPORT_NOT_ALLOWED);
 
     testUri.runEx("ESTwoKeyNav", 
"$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
-        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":1,\"ProperyString\":\"1\"")
+        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":1,\"PropertyString\":\"1\"")
         .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
 
     testUri.runEx("ESTwoKeyNav", 
"$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
-        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":1,\"ProperyString\":\"1\"}}")
+        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":1,\"PropertyString\":\"1\"}}")
         .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
 
     testUri.runEx("ESTwoKeyNav", 
"$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
-        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":[1,2,3]],\"ProperyString\":\"1\"}")
+        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":[1,2,3]],\"PropertyString\":\"1\"}")
         .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
 
     testUri.runEx("ESTwoKeyNav", 
"$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
-        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":[1,2,3,\"ProperyString\":\"1\"}")
+        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":[1,2,3,\"PropertyString\":\"1\"}")
         .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
 
     testUri.runEx("ESTwoKeyNav", 
"$filter=olingo.odata.test1.BFCESTwoKeyNavRTStringParam"
-        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":[1,2,3},\"ProperyString\":\"1\"}")
+        + "(ParameterComp=@p1) eq 
0&@p1={\"PropertyInt16\":[1,2,3},\"PropertyString\":\"1\"}")
         .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
   }
 

Reply via email to