/*
 * 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.tecsvc.processor;

import java.io.InputStream;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.ContextURL.Builder;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmReturnType;
import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.deserializer.FixedFormatDeserializer;
import org.apache.olingo.server.api.prefer.Preferences.Return;
import org.apache.olingo.server.api.prefer.PreferencesApplied;
import org.apache.olingo.server.api.processor.ComplexCollectionProcessor;
import org.apache.olingo.server.api.processor.ComplexProcessor;
import org.apache.olingo.server.api.processor.CountComplexCollectionProcessor;
import org.apache.olingo.server.api.processor.CountPrimitiveCollectionProcessor;
import org.apache.olingo.server.api.processor.PrimitiveCollectionProcessor;
import org.apache.olingo.server.api.processor.PrimitiveProcessor;
import org.apache.olingo.server.api.processor.PrimitiveValueProcessor;
import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
import org.apache.olingo.server.api.serializer.PrimitiveValueSerializerOptions;
import org.apache.olingo.server.api.serializer.RepresentationType;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.serializer.SerializerResult;
import org.apache.olingo.server.api.uri.UriHelper;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceComplexProperty;
import org.apache.olingo.server.api.uri.UriResourceFunction;
import org.apache.olingo.server.api.uri.UriResourceKind;
import org.apache.olingo.server.api.uri.UriResourceProperty;
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
import org.apache.olingo.server.tecsvc.data.DataProvider;
import org.apache.olingo.server.tecsvc.data.DataProvider.DataProviderException;

/**
 * Technical Processor which provides functionality related to primitive and complex types and collections thereof.
 */
