/*******************************************************************************
 * 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;

import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.olingo.odata2.api.commons.InlineCount;
import org.apache.olingo.odata2.api.edm.Edm;
import org.apache.olingo.odata2.api.edm.EdmComplexType;
import org.apache.olingo.odata2.api.edm.EdmEntityContainer;
import org.apache.olingo.odata2.api.edm.EdmEntitySet;
import org.apache.olingo.odata2.api.edm.EdmEntityType;
import org.apache.olingo.odata2.api.edm.EdmException;
import org.apache.olingo.odata2.api.edm.EdmFacets;
import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
import org.apache.olingo.odata2.api.edm.EdmLiteral;
import org.apache.olingo.odata2.api.edm.EdmLiteralException;
import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
import org.apache.olingo.odata2.api.edm.EdmParameter;
import org.apache.olingo.odata2.api.edm.EdmProperty;
import org.apache.olingo.odata2.api.edm.EdmSimpleType;
import org.apache.olingo.odata2.api.edm.EdmSimpleTypeFacade;
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.exception.MessageReference;
import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
import org.apache.olingo.odata2.api.exception.ODataException;
import org.apache.olingo.odata2.api.exception.ODataMessageException;
import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
import org.apache.olingo.odata2.api.uri.KeyPredicate;
import org.apache.olingo.odata2.api.uri.NavigationPropertySegment;
import org.apache.olingo.odata2.api.uri.PathSegment;
import org.apache.olingo.odata2.api.uri.SelectItem;
import org.apache.olingo.odata2.api.uri.UriInfo;
import org.apache.olingo.odata2.api.uri.UriNotMatchingException;
import org.apache.olingo.odata2.api.uri.UriParser;
import org.apache.olingo.odata2.api.uri.UriSyntaxException;
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.OrderByExpression;
import org.apache.olingo.odata2.core.ODataPathSegmentImpl;
import org.apache.olingo.odata2.core.commons.Decoder;
import org.apache.olingo.odata2.core.edm.EdmSimpleTypeFacadeImpl;
import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
import org.apache.olingo.odata2.core.uri.expression.FilterParserImpl;
import org.apache.olingo.odata2.core.uri.expression.OrderByParserImpl;

/**
 * Parser for the OData part of the URL.
 * 
 */
public class UriParserImpl extends UriParser {

  private static final Pattern INITIAL_SEGMENT_PATTERN = Pattern
      .compile("(?:([^.()]+)\\.)?([^.()]+)(?:\\((.+)\\)|(\\(\\)))?");
  private static final Pattern NAVIGATION_SEGMENT_PATTERN = Pattern.compile("([^()]+)(?:\\((.+)\\)|(\\(\\)))?");
  private static final Pattern NAMED_VALUE_PATTERN = Pattern.compile("(?:([^=]+)=)?([^=]+)");
  private static final char COMMA = ',';
  private static final char SQUOTE = '\'';
  private static final String ACCEPT_FORM_ENCODING = "odata-accept-forms-encoding";

  private final Edm edm;
  private final EdmSimpleTypeFacade simpleTypeFacade;
  private List<String> pathSegments;
  private String currentPathSegment;
  private UriInfoImpl uriResult;
  private Map<SystemQueryOption, String> systemQueryOptions;
  private Map<String, String> otherQueryParameters;

  public UriParserImpl(final Edm edm) {
    this.edm = edm;
    simpleTypeFacade = new EdmSimpleTypeFacadeImpl();
  }

  /**
   * Parse the URI part after an OData service root,
   * already splitted into path segments and query parameters.
   * @param pathSegments the {@link PathSegment}s of the resource path,
   * potentially percent-encoded
   * @param queryParameters the query parameters, already percent-decoded
   * @return a {@link UriInfoImpl} instance containing the parsed information
   */
  @Override
  public UriInfo parse(final List<PathSegment> pathSegments, final Map<String, String> queryParameters)
      throws UriSyntaxException, UriNotMatchingException, EdmException {

    return parseAll(pathSegments, convertFromSingleMapToMultiMap(queryParameters));
  }

  @Override
  public UriInfo parseAll(final List<PathSegment> pathSegments, final Map<String, List<String>> allQueryParameters)
      throws UriSyntaxException, UriNotMatchingException, EdmException {

    this.pathSegments = copyPathSegmentList(pathSegments);
    systemQueryOptions = new HashMap<SystemQueryOption, String>();
    otherQueryParameters = new HashMap<String, String>();
    uriResult = new UriInfoImpl();

    preparePathSegments();

    handleResourcePath();

    distributeQueryParameters(allQueryParameters);
    checkSystemQueryOptionsCompatibility();
    handleSystemQueryOptions();
    handleOtherQueryParameters();

    return uriResult;
  }

  private <T, K> Map<T, List<K>> convertFromSingleMapToMultiMap(final Map<T, K> singleMap) {
    Map<T, List<K>> multiMap = new HashMap<T, List<K>>();

    for (Entry<T, K> entry : singleMap.entrySet()) {
      List<K> valueList = new LinkedList<K>();
      valueList.add(entry.getValue());

      multiMap.put(entry.getKey(), valueList);
    }

    return multiMap;
  }

