/*******************************************************************************
 * 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.odata2.core.uri.expression;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
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;
import org.apache.olingo.odata2.api.uri.expression.CommonExpression;
import org.apache.olingo.odata2.api.uri.expression.ExpressionKind;
import org.apache.olingo.odata2.api.uri.expression.ExpressionParserException;
import org.apache.olingo.odata2.api.uri.expression.FilterExpression;
import org.apache.olingo.odata2.api.uri.expression.LiteralExpression;
import org.apache.olingo.odata2.api.uri.expression.MethodExpression;
import org.apache.olingo.odata2.api.uri.expression.MethodOperator;
import org.apache.olingo.odata2.api.uri.expression.UnaryExpression;
import org.apache.olingo.odata2.api.uri.expression.UnaryOperator;
import org.apache.olingo.odata2.core.edm.EdmBoolean;
import org.apache.olingo.odata2.core.edm.EdmSimpleTypeFacadeImpl;

/**
 *  
 */
public class FilterParserImpl implements FilterParser {
  /* do the static initialization */
  protected static Map<String, InfoBinaryOperator> availableBinaryOperators;
  protected static Map<String, InfoMethod> availableMethods;
  protected static Map<String, InfoUnaryOperator> availableUnaryOperators;

  static {
    initAvailTables();
  }

  /* instance attributes */
  protected EdmEntityType resourceEntityType = null;
  protected TokenList tokenList = null;
  protected String curExpression;
  protected String originalFilterString = "";
  protected String decodedFilterString  = "";
  private boolean strictFilter = true;


  /**
   * Creates a new FilterParser implementation
   * @param resourceEntityType EntityType of the resource on which the filter is applied
   */
  public FilterParserImpl(final EdmEntityType resourceEntityType) {
    this.resourceEntityType = resourceEntityType;
  }

  /**
   * Creates a new FilterParser implementation
   * @param resourceEntityType EntityType of the resource on which the filter is applied
   * @param strictFilter boolean check to decide weather to validate filter
   */
  public FilterParserImpl(final EdmEntityType resourceEntityType, boolean strictFilter) {
    this.resourceEntityType = resourceEntityType;
    this.strictFilter = strictFilter;
  }

  /**
   * Creates a new FilterParser implementation
   * @param resourceEntityType EntityType of the resource on which the filter is applied
   * @param strictFilter boolean check to decide weather to validate filter
   * @param originalFilterString String original filter string prior to decoding
   */
  public FilterParserImpl(final EdmEntityType resourceEntityType, boolean strictFilter,
                          String originalFilterString) {
    this.resourceEntityType = resourceEntityType;
    this.strictFilter = strictFilter;
    this.originalFilterString = originalFilterString;
  }

  @Override
  public FilterExpression parseFilterString(final String filterExpression) throws ExpressionParserException,
      ExpressionParserInternalError {
    return parseFilterString(filterExpression, false);
  }

  public FilterExpression parseFilterString(final String filterExpression, final boolean allowOnlyBinary)
      throws ExpressionParserException, ExpressionParserInternalError {
    CommonExpression node = null;
    curExpression = filterExpression;
    decodedFilterString = filterExpression;
    try {
      // Throws TokenizerException and FilterParserException. FilterParserException is caught somewhere above
      tokenList = new Tokenizer(filterExpression).tokenize();
      if (!tokenList.hasTokens()) {
        return new FilterExpressionImpl(filterExpression);
      }
    } catch (TokenizerException tokenizerException) {
      // Tested with TestParserExceptions.TestPMparseFilterString
      throw FilterParserExceptionImpl.createERROR_IN_TOKENIZER(tokenizerException, curExpression);
    }

    try {
      CommonExpression nodeLeft = readElement(null);
      node = readElements(nodeLeft, 0);
    } catch (ExpressionParserException filterParserException) {
      // Add empty filterTree to Exception
      // Tested for original throw point
      filterParserException.setFilterTree(new FilterExpressionImpl(filterExpression));
      throw filterParserException;
    }

    // Post check
    if (tokenList.tokenCount() > tokenList.currentToken) // this indicates that not all tokens have been read
    {
      // Tested with TestParserExceptions.TestPMparseFilterString
      throw FilterParserExceptionImpl.createINVALID_TRAILING_TOKEN_DETECTED_AFTER_PARSING(tokenList
          .elementAt(tokenList.currentToken), filterExpression);
    }

    // Create and return filterExpression node
    if ((allowOnlyBinary == true) && (node.getEdmType() != null)
        && (node.getEdmType() != EdmSimpleTypeKind.Boolean.getEdmSimpleTypeInstance())) {
      // Tested with TestParserExceptions.testAdditionalStuff CASE 9
      throw FilterParserExceptionImpl.createTYPE_EXPECTED_AT(EdmBoolean.getInstance(), node.getEdmType(), 1,
          curExpression);
    }
    if (filterExpression.equals(decodedFilterString)) {
        return new FilterExpressionImpl(filterExpression, node);
    } else {
        return new FilterExpressionImpl(decodedFilterString, node);
    } 
  }