public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
    implements PrimitiveProcessor, PrimitiveValueProcessor,
    PrimitiveCollectionProcessor, CountPrimitiveCollectionProcessor,
    ComplexProcessor, ComplexCollectionProcessor, CountComplexCollectionProcessor {

  private static final String EDMSTREAM = "Edm.Stream";

  public TechnicalPrimitiveComplexProcessor(final DataProvider dataProvider,
      final ServiceMetadata serviceMetadata) {
    super(dataProvider, serviceMetadata);
  }

  @Override
  public void readPrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType contentType) throws ODataApplicationException, ODataLibraryException {
    readProperty(request, response, uriInfo, contentType, RepresentationType.PRIMITIVE);
  }

  @Override
  public void readPrimitiveValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType contentType) throws ODataApplicationException, ODataLibraryException {
    readProperty(request, response, uriInfo, contentType, RepresentationType.VALUE);
  }

  @Override
  public void updatePrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType requestFormat, final ContentType responseFormat)
      throws ODataApplicationException, ODataLibraryException {
    updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.PRIMITIVE);
  }

  @Override
  public void updatePrimitiveValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType requestFormat, final ContentType responseFormat)
      throws ODataApplicationException, ODataLibraryException {
    updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.VALUE);
  }

  @Override
  public void deletePrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
      throws ODataApplicationException, ODataLibraryException {
    deleteProperty(request, response, uriInfo, false);
  }

  @Override
  public void deletePrimitiveValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
      throws ODataApplicationException, ODataLibraryException {
    deleteProperty(request, response, uriInfo, true);
  }

  @Override
  public void readPrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType contentType) throws ODataApplicationException, ODataLibraryException {
    readProperty(request, response, uriInfo, contentType, RepresentationType.COLLECTION_PRIMITIVE);
  }

  @Override
  public void countPrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
      throws ODataApplicationException, ODataLibraryException {
    readProperty(request, response, uriInfo, ContentType.TEXT_PLAIN, RepresentationType.COUNT);
  }

  @Override
  public void updatePrimitiveCollection(final ODataRequest request, ODataResponse response,
      final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat)
      throws ODataApplicationException, ODataLibraryException {
    updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.COLLECTION_PRIMITIVE);
  }

  @Override
  public void deletePrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
      throws ODataApplicationException, ODataLibraryException {
    deleteProperty(request, response, uriInfo, false);
  }

  @Override
  public void readComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType contentType) throws ODataApplicationException, ODataLibraryException {
    readProperty(request, response, uriInfo, contentType, RepresentationType.COMPLEX);
  }

  @Override
  public void updateComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType requestFormat, final ContentType responseFormat)
      throws ODataApplicationException, ODataLibraryException {
    updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.COMPLEX);
  }

  @Override
  public void deleteComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
      throws ODataApplicationException, ODataLibraryException {
    deleteProperty(request, response, uriInfo, false);
  }

  @Override
  public void readComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType contentType) throws ODataApplicationException, ODataLibraryException {
    readProperty(request, response, uriInfo, contentType, RepresentationType.COLLECTION_COMPLEX);
  }

  @Override
  public void countComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
      throws ODataApplicationException, ODataLibraryException {
    readProperty(request, response, uriInfo, ContentType.TEXT_PLAIN, RepresentationType.COUNT);
  }

  @Override
  public void updateComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType requestFormat, final ContentType responseFormat)
      throws ODataApplicationException, ODataLibraryException {
    updateProperty(request, response, uriInfo, requestFormat, responseFormat, RepresentationType.COLLECTION_COMPLEX);
  }

  @Override
  public void deleteComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
      throws ODataApplicationException, ODataLibraryException {
    deleteProperty(request, response, uriInfo, false);
  }

  private void readProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType contentType, final RepresentationType representationType)
          throws ODataApplicationException, ODataLibraryException {
    final UriInfoResource resource = uriInfo.asUriInfoResource();
    validateOptions(resource);
    validatePath(resource);
    final EdmEntitySet edmEntitySet = getEdmEntitySet(resource);

    final List<UriResource> resourceParts = resource.getUriResourceParts();
    final int trailing =
        representationType == RepresentationType.COUNT || representationType == RepresentationType.VALUE ? 1 : 0;
    final List<String> path = getPropertyPath(resourceParts, trailing);

    final Entity entity = readEntity(uriInfo);

    if (entity != null && entity.getETag() != null) {
      if (odata.createETagHelper().checkReadPreconditions(entity.getETag(),
          request.getHeaders(HttpHeader.IF_MATCH),
          request.getHeaders(HttpHeader.IF_NONE_MATCH))) {
        response.setStatusCode(HttpStatusCode.NOT_MODIFIED.getStatusCode());
        response.setHeader(HttpHeader.ETAG, entity.getETag());
        return;
      }
    }

    final Property property = entity == null ?
        getPropertyData(
            dataProvider.readFunctionPrimitiveComplex(((UriResourceFunction) resourceParts.get(0)).getFunction(),
            ((UriResourceFunction) resourceParts.get(0)).getParameters(), resource), path) :
        getData(entity, path, resourceParts, resource);

    // TODO: implement filter on collection properties (on a shallow copy of the values)
    // FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), property, uriInfo, serviceMetadata.getEdm());

    if (property == null && representationType != RepresentationType.COUNT) {
      if (representationType == RepresentationType.VALUE) {
        response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
      } else {
        throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
      }
    } else {
      if (property.getValue() == null && representationType != RepresentationType.COUNT) {
        response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
      } else {
        response.setStatusCode(HttpStatusCode.OK.getStatusCode());
        if (representationType == RepresentationType.COUNT) {
          response.setContent(odata.createFixedFormatSerializer().count(
              property.asCollection().size()));
        } else {
          final EdmProperty edmProperty = path.isEmpty() ? null :
              ((UriResourceProperty) resourceParts.get(resourceParts.size() - trailing - 1)).getProperty();
          EdmType type = null;
          if (resourceParts.get(resourceParts.size() - trailing - 1) 
             instanceof UriResourceComplexProperty &&
              ((UriResourceComplexProperty)resourceParts.get(resourceParts.size() - trailing - 1)).
              getComplexTypeFilter() != null) {
            type = ((UriResourceComplexProperty)resourceParts.get(resourceParts.size() - trailing - 1)).
                getComplexTypeFilter();
          }else if(resourceParts.get(resourceParts.size() - trailing - 1) 
             instanceof UriResourceFunction &&
              ((UriResourceFunction)resourceParts.get(resourceParts.size() - trailing - 1)).
              getFunction() != null){ 
            type = ((UriResourceFunction)resourceParts.get(resourceParts.size() - trailing - 1)).
                getType();
          }else {
            type = edmProperty == null ?
                ((UriResourceFunction) resourceParts.get(0)).getType() :
                edmProperty.getType();
          }
          final EdmReturnType returnType = resourceParts.get(0) instanceof UriResourceFunction ?
              ((UriResourceFunction) resourceParts.get(0)).getFunction().getReturnType() : 
                resourceParts.get(1) instanceof UriResourceFunction ? 
                    ((UriResourceFunction) resourceParts.get(1)).getFunction().getReturnType():null ;

          if (representationType == RepresentationType.VALUE) {
            response.setContent(serializePrimitiveValue(property, edmProperty, (EdmPrimitiveType) type, returnType));
          }else if(representationType == RepresentationType.PRIMITIVE && type.getFullQualifiedName()
              .getFullQualifiedNameAsString().equals(EDMSTREAM)){
            response.setContent(odata.createFixedFormatSerializer().binary(dataProvider.readStreamProperty(property)));
            response.setStatusCode(HttpStatusCode.OK.getStatusCode());
            response.setHeader(HttpHeader.CONTENT_TYPE, ((Link)property.getValue()).getType());
            if (entity.getMediaETag() != null) {
              response.setHeader(HttpHeader.ETAG, entity.getMediaETag());
            }
          }else {
            final ExpandOption expand = uriInfo.getExpandOption();
            final SelectOption select = uriInfo.getSelectOption();
            final SerializerResult result = serializeProperty(entity, edmEntitySet, path, property, edmProperty,
                type, returnType, representationType, contentType, expand, select);
            response.setContent(result.getContent());
          }
        }
        response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
      }
      if (entity != null && entity.getETag() != null) {
        response.setHeader(HttpHeader.ETAG, entity.getETag());
      }
    }
  }

  private Property getData(Entity entity, List<String> path, List<UriResource> resourceParts, UriInfoResource resource) 
      throws DataProviderException {
    if(resourceParts.size()>1 && resourceParts.get(1) instanceof UriResourceFunction){
      return dataProvider.readFunctionPrimitiveComplex(((UriResourceFunction) resourceParts.get(1)).getFunction(),
          ((UriResourceFunction) resourceParts.get(1)).getParameters(), resource);
    }
    return getPropertyData(entity, path);
  }

  private Property getFunctionData(UriResource uriResource) {
    // TODO Auto-generated method stub
    return null;
  }

  private void updateProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType requestFormat, final ContentType responseFormat, final RepresentationType representationType)
      throws ODataApplicationException, ODataLibraryException {
    final UriInfoResource resource = uriInfo.asUriInfoResource();
    validatePath(resource);
    final EdmEntitySet edmEntitySet = getEdmEntitySet(resource);

    Entity entity = readEntity(uriInfo);
    odata.createETagHelper().checkChangePreconditions(entity.getETag(),
        request.getHeaders(HttpHeader.IF_MATCH),
        request.getHeaders(HttpHeader.IF_NONE_MATCH));

    final List<UriResource> resourceParts = resource.getUriResourceParts();
    final int trailing = representationType == RepresentationType.VALUE ? 1 : 0;
    final List<String> path = getPropertyPath(resourceParts, trailing);
    final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(resourceParts.size() - trailing - 1))
        .getProperty();

    Property property = getPropertyData(entity, path);

    if (representationType == RepresentationType.VALUE || 
    		edmProperty.getType().getFullQualifiedName()
    		.getFullQualifiedNameAsString().equalsIgnoreCase(EDMSTREAM)) {
      final FixedFormatDeserializer deserializer = odata.createFixedFormatDeserializer();
      final Object value = edmProperty.getType() == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Binary) 
    		  || edmProperty.getType() == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Stream) ?
          deserializer.binary(request.getBody()) :
          deserializer.primitiveValue(request.getBody(), edmProperty);
      dataProvider.updatePropertyValue(property, value);
    } else {
      final Property changedProperty = odata.createDeserializer(requestFormat)
          .property(request.getBody(), edmProperty).getProperty();
      if (changedProperty.isNull() && !edmProperty.isNullable()) {
        throw new ODataApplicationException("Not nullable.", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
      }
      dataProvider.updateProperty(edmProperty, property, changedProperty, request.getMethod() == HttpMethod.PATCH);
    }

    dataProvider.updateETag(entity);

    final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
    if (returnPreference == null || returnPreference == Return.REPRESENTATION) {
      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
      if (representationType == RepresentationType.VALUE || 
        		edmProperty.getType().getFullQualifiedName()
          		.getFullQualifiedNameAsString().equalsIgnoreCase(EDMSTREAM)) {
        response.setContent(
            serializePrimitiveValue(property, edmProperty, (EdmPrimitiveType) edmProperty.getType(), null));
      } else {
        final SerializerResult result = serializeProperty(entity, edmEntitySet, path, property, edmProperty,
            edmProperty.getType(), null, representationType, responseFormat, null, null);
        response.setContent(result.getContent());
      }
      if (edmProperty.getType().getFullQualifiedName()
        		.getFullQualifiedNameAsString().equalsIgnoreCase(EDMSTREAM)) {
      	  response.setHeader(HttpHeader.CONTENT_TYPE, requestFormat.toContentTypeString());
        } else {
      	  response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
        }
    } else {
      response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
    }
    if (returnPreference != null) {
      response.setHeader(HttpHeader.PREFERENCE_APPLIED,
          PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
    }
    if (entity.getETag() != null) {
      response.setHeader(HttpHeader.ETAG, entity.getETag());
    }
  }

  private void deleteProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final boolean isValue) throws ODataLibraryException, ODataApplicationException {
    final UriInfoResource resource = uriInfo.asUriInfoResource();
    validatePath(resource);
    getEdmEntitySet(uriInfo); // including checks

    Entity entity = readEntity(uriInfo);
    odata.createETagHelper().checkChangePreconditions(entity.getETag(),
        request.getHeaders(HttpHeader.IF_MATCH),
        request.getHeaders(HttpHeader.IF_NONE_MATCH));

    final List<UriResource> resourceParts = resource.getUriResourceParts();
    final int trailing = isValue ? 1 : 0;
    final List<String> path = getPropertyPath(resourceParts, trailing);

    Property property = getPropertyData(entity, path);

    final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(resourceParts.size() - trailing - 1))
        .getProperty();

    if (edmProperty.isNullable()) {
      property.setValue(property.getValueType(), edmProperty.isCollection() ? Collections.emptyList() : null);
      dataProvider.updateETag(entity);
      response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
      if (entity.getETag() != null) {
        response.setHeader(HttpHeader.ETAG, entity.getETag());
      }
    } else {
      throw new ODataApplicationException("Not nullable.", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
    }
  }

  private Property getPropertyData(final Entity entity, final List<String> path) {
    return getPropertyData(entity.getProperty(path.get(0)), path.subList(1, path.size()));
  }

  private Property getPropertyData(final Property property, final List<String> path) {
    Property result = property;
    for (final String name : path) {
      if (result != null && property.isComplex()) {
        final List<Property> complex = result.asComplex().getValue();
        result = null;
        for (final Property innerProperty : complex) {
          if (innerProperty.getName().equals(name)) {
            result = innerProperty;
            break;
          }
        }
      }
    }
    return result;
  }

  private List<String> getPropertyPath(final List<UriResource> path, final int trailing) {
    List<String> result = new LinkedList<String>();
    int index = path.size() - trailing - 1;
    while (path.get(index) instanceof UriResourceProperty) {
      result.add(0, ((UriResourceProperty) path.get(index)).getProperty().getName());
      index--;
    }
    return result;
  }

  private String buildPropertyPath(final List<String> path) {
    StringBuilder result = new StringBuilder();
    for (final String segment : path) {
      result.append(result.length() == 0 ? "" : '/').append(segment);
    }
    return result.toString();
  }

  private SerializerResult serializeProperty(final Entity entity, final EdmEntitySet edmEntitySet,
      final List<String> path, final Property property, final EdmProperty edmProperty,
      final EdmType type, final EdmReturnType returnType,
      final RepresentationType representationType, final ContentType responseFormat,
      final ExpandOption expand, final SelectOption select) throws ODataLibraryException {
    ODataSerializer serializer = odata.createSerializer(responseFormat);
    final ContextURL contextURL = isODataMetadataNone(responseFormat) ? null :
        getContextUrl(edmEntitySet, entity, path, type, representationType, expand, select);
    SerializerResult result = null;
    switch (representationType) {
    case PRIMITIVE:
      result = serializer.primitive(serviceMetadata, (EdmPrimitiveType) type, property,
          PrimitiveSerializerOptions.with().contextURL(contextURL)
              .nullable(edmProperty == null ? returnType.isNullable() : edmProperty.isNullable())
              .maxLength(edmProperty == null ? returnType.getMaxLength() : edmProperty.getMaxLength())
              .precision(edmProperty == null ? returnType.getPrecision() : edmProperty.getPrecision())
              .scale(edmProperty == null ? returnType.getScale() : edmProperty.getScale())
              .unicode(edmProperty == null ? null : edmProperty.isUnicode())
              .build());
      break;
    case COMPLEX:
      result = serializer.complex(serviceMetadata, (EdmComplexType) type, property,
          ComplexSerializerOptions.with().contextURL(contextURL)
              .expand(expand).select(select)
              .build());
      break;
    case COLLECTION_PRIMITIVE:
      result = serializer.primitiveCollection(serviceMetadata, (EdmPrimitiveType) type, property,
          PrimitiveSerializerOptions.with().contextURL(contextURL)
              .nullable(edmProperty == null ? returnType.isNullable() : edmProperty.isNullable())
              .maxLength(edmProperty == null ? returnType.getMaxLength() : edmProperty.getMaxLength())
              .precision(edmProperty == null ? returnType.getPrecision() : edmProperty.getPrecision())
              .scale(edmProperty == null ? returnType.getScale() : edmProperty.getScale())
              .unicode(edmProperty == null ? null : edmProperty.isUnicode())
              .build());
      break;
    case COLLECTION_COMPLEX:
      result = serializer.complexCollection(serviceMetadata, (EdmComplexType) type, property,
          ComplexSerializerOptions.with().contextURL(contextURL)
              .expand(expand).select(select)
              .build());
      break;
    default:
      break;
    }
    return result;
  }

  private ContextURL getContextUrl(final EdmEntitySet entitySet, final Entity entity, final List<String> path,
      final EdmType type, final RepresentationType representationType,
      final ExpandOption expand, final SelectOption select) throws ODataLibraryException {
    final UriHelper helper = odata.createUriHelper();
    Builder builder = ContextURL.with();
    builder = entitySet == null ?
        representationType == RepresentationType.PRIMITIVE || representationType == RepresentationType.COMPLEX ?
            builder.type(type) :
            builder.type(type).asCollection() :
        builder.entitySet(entitySet).keyPath(helper.buildKeyPredicate(entitySet.getEntityType(), entity));
    if (entitySet != null && !path.isEmpty()) {
      builder = builder.navOrPropertyPath(buildPropertyPath(path));
    }
    builder = builder.selectList(
        type.getKind() == EdmTypeKind.PRIMITIVE
            || type.getKind() == EdmTypeKind.ENUM
            || type.getKind() == EdmTypeKind.DEFINITION ?
                null :
                helper.buildContextURLSelectList((EdmStructuredType) type, expand, select));
    return builder.build();
  }

  private InputStream serializePrimitiveValue(final Property property, final EdmProperty edmProperty,
      final EdmPrimitiveType type, final EdmReturnType returnType) throws SerializerException {
    final FixedFormatSerializer serializer = odata.createFixedFormatSerializer();
    return type == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Binary) ||
    		type == odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Stream) ?
      serializer.binary((byte[]) property.getValue()) :
      serializer.primitiveValue(type, property.getValue(),
          PrimitiveValueSerializerOptions.with()
              .nullable(edmProperty == null ? returnType.isNullable() : edmProperty.isNullable())
              .maxLength(edmProperty == null ? returnType.getMaxLength() : edmProperty.getMaxLength())
              .precision(edmProperty == null ? returnType.getPrecision() : edmProperty.getPrecision())
              .scale(edmProperty == null ? returnType.getScale() : edmProperty.getScale())
              .unicode(edmProperty == null ? null : edmProperty.isUnicode())
              .build());
  }

  private void validatePath(final UriInfoResource uriInfo) throws ODataApplicationException {
    final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
    for (final UriResource segment : resourcePaths.subList(1, resourcePaths.size())) {
      final UriResourceKind kind = segment.getKind();
      if (kind != UriResourceKind.navigationProperty
          && kind != UriResourceKind.primitiveProperty
          && kind != UriResourceKind.complexProperty
          && kind != UriResourceKind.count
          && kind != UriResourceKind.value
          && kind != UriResourceKind.function) {
        throw new ODataApplicationException("Invalid resource type.",
            HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
      }
    }
  }
}