  private void preparePathSegments() throws UriSyntaxException {
    // Remove an empty path segment at the start of the OData part of the resource path.
    if (!pathSegments.isEmpty() && "".equals(pathSegments.get(0))) {
      pathSegments.remove(0);
    }

    // Remove an empty path segment at the end of the resource path,
    // although there is nothing in the OData specification that would allow that.
    if (!pathSegments.isEmpty() && "".equals(pathSegments.get(pathSegments.size() - 1))) {
      pathSegments.remove(pathSegments.size() - 1);
    }

    // Intermediate empty path segments are an error, however.
    for (String pathSegment : pathSegments) {
      if ("".equals(pathSegment)) {
        throw new UriSyntaxException(UriSyntaxException.EMPTYSEGMENT);
      }
    }
  }

  private void handleResourcePath() throws UriSyntaxException, UriNotMatchingException, EdmException {
    if (pathSegments.isEmpty()) {
      uriResult.setUriType(UriType.URI0);
    } else {

      currentPathSegment = pathSegments.remove(0);
      final String decodedPath = percentDecode(currentPathSegment);

      if ("$metadata".equals(decodedPath)) {
        ensureLastSegment();
        uriResult.setUriType(UriType.URI8);

      } else if ("$batch".equals(decodedPath)) {
        ensureLastSegment();
        uriResult.setUriType(UriType.URI9);

      } else {
        handleNormalInitialSegment();
      }
    }
  }

  private void handleNormalInitialSegment() throws UriSyntaxException, UriNotMatchingException, EdmException {
    final Matcher matcher = INITIAL_SEGMENT_PATTERN.matcher(currentPathSegment);
    if (!matcher.matches()) {
      throw new UriNotMatchingException(UriNotMatchingException.MATCHPROBLEM.addContent(currentPathSegment));
    }

    final String entityContainerName = percentDecode(matcher.group(1));
    final String segmentName = percentDecode(matcher.group(2));
    final String keyPredicate = matcher.group(3);
    final String emptyParentheses = matcher.group(4);

    final EdmEntityContainer entityContainer =
        entityContainerName == null ? edm.getDefaultEntityContainer() : edm.getEntityContainer(entityContainerName);
    if (entityContainer == null) {
      throw new UriNotMatchingException(UriNotMatchingException.CONTAINERNOTFOUND.addContent(entityContainerName));
    }
    uriResult.setEntityContainer(entityContainer);

    final EdmEntitySet entitySet = entityContainer.getEntitySet(segmentName);
    if (entitySet != null) {
      uriResult.setStartEntitySet(entitySet);
      handleEntitySet(entitySet, keyPredicate);
    } else {
      final EdmFunctionImport functionImport = entityContainer.getFunctionImport(segmentName);
      if (functionImport == null) {
        throw new UriNotMatchingException(UriNotMatchingException.NOTFOUND.addContent(segmentName));
      }
      uriResult.setFunctionImport(functionImport);
      handleFunctionImport(functionImport, emptyParentheses, keyPredicate);
    }
  }

  private void handleEntitySet(final EdmEntitySet entitySet, final String keyPredicate) throws UriSyntaxException,
      UriNotMatchingException, EdmException {
    final EdmEntityType entityType = entitySet.getEntityType();

    uriResult.setTargetType(entityType);
    uriResult.setTargetEntitySet(entitySet);

    if (keyPredicate == null) {
      if (pathSegments.isEmpty()) {
        uriResult.setUriType(UriType.URI1);
      } else {
        currentPathSegment = pathSegments.remove(0);
        checkCount();
        if (uriResult.isCount()) {
          uriResult.setUriType(UriType.URI15);
        } else {
          throw new UriSyntaxException(UriSyntaxException.ENTITYSETINSTEADOFENTITY.addContent(entitySet.getName()));
        }
      }
    } else {
      uriResult.setKeyPredicates(parseKey(keyPredicate, entityType));
      if (pathSegments.isEmpty()) {
        uriResult.setUriType(UriType.URI2);
      } else {
        handleNavigationPathOptions();
      }
    }
  }

  private void handleNavigationPathOptions() throws UriSyntaxException, UriNotMatchingException, EdmException {
    currentPathSegment = pathSegments.remove(0);
    final String decodedPath = percentDecode(currentPathSegment);

    checkCount();
    if (uriResult.isCount()) {
      uriResult.setUriType(UriType.URI16); // Count of multiple entities is handled elsewhere

    } else if ("$value".equals(decodedPath)) {
      if (uriResult.getTargetEntitySet().getEntityType().hasStream()) {
        ensureLastSegment();
        uriResult.setUriType(UriType.URI17);
        uriResult.setValue(true);
      } else {
        throw new UriSyntaxException(UriSyntaxException.NOMEDIARESOURCE);
      }

    } else if ("$links".equals(decodedPath)) {
      uriResult.setLinks(true);
      if (pathSegments.isEmpty()) {
        throw new UriSyntaxException(UriSyntaxException.MUSTNOTBELASTSEGMENT.addContent(currentPathSegment));
      }
      currentPathSegment = pathSegments.remove(0);
      handleNavigationProperties();

    } else {
      handleNavigationProperties();
    }
  }