  protected CommonExpression readElements(final CommonExpression leftExpression, final int priority)
      throws ExpressionParserException, ExpressionParserInternalError {
    CommonExpression leftNode = leftExpression;
    CommonExpression rightNode;
    BinaryExpression binaryNode;

    ActualBinaryOperator operator = readBinaryOperator();
    ActualBinaryOperator nextOperator;

    while ((operator != null) && (operator.getOP().getPriority() >= priority)) {
      tokenList.next(); // eat the operator
      rightNode = readElement(leftNode, operator); // throws FilterParserException, FilterParserInternalError
      if (rightNode == null) {
        // Tested with TestParserExceptions.testAdditionalStuff CASE 10
        throw FilterParserExceptionImpl.createEXPRESSION_EXPECTED_AFTER_POS(operator.getToken().getPosition()
            + operator.getToken().getUriLiteral().length(), curExpression);
      }
      nextOperator = readBinaryOperator();

      // It must be "while" because for example in "Filter=a or c eq d and e eq f"
      // after reading the "eq" operator the "and" operator must be consumed too. This is due to the fact that "and" has
      // a higher priority than "or"
      while ((nextOperator != null) && (nextOperator.getOP().getPriority() > operator.getOP().getPriority())) {
        // recurse until the a binary operator with a lower priority is detected
        rightNode = readElements(rightNode, nextOperator.getOP().getPriority());
        nextOperator = readBinaryOperator();
      }

      // Although the member operator is also a binary operator, there is some special handling in the filterTree
      if (operator.getOP().getOperator() == BinaryOperator.PROPERTY_ACCESS) {
        binaryNode = new MemberExpressionImpl(leftNode, rightNode);
      } else {
        binaryNode = new BinaryExpressionImpl(operator.getOP(), leftNode, rightNode, operator.getToken());
      }

      try {
        validateBinaryOperatorTypes(binaryNode);
      } catch (ExpressionParserException expressionException) {
        // Extend the error information
        // Tested for original throw point
        expressionException.setFilterTree(binaryNode);
        throw expressionException;
      }

      leftNode = binaryNode;
      operator = readBinaryOperator();
    }

    // Add special handling for expressions like $filter=notsupportedfunction('a')
    // If this special handling is not in place the error text would be
    // -->Invalid token "(" detected after parsing at position 21 in "notsupportedfunction('a')".
    // with this special handling we ensure that the error text would be

    Token token = tokenList.lookToken();
    if (token != null) {
      if ((leftNode.getKind() == ExpressionKind.PROPERTY) && (tokenList.lookToken().getKind() == TokenKind.OPENPAREN)) {
        // Tested with TestParserExceptions.testAdditionalStuff CASE 2
        throw FilterParserExceptionImpl.createINVALID_METHOD_CALL(leftNode, tokenList.lookPrevToken(), curExpression);
      }
    }

    return leftNode;
  }