  private void handleNavigationProperties() throws UriSyntaxException, UriNotMatchingException, EdmException {

    final Matcher matcher = NAVIGATION_SEGMENT_PATTERN.matcher(currentPathSegment);
    if (!matcher.matches()) {
      throw new UriNotMatchingException(UriNotMatchingException.MATCHPROBLEM.addContent(currentPathSegment));
    }

    final String navigationPropertyName = percentDecode(matcher.group(1));
    final String keyPredicateName = matcher.group(2);
    final String emptyParentheses = matcher.group(3);

    final EdmTyped property = uriResult.getTargetEntitySet().getEntityType().getProperty(navigationPropertyName);
    if (property == null) {
      throw new UriNotMatchingException(UriNotMatchingException.PROPERTYNOTFOUND.addContent(navigationPropertyName));
    }

    switch (property.getType().getKind()) {
    case SIMPLE:
    case COMPLEX:
      if (keyPredicateName != null || emptyParentheses != null) {
        throw new UriSyntaxException(UriSyntaxException.INVALIDSEGMENT.addContent(currentPathSegment));
      }
      if (uriResult.isLinks()) {
        throw new UriSyntaxException(UriSyntaxException.NONAVIGATIONPROPERTY.addContent(property));
      }

      handlePropertyPath((EdmProperty) property);
      break;

    case ENTITY: // navigation properties point to entities
      final EdmNavigationProperty navigationProperty = (EdmNavigationProperty) property;
      if (keyPredicateName != null || emptyParentheses != null) {
        if (navigationProperty.getMultiplicity() != EdmMultiplicity.MANY) {
          throw new UriSyntaxException(UriSyntaxException.INVALIDSEGMENT.addContent(currentPathSegment));
        }
      }

      addNavigationSegment(keyPredicateName, navigationProperty);

      boolean many = false;
      if (navigationProperty.getMultiplicity() == EdmMultiplicity.MANY) {
        many = keyPredicateName == null;
      }

      if (pathSegments.isEmpty()) {
        if (many) {
          if (uriResult.isLinks()) {
            uriResult.setUriType(UriType.URI7B);
          } else {
            uriResult.setUriType(UriType.URI6B);
          }
        } else if (uriResult.isLinks()) {
          uriResult.setUriType(UriType.URI7A);
        } else {
          uriResult.setUriType(UriType.URI6A);
        }
      } else if (many || uriResult.isLinks()) {
        currentPathSegment = pathSegments.remove(0);
        checkCount();
        if (!uriResult.isCount()) {
          throw new UriSyntaxException(UriSyntaxException.INVALIDSEGMENT.addContent(currentPathSegment));
        }
        if (many) {
          if (uriResult.isLinks()) {
            uriResult.setUriType(UriType.URI50B);
          } else {
            uriResult.setUriType(UriType.URI15);
          }
        } else {
          uriResult.setUriType(UriType.URI50A);
        }
      } else {
        handleNavigationPathOptions();
      }
      break;

    default:
      throw new UriSyntaxException(UriSyntaxException.INVALIDPROPERTYTYPE.addContent(property.getType().getKind()));
    }
  }

  private void addNavigationSegment(final String keyPredicateName, final EdmNavigationProperty navigationProperty)
      throws UriSyntaxException, EdmException {
    final EdmEntitySet targetEntitySet = uriResult.getTargetEntitySet().getRelatedEntitySet(navigationProperty);
    final EdmEntityType targetEntityType = targetEntitySet.getEntityType();
    uriResult.setTargetEntitySet(targetEntitySet);
    uriResult.setTargetType(targetEntityType);

    NavigationSegmentImpl navigationSegment = new NavigationSegmentImpl();
    navigationSegment.setEntitySet(targetEntitySet);
    navigationSegment.setNavigationProperty(navigationProperty);
    if (keyPredicateName != null) {
      navigationSegment.setKeyPredicates(parseKey(keyPredicateName, targetEntityType));
    }
    uriResult.addNavigationSegment(navigationSegment);
  }

  private void handlePropertyPath(final EdmProperty property) throws UriSyntaxException, UriNotMatchingException,
      EdmException {
    uriResult.addProperty(property);
    final EdmType type = property.getType();

    if (pathSegments.isEmpty()) {
      if (type.getKind() == EdmTypeKind.SIMPLE) {
        if (uriResult.getPropertyPath().size() == 1) {
          uriResult.setUriType(UriType.URI5);
        } else {
          uriResult.setUriType(UriType.URI4);
        }
      } else if (type.getKind() == EdmTypeKind.COMPLEX) {
        uriResult.setUriType(UriType.URI3);
      } else {
        throw new UriSyntaxException(UriSyntaxException.INVALIDPROPERTYTYPE.addContent(type.getKind()));
      }
      uriResult.setTargetType(type);
    } else {

      currentPathSegment = percentDecode(pathSegments.remove(0));
      switch (type.getKind()) {
      case SIMPLE:
        if ("$value".equals(percentDecode(currentPathSegment))) {
          ensureLastSegment();
          uriResult.setValue(true);
          if (uriResult.getPropertyPath().size() == 1) {
            uriResult.setUriType(UriType.URI5);
          } else {
            uriResult.setUriType(UriType.URI4);
          }
        } else {
          throw new UriSyntaxException(UriSyntaxException.INVALIDSEGMENT.addContent(currentPathSegment));
        }
        uriResult.setTargetType(type);
        break;

      case COMPLEX:
        final EdmProperty nextProperty = (EdmProperty) ((EdmComplexType) type).getProperty(currentPathSegment);
        if (nextProperty == null) {
          throw new UriNotMatchingException(UriNotMatchingException.PROPERTYNOTFOUND.addContent(currentPathSegment));
        }

        handlePropertyPath(nextProperty);
        break;

      default:
        throw new UriSyntaxException(UriSyntaxException.INVALIDPROPERTYTYPE.addContent(type.getKind()));
      }
    }
  }

  private void ensureLastSegment() throws UriSyntaxException {
    if (!pathSegments.isEmpty()) {
      throw new UriSyntaxException(UriSyntaxException.MUSTBELASTSEGMENT.addContent(currentPathSegment));
    }
  }

  private void checkCount() throws UriSyntaxException {
    if ("$count".equals(percentDecode(currentPathSegment))) {
      if (pathSegments.isEmpty()) {
        uriResult.setCount(true);
      } else {
        throw new UriSyntaxException(UriSyntaxException.MUSTBELASTSEGMENT.addContent(currentPathSegment));
      }
    }
  }

  private ArrayList<KeyPredicate> parseKey(final String keyPredicate, final EdmEntityType entityType)
      throws UriSyntaxException, EdmException {
    final List<EdmProperty> keyProperties = entityType.getKeyProperties();
    ArrayList<EdmProperty> parsedKeyProperties = new ArrayList<EdmProperty>();
    ArrayList<KeyPredicate> keyPredicates = new ArrayList<KeyPredicate>();

    final List<String> keys = splitKeyPredicate(keyPredicate);
    for (final String key : keys) {
      final Matcher matcher = NAMED_VALUE_PATTERN.matcher(key);
      if (!matcher.matches()) {
        throw new UriSyntaxException(UriSyntaxException.INVALIDKEYPREDICATE.addContent(keyPredicate));
      }

      String name = percentDecode(matcher.group(1));
      final String value = percentDecode(matcher.group(2));

      if (name == null) {
        if (keyProperties.size() == 1) {
          name = keyProperties.get(0).getName();
        } else {
          throw new UriSyntaxException(UriSyntaxException.MISSINGKEYPREDICATENAME.addContent(key));
        }
      }
      
      if("''".equals(value) || value==null){
        throw new UriSyntaxException(UriSyntaxException.INVALIDVALUE.addContent(value));
      }

      EdmProperty keyProperty = null;
      for (final EdmProperty testKeyProperty : keyProperties) {
        if (testKeyProperty.getName().equals(name)) {
          keyProperty = testKeyProperty;
          break;
        }
      }
      if (keyProperty == null) {
        throw new UriSyntaxException(UriSyntaxException.INVALIDKEYPREDICATE.addContent(keyPredicate));
      }
      if (parsedKeyProperties.contains(keyProperty)) {
        throw new UriSyntaxException(UriSyntaxException.DUPLICATEKEYNAMES.addContent(keyPredicate));
      }
      parsedKeyProperties.add(keyProperty);

      final EdmLiteral uriLiteral = parseLiteral(value, (EdmSimpleType) keyProperty.getType());
      keyPredicates.add(new KeyPredicateImpl(uriLiteral.getLiteral(), keyProperty));
    }

    if (parsedKeyProperties.size() != keyProperties.size()) {
      throw new UriSyntaxException(UriSyntaxException.INVALIDKEYPREDICATE.addContent(keyPredicate));
    }

    return keyPredicates;
  }

  /**
   * Split the <code>keyPredicate</code> string into separate keys (named keys).
   * e.g. <b>EmployeeId='1,,,2',Test='as'</b> will result in a list with two elements
   * <b>EmployeeId='1,,,2'</b> and <b>Test='as'</b>.
   *
   * e.g. <b>'42'</b> will result in a list with onw element <b>'42'</b>.
   *
   * Snippets from ABNF (odata-abnf-construction-rules)
   *
   * <code>
   * keyPredicate = simpleKey / compoundKey
   * simpleKey = OPEN keyPropertyValue CLOSE
   * compoundKey = OPEN keyValuePair *( COMMA keyValuePair ) CLOSE
   * keyValuePair = ( primitiveKeyProperty / keyPropertyAlias ) EQ keyPropertyValue
   * keyPropertyValue = primitiveLiteral
   * keyPropertyAlias = odataIdentifier
   * </code>
   *
   * <code>
   * string = SQUOTE *( SQUOTE-in-string / pchar-no-SQUOTE ) SQUOTE
   * SQUOTE-in-string = SQUOTE SQUOTE ; two consecutive single quotes represent one within a string literal
   * </code>
   *
   * @param keyPredicate keyPredicate to split
   * @return list of separate (named) key values
   */
  private List<String> splitKeyPredicate(String keyPredicate) {
    StringBuilder b = new StringBuilder();
    final List<String> keys = new ArrayList<String>();
    boolean inStringKeyValue = false;
    for (int i = 0; i < keyPredicate.length(); i++) {
      final char curChar = keyPredicate.charAt(i);
      if (SQUOTE == curChar) {
        // also works with SQUOTE-in-string
        inStringKeyValue = !inStringKeyValue;
        b.append(curChar);
      } else if (COMMA == curChar && !inStringKeyValue) {
        keys.add(b.toString());
        b = new StringBuilder();
      } else {
        b.append(curChar);
      }
    }
    keys.add(b.toString());

    return keys;
  }