  /**
   * Reads the content between parenthesis. Its is expected that the current token is of kind
   * {@link TokenKind#OPENPAREN} because it MUST be check in the calling method ( when read the method name and the '('
   * is read).
   * @return An expression which reflects the content within the parenthesis
   * @throws ExpressionParserException
   * While reading the elements in the parenthesis an error occurred
   * @throws TokenizerMessage
   * The next token did not match the expected token
   */
  protected CommonExpression readParenthesis() throws ExpressionParserException, ExpressionParserInternalError {
    // The existing of a '(' is verified BEFORE this method is called --> so it's a internal error
    Token openParenthesis = tokenList.expectToken(TokenKind.OPENPAREN, true);

    CommonExpression firstExpression = readElement(null);
    CommonExpression parenthesisExpression = readElements(firstExpression, 0);

    // check for ')'
    try {
      tokenList.expectToken(TokenKind.CLOSEPAREN); // TokenizerMessage
    } 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_PARENTHESIS(openParenthesis.getPosition(), curExpression,
          e);
    }
    return parenthesisExpression;
  }

  /**
   * Read the parameters of a method expression
   * @param methodInfo
   * Signature information about the method whose parameters should be read
   * @param methodExpression
   * Method expression to which the read parameters are added
   * @return
   * The method expression input parameter
   * @throws ExpressionParserException
   * @throws ExpressionParserInternalError
   * @throws TokenizerExpectError
   * The next token did not match the expected token
   */
  protected MethodExpression readParameters(final InfoMethod methodInfo, final MethodExpressionImpl methodExpression,
      final Token methodToken) throws ExpressionParserException, ExpressionParserInternalError {
    CommonExpression expression;
    boolean expectAnotherExpression = false;
    boolean readComma = true;

    // The existing of a '(' is verified BEFORE this method is called --> so it's a internal error
    Token openParenthesis = tokenList.expectToken(TokenKind.OPENPAREN, true); // throws FilterParserInternalError

    Token token = tokenList.lookToken();
    if (token == null) {
      // Tested with TestParserExceptions.TestPMreadParameters CASE 1 e.g. "$filter=concat("
      throw FilterParserExceptionImpl.createEXPRESSION_EXPECTED_AFTER_POS(openParenthesis, curExpression);
    }

    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_PARENTHESIS_EXPECTED_AFTER_POS(tokenList
            .lookPrevToken(), curExpression);
      }
      expression = readElement(null);
      if (expression != null) {
        expression = readElements(expression, 0);
      }

      if ((expression == null) && (expectAnotherExpression == true)) {
        // Tested with TestParserExceptions.TestPMreadParameters CASE 4 e.g. "$filter=concat(,"
        throw FilterParserExceptionImpl.createEXPRESSION_EXPECTED_AFTER_POS(token, curExpression);
      } else if (expression != null) {// parameter list may be empty
        methodExpression.appendParameter(expression);
      }

      token = tokenList.lookToken();
      if (token == null) {
        // Tested with TestParserExceptions.TestPMreadParameters CASE 2 e.g. "$filter=concat(123"
        throw FilterParserExceptionImpl.createCOMMA_OR_CLOSING_PARENTHESIS_EXPECTED_AFTER_POS(tokenList
            .lookPrevToken(), curExpression);
      }

      if (token.getKind() == TokenKind.COMMA) {
        expectAnotherExpression = true;
        if (expression == null) {
          // Tested with TestParserExceptions.TestPMreadParameters CASE 3 e.g. "$filter=concat(,"
          throw FilterParserExceptionImpl.createEXPRESSION_EXPECTED_AT_POS(token, curExpression);
        }

        tokenList.expectToken(",", true);
        readComma = true;
      } else {
        readComma = false;
      }
    }

    // because the while loop above only exits if a ')' has been found it is an
    // internal error if there is not ')'
    tokenList.expectToken(TokenKind.CLOSEPAREN, true);

    // ---check parameter count
    int count = methodExpression.getParameters().size();
    if ((methodInfo.getMinParameter() > -1) && (count < methodInfo.getMinParameter())) {
      // Tested with TestParserExceptions.TestPMreadParameters CASE 12
      throw FilterParserExceptionImpl.createMETHOD_WRONG_ARG_COUNT(methodExpression, methodToken, curExpression);
    }

    if ((methodInfo.getMaxParameter() > -1) && (count > methodInfo.getMaxParameter())) {
      // Tested with TestParserExceptions.TestPMreadParameters CASE 15
      throw FilterParserExceptionImpl.createMETHOD_WRONG_ARG_COUNT(methodExpression, methodToken, curExpression);
    }

    return methodExpression;
  }

  protected CommonExpression readElement(final CommonExpression leftExpression) throws ExpressionParserException,
      ExpressionParserInternalError {
    return readElement(leftExpression, null);
  }

  /**
   * Reads: Unary operators, Methods, Properties, ...
   * but not binary operators which are handelt in {@link #readElements(CommonExpression, int)}
   * @param leftExpression
   * Used while parsing properties. In this case ( e.g. parsing "a/b") the property "a" ( as leftExpression of "/") is
   * relevant
   * to verify whether the property "b" exists inside the edm
   * @return a CommonExpression
   * @throws ExpressionParserException
   * @throws ExpressionParserInternalError
   * @throws TokenizerMessage
   */
  protected CommonExpression
      readElement(final CommonExpression leftExpression, final ActualBinaryOperator leftOperator)
          throws ExpressionParserException, ExpressionParserInternalError {
    CommonExpression node = null;
    Token token;
    Token lookToken;
    lookToken = tokenList.lookToken();
    if (lookToken == null) {
      return null;
    }

    switch (lookToken.getKind()) {
    case OPENPAREN:
      node = readParenthesis();
      return node;
    case CLOSEPAREN: // ')' finishes a parenthesis (it is no extra token)" +
    case COMMA: // . " ','  is a separator for function parameters (it is no extra token)" +
      return null;
    default:
      // continue
    }

    // -->Check if the token is a unary operator
    InfoUnaryOperator unaryOperator = isUnaryOperator(lookToken);
    if (unaryOperator != null) {
      return readUnaryoperator(lookToken, unaryOperator);
    }

    // ---expect the look ahead token
    token = tokenList.expectToken(lookToken.getUriLiteral(), true);
    lookToken = tokenList.lookToken();

    // -->Check if the token is a method
    // To avoid name clashes between method names and property names we accept here only method names if a "(" follows.
    // Hence the parser accepts a property named "concat"
    InfoMethod methodOperator = isMethod(token, lookToken);
    if (methodOperator != null) {
      return readMethod(token, methodOperator);
    }

    // -->Check if token is a terminal
    // is a terminal e.g. a Value like an EDM.String 'hugo' or 125L or 1.25D"
    if (token.getKind() == TokenKind.SIMPLE_TYPE) {
    	 LiteralExpression literal = new LiteralExpressionImpl(
       		  getEncodedUriLiteral(token.getUriLiteral(),token.getPosition()), token.getJavaLiteral());
      return literal;
    }

    // -->Check if token is a property, e.g. "name" or "address"
    if (token.getKind() == TokenKind.LITERAL) {
      PropertyExpressionImpl property = new PropertyExpressionImpl(token.getUriLiteral(), token.getJavaLiteral());
      validateEdmProperty(leftExpression, property, token, leftOperator);
      return property;
    }

    // not Tested, should not occur
    throw ExpressionParserInternalError.createCOMMON();
  }

  protected CommonExpression readUnaryoperator(final Token lookToken, final InfoUnaryOperator unaryOperator)
      throws ExpressionParserException, ExpressionParserInternalError {
    tokenList.expectToken(lookToken.getUriLiteral(), true);

    CommonExpression operand = readElement(null);
    UnaryExpression unaryExpression = new UnaryExpressionImpl(unaryOperator, operand);
    validateUnaryOperatorTypes(unaryExpression); // throws ExpressionInvalidOperatorTypeException

    return unaryExpression;
  }

  protected CommonExpression readMethod(final Token token, final InfoMethod methodOperator)
      throws ExpressionParserException, ExpressionParserInternalError {
    MethodExpressionImpl method = new MethodExpressionImpl(methodOperator);

    readParameters(methodOperator, method, token);
    validateMethodTypes(method, token); // throws ExpressionInvalidOperatorTypeException

    return method;
  }

  protected ActualBinaryOperator readBinaryOperator() {
    InfoBinaryOperator operator = null;
    Token token = tokenList.lookToken();
    if (token == null) {
      return null;
    }
    if ((token.getKind() == TokenKind.SYMBOL) && ("/".equals(token.getUriLiteral()))) {
      operator = availableBinaryOperators.get(token.getUriLiteral());
    } else if (token.getKind() == TokenKind.LITERAL) {
      operator = availableBinaryOperators.get(token.getUriLiteral());
    }

    if (operator == null) {
      return null;
    }

    return new ActualBinaryOperator(operator, token);
  }

  /**
   * Check if a token is a UnaryOperator ( e.g. "not" or "-" )
   * 
   * @param token Token to be checked
   * 
   * @return
   * <li>An instance of {@link InfoUnaryOperator} containing information about the specific unary operator</li>
   * <li><code>null</code> if the token is not an unary operator</li>
   */
  protected InfoUnaryOperator isUnaryOperator(final Token token) {
    if ((token.getKind() == TokenKind.LITERAL) || (token.getKind() == TokenKind.SYMBOL)) {
      InfoUnaryOperator operator = availableUnaryOperators.get(token.getUriLiteral());
      return operator;
    }
    return null;
  }

  protected InfoMethod isMethod(final Token token, final Token lookToken) {
    if ((lookToken != null) && (lookToken.getKind() == TokenKind.OPENPAREN)) {
      return availableMethods.get(token.getUriLiteral());
    }
    return null;
  }

  protected void validateEdmProperty(final CommonExpression leftExpression, final PropertyExpressionImpl property,
      final Token propertyToken, final ActualBinaryOperator actBinOp) throws ExpressionParserException,
      ExpressionParserInternalError {

    // Exit if no edm provided
    if (resourceEntityType == null) {
      return;
    }

    if (leftExpression == null) {
      // e.g. "$filter=city eq 'Hong Kong'" --> "city" is checked against the resource entity type of the last URL
      // segment
      validateEdmPropertyOfStructuredType(resourceEntityType, property, propertyToken);
      return;
    }
    // e.g. "$filter='Hong Kong' eq address/city" --> city is "checked" against the type of the property "address".
    // "address" itself must be a (navigation)property of the resource entity type of the last URL segment AND
    // "address" must have a structural edm type
    EdmType parentType = leftExpression.getEdmType(); // parentType point now to the type of property "address"

    if ((actBinOp != null) && (actBinOp.operator.getOperator() != BinaryOperator.PROPERTY_ACCESS)) {
      validateEdmPropertyOfStructuredType(resourceEntityType, property, propertyToken);
      return;
    } else {
      if ((leftExpression.getKind() != ExpressionKind.PROPERTY) &&
          (leftExpression.getKind() != ExpressionKind.MEMBER)) {
        if (actBinOp != null) {
          // Tested with TestParserExceptions.TestPMvalidateEdmProperty CASE 6
          throw FilterParserExceptionImpl.createLEFT_SIDE_NOT_A_PROPERTY(actBinOp.token, curExpression);
        } else {
          // not Tested, should not occur
          throw ExpressionParserInternalError.createCOMMON();
        }

      }
    }

    if (parentType instanceof EdmEntityType) {
      // e.g. "$filter='Hong Kong' eq navigationProp/city" --> "navigationProp" is a navigation property with a entity
      // type
      validateEdmPropertyOfStructuredType((EdmStructuralType) parentType, property, propertyToken);
    } else if (parentType instanceof EdmComplexType) {
      // e.g. "$filter='Hong Kong' eq address/city" --> "address" is a property with a complex type
      validateEdmPropertyOfStructuredType((EdmStructuralType) parentType, property, propertyToken);
    } else {
      // e.g. "$filter='Hong Kong' eq name/city" --> "name is of type String"
      // Tested with TestParserExceptions.TestPMvalidateEdmProperty CASE 5
      throw FilterParserExceptionImpl.createLEFT_SIDE_NOT_STRUCTURAL_TYPE(parentType, property, propertyToken,
          curExpression);
    }

    return;
  }

  protected void validateEdmPropertyOfStructuredType(final EdmStructuralType parentType,
      final PropertyExpressionImpl property, final Token propertyToken) throws ExpressionParserException,
      ExpressionParserInternalError {
    try {
      String propertyName = property.getUriLiteral();
      EdmTyped edmProperty = parentType.getProperty(propertyName);

      if (edmProperty != null) {
        property.setEdmProperty(edmProperty);
        property.setEdmType(edmProperty.getType());
        if(isLastFilterElement(propertyName)) {
          if (edmProperty.getMultiplicity() == EdmMultiplicity.MANY && strictFilter) {
            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,
            curExpression);
      }

    } catch (EdmException e) {
      // not Tested, should not occur
      throw ExpressionParserInternalError.createERROR_ACCESSING_EDM(e);
    }
  }

  /**
   * Check if the property name is the last or only element of the filter
   * @param propertyName name of the property
   * @return <code>true</code> if this is the last or only otherwise <code>false</code>
   */
  private boolean isLastFilterElement(String propertyName) {
    return curExpression.contains(propertyName + " ");
  }

  protected void validateUnaryOperatorTypes(final UnaryExpression unaryExpression)
      throws ExpressionParserInternalError {
    InfoUnaryOperator unOpt = availableUnaryOperators.get(unaryExpression.getOperator().toUriLiteral());
    EdmType operandType = unaryExpression.getOperand().getEdmType();

    if ((operandType == null) && (resourceEntityType == null)) {
      return;
    }

    List<EdmType> actualParameterTypes = new ArrayList<EdmType>();
    actualParameterTypes.add(operandType);

    ParameterSet parameterSet = unOpt.validateParameterSet(actualParameterTypes);
    if (parameterSet != null) {
      unaryExpression.setEdmType(parameterSet.getReturnType());
    }
  }

  protected void validateBinaryOperatorTypes(final BinaryExpression binaryExpression) throws ExpressionParserException,
      ExpressionParserInternalError {
    InfoBinaryOperator binOpt = availableBinaryOperators.get(binaryExpression.getOperator().toUriLiteral());

    List<EdmType> actualParameterTypes = new ArrayList<EdmType>();
    final EdmType leftType = binaryExpression.getLeftOperand().getEdmType();
    if (leftType == null && resourceEntityType == null) {
      return;
    }
    actualParameterTypes.add(leftType);

    final EdmType rightType = binaryExpression.getRightOperand().getEdmType();
    if (rightType == null && resourceEntityType == null) {
      return;
    }
    actualParameterTypes.add(rightType);

    // special case for navigation property (non-)equality comparison with null
    if ("Equality".equals(binOpt.getCategory())
        && (leftType != null && leftType.getKind() == EdmTypeKind.ENTITY
            && rightType == EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Null)
            || leftType == EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Null)
            && rightType != null && rightType.getKind() == EdmTypeKind.ENTITY)) {
      binaryExpression.setEdmType(EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Boolean));
      return;
    }

    final ParameterSet parameterSet = binOpt.validateParameterSet(actualParameterTypes);
    if (parameterSet == null) {
      BinaryExpressionImpl binaryExpressionImpl = (BinaryExpressionImpl) binaryExpression;

      // Tested with TestParserExceptions.TestPMvalidateBinaryOperator
      throw FilterParserExceptionImpl.createINVALID_TYPES_FOR_BINARY_OPERATOR(binaryExpression.getOperator(),
          binaryExpression.getLeftOperand().getEdmType(), binaryExpression.getRightOperand().getEdmType(),
          binaryExpressionImpl.getToken(), curExpression);
    }
    binaryExpression.setEdmType(parameterSet.getReturnType());
  }

  protected void validateMethodTypes(final MethodExpression methodExpression, final Token methodToken)
      throws ExpressionParserException, ExpressionParserInternalError {
    InfoMethod methOpt = availableMethods.get(methodExpression.getUriLiteral());

    List<EdmType> actualParameterTypes = new ArrayList<EdmType>();

    // If there are no parameter then don't perform a type check
    if (methodExpression.getParameters().isEmpty()) {
      return;
    }

    for (CommonExpression parameter : methodExpression.getParameters()) {
      // 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) {
        return;
      }
      actualParameterTypes.add(parameter.getEdmType());
    }

    ParameterSet parameterSet = methOpt.validateParameterSet(actualParameterTypes);
    // If there is not returntype then the input parameter
    if (parameterSet == null) {
      // Tested with TestParserExceptions.testPMvalidateMethodTypes CASE 1
      throw FilterParserExceptionImpl.createMETHOD_WRONG_INPUT_TYPE((MethodExpressionImpl) methodExpression,
          methodToken, curExpression);
    }
    methodExpression.setEdmType(parameterSet.getReturnType());
  }
  
  /*
   * In case we have + in the string literal and is replaced with ' '(space) in UriParserImpl
   * it needs to be changed back to +
   */
  private String getEncodedUriLiteral(String uriLiteral,int pos) {
	  if (originalFilterString.length()!=0 && uriLiteral.contains(" ")) {
			String encodedUriLiteral = uriLiteral.replaceAll(" ", "+");
			String originalFilterToken = originalFilterString.substring(pos,pos+uriLiteral.length());
			if (originalFilterToken!=null && originalFilterToken.equals(encodedUriLiteral)) {
				decodedFilterString=decodedFilterString.substring(0, pos)+encodedUriLiteral+
						decodedFilterString.substring(pos+uriLiteral.length());
				uriLiteral = encodedUriLiteral;
			}
		}
	  return uriLiteral;
  }   

  static void initAvailTables() {
    Map<String, InfoBinaryOperator> lAvailableBinaryOperators = new HashMap<String, InfoBinaryOperator>();
    Map<String, InfoMethod> lAvailableMethods = new HashMap<String, InfoMethod>();
    Map<String, InfoUnaryOperator> lAvailableUnaryOperators = new HashMap<String, InfoUnaryOperator>();

    // create type validators
    ParameterSetCombination combination = null;
    // create type helpers
    EdmSimpleType boolean_ = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Boolean);
    EdmSimpleType sbyte = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.SByte);
    EdmSimpleType byte_ = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Byte);
    EdmSimpleType int16 = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Int16);
    EdmSimpleType int32 = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Int32);
    EdmSimpleType int64 = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Int64);
    EdmSimpleType single = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Single);
    EdmSimpleType double_ = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Double);
    EdmSimpleType decimal = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Decimal);
    EdmSimpleType string = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.String);
    EdmSimpleType time = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Time);
    EdmSimpleType datetime = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.DateTime);
    EdmSimpleType datetimeoffset = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.DateTimeOffset);
    EdmSimpleType guid = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Guid);
    EdmSimpleType binary = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Binary);
    EdmSimpleType null_ = EdmSimpleTypeFacadeImpl.getEdmSimpleType(EdmSimpleTypeKind.Null);

    // ---Member member access---
    lAvailableBinaryOperators.put("/", new InfoBinaryOperator(BinaryOperator.PROPERTY_ACCESS, "Primary", 100,
        new ParameterSetCombination.PSCReturnTypeEqLastParameter()));// todo fix this

    // ---Multiplicative---
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(sbyte, sbyte, sbyte));
    combination.add(new ParameterSet(byte_, byte_, byte_));
    combination.add(new ParameterSet(int16, int16, int16));
    combination.add(new ParameterSet(int32, int32, int32));
    combination.add(new ParameterSet(int64, int64, int64));
    combination.add(new ParameterSet(single, single, single));
    combination.add(new ParameterSet(double_, double_, double_));
    combination.add(new ParameterSet(decimal, decimal, decimal));
        
    combination.add(new ParameterSet(sbyte, sbyte, null_));
    combination.add(new ParameterSet(sbyte, null_, sbyte));
    combination.add(new ParameterSet(byte_, byte_, null_));
    combination.add(new ParameterSet(byte_, null_, byte_));
    
    combination.add(new ParameterSet(int16, int16, null_));
    combination.add(new ParameterSet(int16, null_, int16));
    combination.add(new ParameterSet(int32, int32, null_));
    combination.add(new ParameterSet(int32, null_, int32));
    combination.add(new ParameterSet(int64, int64, null_));
    combination.add(new ParameterSet(int64, null_, int64));
    
    combination.add(new ParameterSet(single, single, null_));
    combination.add(new ParameterSet(single, null_, single));
    combination.add(new ParameterSet(double_, double_, null_));
    combination.add(new ParameterSet(double_, null_, double_));
    combination.add(new ParameterSet(decimal, decimal, null_));
    combination.add(new ParameterSet(decimal, null_, decimal));

    lAvailableBinaryOperators.put(BinaryOperator.MUL.toUriLiteral(), new InfoBinaryOperator(BinaryOperator.MUL,
        "Multiplicative", 60, combination));
    lAvailableBinaryOperators.put(BinaryOperator.DIV.toUriLiteral(), new InfoBinaryOperator(BinaryOperator.DIV,
        "Multiplicative", 60, combination));
    lAvailableBinaryOperators.put(BinaryOperator.MODULO.toUriLiteral(), new InfoBinaryOperator(BinaryOperator.MODULO,
        "Multiplicative", 60, combination));

    // ---Additive---
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(sbyte, sbyte, sbyte));
    combination.add(new ParameterSet(byte_, byte_, byte_));
    combination.add(new ParameterSet(int16, int16, int16));
    combination.add(new ParameterSet(int32, int32, int32));
    combination.add(new ParameterSet(int64, int64, int64));
    combination.add(new ParameterSet(single, single, single));
    combination.add(new ParameterSet(double_, double_, double_));
    combination.add(new ParameterSet(decimal, decimal, decimal));
    
    combination.add(new ParameterSet(sbyte, sbyte, null_));
    combination.add(new ParameterSet(sbyte, null_, sbyte));
    combination.add(new ParameterSet(byte_, byte_, null_));
    combination.add(new ParameterSet(byte_, null_, byte_));
    
    combination.add(new ParameterSet(int16, int16, null_));
    combination.add(new ParameterSet(int16, null_, int16));
    combination.add(new ParameterSet(int32, int32, null_));
    combination.add(new ParameterSet(int32, null_, int32));
    combination.add(new ParameterSet(int64, int64, null_));
    combination.add(new ParameterSet(int64, null_, int64));
    
    combination.add(new ParameterSet(single, single, null_));
    combination.add(new ParameterSet(single, null_, single));
    combination.add(new ParameterSet(double_, double_, null_));
    combination.add(new ParameterSet(double_, null_, double_));
    combination.add(new ParameterSet(decimal, decimal, null_));
    combination.add(new ParameterSet(decimal, null_, decimal));

    lAvailableBinaryOperators.put(BinaryOperator.ADD.toUriLiteral(), new InfoBinaryOperator(BinaryOperator.ADD,
        "Additive", 50, combination));
    lAvailableBinaryOperators.put(BinaryOperator.SUB.toUriLiteral(), new InfoBinaryOperator(BinaryOperator.SUB,
        "Additive", 50, combination));

    // ---Relational---
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(boolean_, string, string));
    combination.add(new ParameterSet(boolean_, time, time));
    combination.add(new ParameterSet(boolean_, datetime, datetime));
    combination.add(new ParameterSet(boolean_, datetimeoffset, datetimeoffset));
    combination.add(new ParameterSet(boolean_, guid, guid));
    combination.add(new ParameterSet(boolean_, sbyte, sbyte));
    combination.add(new ParameterSet(boolean_, byte_, byte_));
    combination.add(new ParameterSet(boolean_, int16, int16));
    combination.add(new ParameterSet(boolean_, int32, int32));
    combination.add(new ParameterSet(boolean_, int64, int64));
    combination.add(new ParameterSet(boolean_, single, single));
    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));
    
    combination.add(new ParameterSet(boolean_, time, null_));
    combination.add(new ParameterSet(boolean_, null_, time));
    
    combination.add(new ParameterSet(boolean_, datetime, null_));
    combination.add(new ParameterSet(boolean_, null_, datetime));
    
    combination.add(new ParameterSet(boolean_, datetimeoffset, null_));
    combination.add(new ParameterSet(boolean_, null_, datetimeoffset));
    
    combination.add(new ParameterSet(boolean_, guid, null_));
    combination.add(new ParameterSet(boolean_, null_, guid));
    
    combination.add(new ParameterSet(boolean_, sbyte, null_));
    combination.add(new ParameterSet(boolean_, null_, sbyte));
    combination.add(new ParameterSet(boolean_, byte_, null_));
    combination.add(new ParameterSet(boolean_, null_, byte_));
    
    combination.add(new ParameterSet(boolean_, int16, null_));
    combination.add(new ParameterSet(boolean_, null_, int16));
    combination.add(new ParameterSet(boolean_, int32, null_));
    combination.add(new ParameterSet(boolean_, null_, int32));
    combination.add(new ParameterSet(boolean_, int64, null_));
    combination.add(new ParameterSet(boolean_, null_, int64));
    
    combination.add(new ParameterSet(boolean_, single, null_));
    combination.add(new ParameterSet(boolean_, null_, single));
    combination.add(new ParameterSet(boolean_, double_, null_));
    combination.add(new ParameterSet(boolean_, null_, double_));
    combination.add(new ParameterSet(boolean_, decimal, null_));
    combination.add(new ParameterSet(boolean_, null_, decimal));
    
    combination.add(new ParameterSet(boolean_, binary, null_));
    combination.add(new ParameterSet(boolean_, null_, binary));
      

    lAvailableBinaryOperators.put(BinaryOperator.LT.toUriLiteral(), new InfoBinaryOperator(BinaryOperator.LT,
        "Relational", 40, combination));
    lAvailableBinaryOperators.put(BinaryOperator.GT.toUriLiteral(), new InfoBinaryOperator(BinaryOperator.GT,
        "Relational", 40, combination));
    lAvailableBinaryOperators.put(BinaryOperator.GE.toUriLiteral(), new InfoBinaryOperator(BinaryOperator.GE,
        "Relational", 40, combination));
    lAvailableBinaryOperators.put(BinaryOperator.LE.toUriLiteral(), new InfoBinaryOperator(BinaryOperator.LE,
        "Relational", 40, combination));

    // ---Equality---
    combination.addFirst(new ParameterSet(boolean_, boolean_, boolean_));
    
    combination.add(new ParameterSet(boolean_, boolean_, null_));
    combination.add(new ParameterSet(boolean_, null_, boolean_));

    lAvailableBinaryOperators.put(BinaryOperator.EQ.toUriLiteral(), new InfoBinaryOperator(BinaryOperator.EQ,
        "Equality", 30, combination));
    lAvailableBinaryOperators.put(BinaryOperator.NE.toUriLiteral(), new InfoBinaryOperator(BinaryOperator.NE,
        "Equality", 30, combination));

    // "---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,
        "Conditional", 20, combination));

    // ---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,
        "Conditional", 10, combination));

    // endswith
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(boolean_, string, string));
    lAvailableMethods.put(MethodOperator.ENDSWITH.toUriLiteral(), new InfoMethod(MethodOperator.ENDSWITH, 2, 2,
        combination));

    // indexof
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(int32, string, string));
    lAvailableMethods.put(MethodOperator.INDEXOF.toUriLiteral(), new InfoMethod(MethodOperator.INDEXOF, 2, 2,
        combination));

    // startswith
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(boolean_, string, string));
    lAvailableMethods.put(MethodOperator.STARTSWITH.toUriLiteral(), new InfoMethod(MethodOperator.STARTSWITH, 2, 2,
        combination));

    // tolower
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(string, string));
    lAvailableMethods.put(MethodOperator.TOLOWER.toUriLiteral(), new InfoMethod(MethodOperator.TOLOWER, combination));

    // toupper
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(string, string));
    lAvailableMethods.put(MethodOperator.TOUPPER.toUriLiteral(), new InfoMethod(MethodOperator.TOUPPER, combination));

    // trim
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(string, string));
    lAvailableMethods.put(MethodOperator.TRIM.toUriLiteral(), new InfoMethod(MethodOperator.TRIM, combination));

    // substring
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(string, string, int32));
    combination.add(new ParameterSet(string, string, int32, int32));
    lAvailableMethods.put(MethodOperator.SUBSTRING.toUriLiteral(), new InfoMethod(MethodOperator.SUBSTRING, 1, -1,
        combination));

    // substringof
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(boolean_, string, string));
    lAvailableMethods.put(MethodOperator.SUBSTRINGOF.toUriLiteral(), new InfoMethod(MethodOperator.SUBSTRINGOF, 1, -1,
        combination));
    
    // replace
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(string, string, string, string));
    lAvailableMethods.put(MethodOperator.REPLACE.toUriLiteral(), new InfoMethod(MethodOperator.REPLACE, 3, 3,
        combination));

    // concat
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(string, string, string).setFurtherType(string));
    lAvailableMethods.put(MethodOperator.CONCAT.toUriLiteral(), new InfoMethod(MethodOperator.CONCAT, 2, -1,
        combination));

    // length
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(int32, string));
    lAvailableMethods.put(MethodOperator.LENGTH.toUriLiteral(), new InfoMethod(MethodOperator.LENGTH, combination));

    // year
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(int32, datetime));
    lAvailableMethods.put(MethodOperator.YEAR.toUriLiteral(), new InfoMethod(MethodOperator.YEAR, combination));

    // month
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(int32, datetime));
    lAvailableMethods.put(MethodOperator.MONTH.toUriLiteral(), new InfoMethod(MethodOperator.MONTH, combination));

    // day
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(int32, datetime));
    lAvailableMethods.put(MethodOperator.DAY.toUriLiteral(), new InfoMethod(MethodOperator.DAY, combination));

    // hour
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(int32, datetime));
    combination.add(new ParameterSet(int32, time));
    combination.add(new ParameterSet(int32, datetimeoffset));
    lAvailableMethods.put(MethodOperator.HOUR.toUriLiteral(), new InfoMethod(MethodOperator.HOUR, combination));

    // minute
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(int32, datetime));
    combination.add(new ParameterSet(int32, time));
    combination.add(new ParameterSet(int32, datetimeoffset));
    lAvailableMethods.put(MethodOperator.MINUTE.toUriLiteral(), new InfoMethod(MethodOperator.MINUTE, combination));

    // second
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(int32, datetime));
    combination.add(new ParameterSet(int32, time));
    combination.add(new ParameterSet(int32, datetimeoffset));
    lAvailableMethods.put(MethodOperator.SECOND.toUriLiteral(), new InfoMethod(MethodOperator.SECOND, combination));

    // round
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(decimal, decimal));
    combination.add(new ParameterSet(double_, double_));
    lAvailableMethods.put(MethodOperator.ROUND.toUriLiteral(), new InfoMethod(MethodOperator.ROUND, combination));

    // ceiling
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(decimal, decimal));
    combination.add(new ParameterSet(double_, double_));
    lAvailableMethods.put(MethodOperator.CEILING.toUriLiteral(), new InfoMethod(MethodOperator.CEILING, combination));

    // floor
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(decimal, decimal));
    combination.add(new ParameterSet(double_, double_));
    lAvailableMethods.put(MethodOperator.FLOOR.toUriLiteral(), new InfoMethod(MethodOperator.FLOOR, combination));

    // ---unary---

    // minus
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(sbyte, sbyte));
    combination.add(new ParameterSet(byte_, byte_));
    combination.add(new ParameterSet(int16, int16));
    combination.add(new ParameterSet(int32, int32));
    combination.add(new ParameterSet(int64, int64));
    combination.add(new ParameterSet(single, single));
    combination.add(new ParameterSet(double_, double_));
    combination.add(new ParameterSet(decimal, decimal));
    combination.add(new ParameterSet(null_, null_));
    

    // minus
    lAvailableUnaryOperators.put(UnaryOperator.MINUS.toUriLiteral(), new InfoUnaryOperator(UnaryOperator.MINUS,
        "minus", combination));

    // not
    combination = new ParameterSetCombination.PSCflex();
    combination.add(new ParameterSet(boolean_, boolean_));
    combination.add(new ParameterSet(null_, null_));
    lAvailableUnaryOperators.put(UnaryOperator.NOT.toUriLiteral(), new InfoUnaryOperator(UnaryOperator.NOT, "not",
        combination));

    availableBinaryOperators = Collections.unmodifiableMap(lAvailableBinaryOperators);
    availableMethods = Collections.unmodifiableMap(lAvailableMethods);
    availableUnaryOperators = Collections.unmodifiableMap(lAvailableUnaryOperators);
  }
}