  private void handleFunctionImport(final EdmFunctionImport functionImport, final String emptyParentheses,
      final String keyPredicate) throws UriSyntaxException, UriNotMatchingException, EdmException {
    final EdmTyped returnType = functionImport.getReturnType();
    
    if (returnType != null && returnType.getType() != null) {
      final EdmType type = returnType.getType();
      final boolean isCollection = returnType.getMultiplicity() == EdmMultiplicity.MANY;
  
      if (type.getKind() == EdmTypeKind.ENTITY && isCollection) {
        handleEntitySet(functionImport.getEntitySet(), keyPredicate);
        return;
      }
  
      if (emptyParentheses != null) {
        throw new UriSyntaxException(UriSyntaxException.INVALIDSEGMENT.addContent(emptyParentheses));
      }
  
      uriResult.setTargetType(type);
      switch (type.getKind()) {
      case SIMPLE:
        uriResult.setUriType(isCollection ? UriType.URI13 : UriType.URI14);
        break;
      case COMPLEX:
        uriResult.setUriType(isCollection ? UriType.URI11 : UriType.URI12);
        break;
      case ENTITY:
        uriResult.setUriType(UriType.URI10);
        break;
      default:
        throw new UriSyntaxException(UriSyntaxException.INVALIDRETURNTYPE.addContent(type.getKind()));
      }
  
      if (!pathSegments.isEmpty()) {
        if (uriResult.getUriType() == UriType.URI14) {
          currentPathSegment = pathSegments.remove(0);
          if ("$value".equals(percentDecode(currentPathSegment))) {
            uriResult.setValue(true);
          } else {
            throw new UriSyntaxException(UriSyntaxException.INVALIDSEGMENT.addContent(currentPathSegment));
          }
        }
      }
    } else {
      uriResult.setUriType(UriType.URI14);
    }
    ensureLastSegment();
  }

  private void distributeQueryParameters(final Map<String, List<String>> queryParameters) throws UriSyntaxException {
    boolean formEncoding = false;
    if(queryParameters.containsKey(ACCEPT_FORM_ENCODING)){
      formEncoding=Boolean.parseBoolean(queryParameters.get(ACCEPT_FORM_ENCODING).get(0));
      queryParameters.remove(ACCEPT_FORM_ENCODING);
    }
    for (final String queryOptionString : queryParameters.keySet()) {
      final String decodedString = percentDecode(queryOptionString);
      final List<String> valueList = queryParameters.get(queryOptionString);

      if (valueList.size() >= 1) {
        String value = valueList.get(0);
        if(formEncoding){
          value = getFormEncodedValue(value);
        }
        if (decodedString.startsWith("$")) {
          SystemQueryOption queryOption;
          try {
            queryOption = SystemQueryOption.valueOf(decodedString);
          } catch (IllegalArgumentException e) {
            throw new UriSyntaxException(UriSyntaxException.INVALIDSYSTEMQUERYOPTION.addContent(queryOptionString), e);
          }
          if ("".equals(value)) {
            throw new UriSyntaxException(UriSyntaxException.INVALIDNULLVALUE.addContent(queryOptionString));
          } else {
            if (valueList.size() == 1 && !systemQueryOptions.containsKey(queryOption)) {
              systemQueryOptions.put(queryOption, value);
            } else {
              throw new UriSyntaxException(UriSyntaxException.DUPLICATESYSTEMQUERYPARAMETES
                  .addContent(queryOptionString));
            }
          }
        } else {
          otherQueryParameters.put(decodedString, value);
        }
      } else {
        throw new UriSyntaxException(UriSyntaxException.INVALIDNULLVALUE.addContent(queryOptionString));
      }
    }
  }

  private String getFormEncodedValue(String value) {
    if(value.contains("+")){
      value = value.replaceAll("\\+", " ");
    }
    return value;    
  }

  private void checkSystemQueryOptionsCompatibility() throws UriSyntaxException {
    final UriType uriType = uriResult.getUriType();

    for (SystemQueryOption queryOption : systemQueryOptions.keySet()) {

      if (queryOption == SystemQueryOption.$format && (uriType == UriType.URI4 || uriType == UriType.URI5)
          && uriResult.isValue()) {
        throw new UriSyntaxException(UriSyntaxException.INCOMPATIBLESYSTEMQUERYOPTION.addContent(queryOption));
      }

      if (!uriType.isCompatible(queryOption)) {
        throw new UriSyntaxException(UriSyntaxException.INCOMPATIBLESYSTEMQUERYOPTION.addContent(queryOption));
      }
    }
  }

  private void handleSystemQueryOptions() throws UriSyntaxException, UriNotMatchingException, EdmException {

    for (SystemQueryOption queryOption : systemQueryOptions.keySet()) {
      switch (queryOption) {
      case $format:
        handleSystemQueryOptionFormat(systemQueryOptions.get(SystemQueryOption.$format));
        break;
      case $filter:
        handleSystemQueryOptionFilter(systemQueryOptions.get(SystemQueryOption.$filter));
        break;
      case $inlinecount:
        handleSystemQueryOptionInlineCount(systemQueryOptions.get(SystemQueryOption.$inlinecount));
        break;
      case $orderby:
        handleSystemQueryOptionOrderBy(systemQueryOptions.get(SystemQueryOption.$orderby));
        break;
      case $skiptoken:
        handleSystemQueryOptionSkipToken(systemQueryOptions.get(SystemQueryOption.$skiptoken));
        break;
      case $skip:
        handleSystemQueryOptionSkip(systemQueryOptions.get(SystemQueryOption.$skip));
        break;
      case $top:
        handleSystemQueryOptionTop(systemQueryOptions.get(SystemQueryOption.$top));
        break;
      case $expand:
        handleSystemQueryOptionExpand(systemQueryOptions.get(SystemQueryOption.$expand));
        break;
      case $select:
        handleSystemQueryOptionSelect(systemQueryOptions.get(SystemQueryOption.$select));
        break;
      default:
        throw new ODataRuntimeException("Invalid System Query Option " + queryOption);
      }
    }
  }

  private void handleSystemQueryOptionFormat(final String format) throws UriSyntaxException {
    uriResult.setFormat(format);
  }

  private void handleSystemQueryOptionFilter(final String filter) throws UriSyntaxException {
    final EdmType targetType = uriResult.getTargetType();
    if (targetType instanceof EdmEntityType) {
      try {
        uriResult.setFilter(new FilterParserImpl((EdmEntityType) targetType).parseFilterString(filter, true));
      } catch (ExpressionParserException e) {
        throw new UriSyntaxException(UriSyntaxException.INVALIDFILTEREXPRESSION.addContent(filter), e);
      } catch (ODataMessageException e) {
        throw new UriSyntaxException(UriSyntaxException.INVALIDFILTEREXPRESSION.addContent(filter), e);
      }
    }
  }

  private void handleSystemQueryOptionOrderBy(final String orderBy) throws UriSyntaxException {
    final EdmType targetType = uriResult.getTargetType();
    if (targetType instanceof EdmEntityType) {
      try {
        uriResult.setOrderBy(parseOrderByString((EdmEntityType) targetType, orderBy));
      } catch (ExpressionParserException e) {
        throw new UriSyntaxException(UriSyntaxException.INVALIDORDERBYEXPRESSION.addContent(orderBy), e);
      } catch (ODataMessageException e) {
        throw new UriSyntaxException(UriSyntaxException.INVALIDORDERBYEXPRESSION.addContent(orderBy), e);
      }
    }
  }

  private void handleSystemQueryOptionInlineCount(final String inlineCount) throws UriSyntaxException {
    if ("allpages".equals(inlineCount)) {
      uriResult.setInlineCount(InlineCount.ALLPAGES);
    } else if ("none".equals(inlineCount)) {
      uriResult.setInlineCount(InlineCount.NONE);
    } else {
      throw new UriSyntaxException(UriSyntaxException.INVALIDVALUE.addContent(inlineCount));
    }
  }

  private void handleSystemQueryOptionSkipToken(final String skiptoken) throws UriSyntaxException {
    uriResult.setSkipToken(skiptoken);
  }

  private void handleSystemQueryOptionSkip(final String skip) throws UriSyntaxException {
    try {
      uriResult.setSkip(Integer.valueOf(skip));
    } catch (NumberFormatException e) {
      throw new UriSyntaxException(UriSyntaxException.INVALIDVALUE.addContent(skip), e);
    }

    if (skip.startsWith("-")) {
      throw new UriSyntaxException(UriSyntaxException.INVALIDNEGATIVEVALUE.addContent(skip));
    } else if (skip.startsWith("+")) {
      throw new UriSyntaxException(UriSyntaxException.INVALIDVALUE.addContent(skip));
    }
  }

  private void handleSystemQueryOptionTop(final String top) throws UriSyntaxException {
    try {
      uriResult.setTop(Integer.valueOf(top));
    } catch (NumberFormatException e) {
      throw new UriSyntaxException(UriSyntaxException.INVALIDVALUE.addContent(top), e);
    }

    if (top.startsWith("-")) {
      throw new UriSyntaxException(UriSyntaxException.INVALIDNEGATIVEVALUE.addContent(top));
    } else if (top.startsWith("+")) {
      throw new UriSyntaxException(UriSyntaxException.INVALIDVALUE.addContent(top));
    }
  }

  private void handleSystemQueryOptionExpand(final String expandStatement) throws UriSyntaxException,
      UriNotMatchingException, EdmException {
    ArrayList<ArrayList<NavigationPropertySegment>> expand = new ArrayList<ArrayList<NavigationPropertySegment>>();

    if (expandStatement.startsWith(",") || expandStatement.endsWith(",")) {
      throw new UriSyntaxException(UriSyntaxException.EMPTYSEGMENT);
    }

    for (String expandItemString : expandStatement.split(",")) {
      expandItemString = expandItemString.trim();
      if ("".equals(expandItemString)) {
        throw new UriSyntaxException(UriSyntaxException.EMPTYSEGMENT);
      }
      if (expandItemString.startsWith("/") || expandItemString.endsWith("/")) {
        throw new UriSyntaxException(UriSyntaxException.EMPTYSEGMENT);
      }

      ArrayList<NavigationPropertySegment> expandNavigationProperties = new ArrayList<NavigationPropertySegment>();
      EdmEntitySet fromEntitySet = uriResult.getTargetEntitySet();

      for (String expandPropertyName : expandItemString.split("/")) {
        if ("".equals(expandPropertyName)) {
          throw new UriSyntaxException(UriSyntaxException.EMPTYSEGMENT);
        }

        final EdmTyped property = fromEntitySet.getEntityType().getProperty(expandPropertyName);
        if (property == null) {
          throw new UriNotMatchingException(UriNotMatchingException.PROPERTYNOTFOUND.addContent(expandPropertyName));
        }
        if (property.getType().getKind() == EdmTypeKind.ENTITY) {
          final EdmNavigationProperty navigationProperty = (EdmNavigationProperty) property;
          fromEntitySet = fromEntitySet.getRelatedEntitySet(navigationProperty);
          NavigationPropertySegmentImpl propertySegment = new NavigationPropertySegmentImpl();
          propertySegment.setNavigationProperty(navigationProperty);
          propertySegment.setTargetEntitySet(fromEntitySet);
          expandNavigationProperties.add(propertySegment);
        } else {
          throw new UriSyntaxException(UriSyntaxException.NONAVIGATIONPROPERTY.addContent(expandPropertyName));
        }
      }
      expand.add(expandNavigationProperties);
    }
    uriResult.setExpand(expand);
  }

  private void handleSystemQueryOptionSelect(final String selectStatement) throws UriSyntaxException,
      UriNotMatchingException, EdmException {
    ArrayList<SelectItem> select = new ArrayList<SelectItem>();

    if (selectStatement.startsWith(",") || selectStatement.endsWith(",")) {
      throw new UriSyntaxException(UriSyntaxException.EMPTYSEGMENT);
    }

    for (String selectItemString : selectStatement.split(",")) {
      selectItemString = selectItemString.trim();
      if ("".equals(selectItemString)) {
        throw new UriSyntaxException(UriSyntaxException.EMPTYSEGMENT);
      }
      if (selectItemString.startsWith("/") || selectItemString.endsWith("/")) {
        throw new UriSyntaxException(UriSyntaxException.EMPTYSEGMENT);
      }

      SelectItemImpl selectItem = new SelectItemImpl();
      boolean exit = false;
      EdmEntitySet fromEntitySet = uriResult.getTargetEntitySet();

      for (String selectedPropertyName : selectItemString.split("/")) {
        if ("".equals(selectedPropertyName)) {
          throw new UriSyntaxException(UriSyntaxException.EMPTYSEGMENT);
        }

        if (exit) {
          throw new UriSyntaxException(UriSyntaxException.INVALIDSEGMENT.addContent(selectItemString));
        }

        if ("*".equals(selectedPropertyName)) {
          selectItem.setStar(true);
          exit = true;
          continue;
        }

        final EdmTyped property = fromEntitySet.getEntityType().getProperty(selectedPropertyName);
        if (property == null) {
          throw new UriNotMatchingException(UriNotMatchingException.PROPERTYNOTFOUND.addContent(selectedPropertyName));
        }

        switch (property.getType().getKind()) {
        case SIMPLE:
        case COMPLEX:
          selectItem.setProperty((EdmProperty) property);
          exit = true;
          break;

        case ENTITY: // navigation properties point to entities
          final EdmNavigationProperty navigationProperty = (EdmNavigationProperty) property;
          final EdmEntitySet targetEntitySet = fromEntitySet.getRelatedEntitySet(navigationProperty);

          NavigationPropertySegmentImpl navigationPropertySegment = new NavigationPropertySegmentImpl();
          navigationPropertySegment.setNavigationProperty(navigationProperty);
          navigationPropertySegment.setTargetEntitySet(targetEntitySet);
          selectItem.addNavigationPropertySegment(navigationPropertySegment);

          fromEntitySet = targetEntitySet;
          break;

        default:
          throw new UriSyntaxException(UriSyntaxException.INVALIDPROPERTYTYPE);
        }
      }
      select.add(selectItem);
    }
    uriResult.setSelect(select);
  }

  private void handleOtherQueryParameters() throws UriSyntaxException, EdmException {
    final EdmFunctionImport functionImport = uriResult.getFunctionImport();
    if (functionImport != null) {
      for (final String parameterName : functionImport.getParameterNames()) {
        final EdmParameter parameter = functionImport.getParameter(parameterName);
        final String value = otherQueryParameters.remove(parameterName);

        if (value == null) {
          if (parameter.getFacets() == null || parameter.getFacets().isNullable() == null
              || parameter.getFacets().isNullable()) {
            continue;
          } else {
            throw new UriSyntaxException(UriSyntaxException.MISSINGPARAMETER);
          }
        }

        EdmLiteral uriLiteral = parseLiteral(value, (EdmSimpleType) parameter.getType(), parameter.getFacets());
        uriResult.addFunctionImportParameter(parameterName, uriLiteral);
      }
    }

    uriResult.setCustomQueryOptions(otherQueryParameters);
  }

  private EdmLiteral parseLiteral(String value, EdmSimpleType expectedType, EdmFacets facets) 
      throws UriSyntaxException {
    EdmLiteral literal;
    try {
      literal = simpleTypeFacade.parseUriLiteral(value, facets);
    } catch (EdmLiteralException e) {
      throw convertEdmLiteralException(e);
    }

    if (expectedType.isCompatible(literal.getType())) {
      return literal;
    } else {
      throw new UriSyntaxException(UriSyntaxException.INCOMPATIBLELITERAL.addContent(value, expectedType));
    }
  }

  private EdmLiteral parseLiteral(final String value, final EdmSimpleType expectedType) throws UriSyntaxException {
    EdmLiteral literal;
    try {
      literal = simpleTypeFacade.parseUriLiteral(value);
    } catch (EdmLiteralException e) {
      throw convertEdmLiteralException(e);
    }

    if (expectedType.isCompatible(literal.getType())) {
      return literal;
    } else {
      throw new UriSyntaxException(UriSyntaxException.INCOMPATIBLELITERAL.addContent(value, expectedType));
    }
  }

  private static UriSyntaxException convertEdmLiteralException(final EdmLiteralException e) {
    final MessageReference messageReference = e.getMessageReference();

    if (EdmLiteralException.LITERALFORMAT.equals(messageReference)) {
      return new UriSyntaxException(UriSyntaxException.LITERALFORMAT.addContent(messageReference.getContent()), e);
    } else if (EdmLiteralException.NOTEXT.equals(messageReference)) {
      return new UriSyntaxException(UriSyntaxException.NOTEXT.addContent(messageReference.getContent()), e);
    } else if (EdmLiteralException.UNKNOWNLITERAL.equals(messageReference)) {
      return new UriSyntaxException(UriSyntaxException.UNKNOWNLITERAL.addContent(messageReference.getContent()), e);
    } else {
      return new UriSyntaxException(ODataBadRequestException.COMMON, e);
    }
  }

  private static List<String> copyPathSegmentList(final List<PathSegment> source) {
    List<String> copy = new ArrayList<String>();

    for (final PathSegment segment : source) {
      copy.add(segment.getPath());
    }

    return copy;
  }

  private static String percentDecode(final String value) throws UriSyntaxException {
    try {
      return Decoder.decode(value);
    } catch (RuntimeException e) {
      throw new UriSyntaxException(UriSyntaxException.URISYNTAX, e);
    }
  }

  @Override
  public FilterExpression parseFilterString(final EdmEntityType entityType, final String expression)
      throws ODataMessageException {
    return new FilterParserImpl(entityType).parseFilterString(expression);
  }

  @Override
  public OrderByExpression parseOrderByString(final EdmEntityType entityType, final String expression)
      throws ODataMessageException {
    return new OrderByParserImpl(entityType).parseOrderByString(expression);
  }

  @Override
  public ExpandSelectTreeNode buildExpandSelectTree(final List<SelectItem> select,
      final List<ArrayList<NavigationPropertySegment>> expand) throws EdmException {
    return new ExpandSelectTreeCreator(select, expand).create();
  }

  @Override
  protected PathSegment buildPathSegment(String path, Map<String, List<String>> matrixParameters) {
    return new ODataPathSegmentImpl(path, matrixParameters);
  }

  @Override
  public List<KeyPredicate> getKeyFromEntityLink(final EdmEntitySet entitySet, final String entityLink,
      final URI serviceRoot) throws ODataException {
    final String relativeLink = serviceRoot == null ? entityLink :
        entityLink.startsWith(serviceRoot.toString()) ?
            entityLink.substring(serviceRoot.toString().length()) : entityLink;
    final Matcher matcher = INITIAL_SEGMENT_PATTERN.matcher(relativeLink);
    if (!matcher.matches()) {
      throw new UriNotMatchingException(UriNotMatchingException.MATCHPROBLEM.addContent(relativeLink));
    }

    final String entityContainerName = percentDecode(matcher.group(1));
    if (entityContainerName == null && !entitySet.getEntityContainer().isDefaultEntityContainer()
        || entityContainerName != null && !entityContainerName.equals(entitySet.getEntityContainer().getName())) {
      throw new UriNotMatchingException(UriNotMatchingException.CONTAINERNOTFOUND.addContent(entityContainerName));
    }

    final String entitySetName = percentDecode(matcher.group(2));
    if (!entitySetName.equals(entitySet.getName())) {
      throw new UriNotMatchingException(UriNotMatchingException.NOTFOUND.addContent(entitySetName));
    }

    final String keyPredicate = matcher.group(3);
    if (keyPredicate == null) {
      throw new UriSyntaxException(UriSyntaxException.ENTITYSETINSTEADOFENTITY.addContent(entitySetName));
    }
    return parseKey(keyPredicate, entitySet.getEntityType());
  }
}
