﻿// Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation 
// files (the "Software"), to deal  in the Software without restriction, including without limitation the rights  to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// odata-json-light.js

(function (window, undefined) {

    var datajs = window.datajs || {};
    var odata = window.OData || {};

    // Imports

    var assigned = datajs.assigned;
    var djsassert = datajs.djsassert;
    var extend = datajs.extend;
    var getURIInfo = datajs.getURIInfo;
    var isArray = datajs.isArray;
    var isDate = datajs.isDate;
    var normalizeURI = datajs.normalizeURI;
    var renameProperty = datajs.renameProperty;
    var undefinedDefault = datajs.undefinedDefault;
    var convertByteArrayToHexString = datajs.convertByteArrayToHexString;

    var dataItemTypeName = odata.dataItemTypeName;
    var EDM_DATETIME = odata.EDM_DATETIME;
    var EDM_DATETIMEOFFSET = odata.EDM_DATETIMEOFFSET;
    var EDM_TIME = odata.EDM_TIME;
    var getCollectionType = odata.getCollectionType;
    var isCollection = odata.isCollection;
    var isCollectionType = odata.isCollectionType;
    var isComplex = odata.isComplex;
    var isDeferred = odata.isDeferred;
    var isFeed = odata.isFeed;
    var isEntry = odata.isEntry;
    var isGeographyEdmType = odata.isGeographyEdmType;
    var isGeometryEdmType = odata.isGeometryEdmType;
    var isPrimitiveEdmType = odata.isPrimitiveEdmType;
    var isPrimitive = odata.isPrimitive;
    var lookupComplexType = odata.lookupComplexType;
    var lookupDefaultEntityContainer = odata.lookupDefaultEntityContainer;
    var lookupEntityContainer = odata.lookupEntityContainer;
    var lookupEntitySet = odata.lookupEntitySet;
    var lookupEntityType = odata.lookupEntityType;
    var lookupFunctionImport = odata.lookupFunctionImport;
    var lookupNavigationPropertyType = odata.lookupNavigationPropertyType;
    var getEntitySetInfo = odata.getEntitySetInfo;
    var lookupNavigationPropertyEntitySet = odata.lookupNavigationPropertyEntitySet;
    var lookupProperty = odata.lookupProperty;
    var parseBool = odata.parseBool;
    var parseDateTime = odata.parseDateTime;
    var parseDateTimeOffset = odata.parseDateTimeOffset;
    var parseDuration = odata.parseDuration;

    // CONTENT START

    var PAYLOADTYPE_OBJECT = "o";
    var PAYLOADTYPE_FEED = "f";
    var PAYLOADTYPE_PRIMITIVE = "p";
    var PAYLOADTYPE_COLLECTION = "c";
    var PAYLOADTYPE_SVCDOC = "s";
    var PAYLOADTYPE_LINKS = "l";

    var odataNs = "odata";
    var odataAnnotationPrefix = odataNs + ".";

    var bindAnnotation = "@" + odataAnnotationPrefix + "bind";
    var metadataAnnotation = odataAnnotationPrefix + "metadata";
    var navUrlAnnotation = odataAnnotationPrefix + "navigationLinkUrl";
    var typeAnnotation = odataAnnotationPrefix + "type";

    var jsonLightNameMap = {
        readLink: "self",
        editLink: "edit",
        nextLink: "__next",
        mediaReadLink: "media_src",
        mediaEditLink: "edit_media",
        mediaContentType: "content_type",
        mediaETag: "media_etag",
        count: "__count",
        media_src: "mediaReadLink",
        edit_media: "mediaEditLink",
        content_type: "mediaContentType",
        media_etag: "mediaETag",
        url: "uri"
    };

    var jsonLightAnnotations = {
        metadata: "odata.metadata",
        count: "odata.count",
        next: "odata.nextLink",
        id: "odata.id",
        etag: "odata.etag",
        read: "odata.readLink",
        edit: "odata.editLink",
        mediaRead: "odata.mediaReadLink",
        mediaEdit: "odata.mediaEditLink",
        mediaEtag: "odata.mediaETag",
        mediaContentType: "odata.mediaContentType",
        actions: "odata.actions",
        functions: "odata.functions",
        navigationUrl: "odata.navigationLinkUrl",
        associationUrl: "odata.associationLinkUrl",
        type: "odata.type"
    };

    var jsonLightAnnotationInfo = function (annotation) {
        /// <summary>Gets the name and target of an annotation in a JSON light payload.</summary>
        /// <param name="annotation" type="String">JSON light payload annotation.</param>
        /// <returns type="Object">Object containing the annotation name and the target property name.</param>

        if (annotation.indexOf(".") > 0) {
            var targetEnd = annotation.indexOf("@");
            var target = targetEnd > -1 ? annotation.substring(0, targetEnd) : null;
            var name = annotation.substring(targetEnd + 1);

            return {
                target: target,
                name: name,
                isOData: name.indexOf(odataAnnotationPrefix) === 0
            };
        }
        return null;
    };

    var jsonLightDataItemType = function (name, value, container, dataItemModel, model) {
        /// <summary>Gets the type name of a JSON light data item that belongs to a feed, an entry, a complex type property, or a collection property.</summary>
        /// <param name="name" type="String">Name of the data item for which the type name is going to be retrieved.</param>
        /// <param name="value">Value of the data item.</param>
        /// <param name="container" type="Object">JSON light object that owns the data item.</param>
        /// <param name="dataItemModel" type="Object" optional="true">Object describing the data item in an OData conceptual schema.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <remarks>
        ///    This function will first try to get the type name from the data item's value itself if it is a JSON light object; otherwise
        ///    it will try to get it from the odata.type annotation applied to the data item in the container. Then, it will fallback to the data item model.
        ///    If all attempts fail, it will return null.
        /// </remarks>
        /// <returns type="String">Data item type name; null if the type name cannot be found.</returns>

        return (isComplex(value) && value[typeAnnotation]) ||
            (container && container[name + "@" + typeAnnotation]) ||
            (dataItemModel && dataItemModel.type) ||
            (lookupNavigationPropertyType(dataItemModel, model)) ||
            null;
    };

    var jsonLightDataItemModel = function (name, containerModel) {
        /// <summary>Gets an object describing a data item in an OData conceptual schema.</summary>
        /// <param name="name" type="String">Name of the data item for which the model is going to be retrieved.</param>
        /// <param name="containerModel" type="Object">Object describing the owner of the data item in an OData conceptual schema.</param>
        /// <returns type="Object">Object describing the data item; null if it cannot be found.</returns>

        if (containerModel) {
            return lookupProperty(containerModel.property, name) ||
                lookupProperty(containerModel.navigationProperty, name);
        }
        return null;
    };

    var jsonLightIsEntry = function (data) {
        /// <summary>Determines whether data represents a JSON light entry object.</summary>
        /// <param name="data" type="Object">JSON light object to test.</param>
        /// <returns type="Boolean">True if the data is JSON light entry object; false otherwise.</returns>

        return isComplex(data) && ((odataAnnotationPrefix + "id") in data);
    };

    var jsonLightIsNavigationProperty = function (name, data, dataItemModel) {
        /// <summary>Determines whether a data item in a JSON light object is a navigation property.</summary>
        /// <param name="name" type="String">Name of the data item to test.</param>
        /// <param name="data" type="Object">JSON light object that owns the data item.</param>
        /// <param name="dataItemModel" type="Object">Object describing the data item in an OData conceptual schema.</param>
        /// <returns type="Boolean">True if the data item is a navigation property; false otherwise.</returns>

        djsassert(isComplex(data), "jsonLightIsNavProp - data is not an object!!");
        if (!!data[name + "@" + navUrlAnnotation] || (dataItemModel && dataItemModel.relationship)) {
            return true;
        }

        // Sniff the property value.
        var value = isArray(data[name]) ? data[name][0] : data[name];
        return jsonLightIsEntry(value);
    };

    var jsonLightIsPrimitiveType = function (typeName) {
        /// <summary>Determines whether a type name is a primitive type in a JSON light payload.</summary>
        /// <param name="typeName" type="String">Type name to test.</param>
        /// <returns type="Boolean">True if the type name an EDM primitive type or an OData spatial type; false otherwise.</returns>

        return isPrimitiveEdmType(typeName) || isGeographyEdmType(typeName) || isGeometryEdmType(typeName);
    };

    var jsonLightReadDataAnnotations = function (data, obj, baseURI, dataModel, model) {
        /// <summary>Converts annotations found in a JSON light payload object to either properties or metadata.</summary>
        /// <param name="data" type="Object">JSON light payload object containing the annotations to convert.</param>
        /// <param name="obj" type="Object">Object that will store the converted annotations.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
        /// <param name="dataModel" type="Object">Object describing the JSON light payload in an OData conceptual schema.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <returns>JSON light payload object with its annotations converted to either properties or metadata.</param>

        for (var name in data) {
            if (name.indexOf(".") > 0 && name.charAt(0) !== "#") {
                var annotationInfo = jsonLightAnnotationInfo(name);
                if (annotationInfo) {
                    var annotationName = annotationInfo.name;
                    var target = annotationInfo.target;
                    var targetModel = null;
                    var targetType = null;

                    if (target) {
                        targetModel = jsonLightDataItemModel(target, dataModel);
                        targetType = jsonLightDataItemType(target, data[target], data, targetModel, model);
                    }

                    if (annotationInfo.isOData) {
                        jsonLightApplyPayloadODataAnnotation(annotationName, target, targetType, data[name], data, obj, baseURI);
                    } else {
                        obj[name] = data[name];
                    }
                }
            }
        }
        return obj;
    };

    var jsonLightApplyPayloadODataAnnotation = function (name, target, targetType, value, data, obj, baseURI) {
        /// <summary>
        ///   Processes a JSON Light payload OData annotation producing either a property, payload metadata, or property metadata on its owner object.
        /// </summary>
        /// <param name="name" type="String">Annotation name.</param>
        /// <param name="target" type="String">Name of the property that is being targeted by the annotation.</param>
        /// <param name="targetType" type="String">Type name of the target property.</param>
        /// <param name="data" type="Object">JSON light object containing the annotation.</param>
        /// <param name="obj" type="Object">Object that will hold properties produced by the annotation.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>

        var annotation = name.substring(odataAnnotationPrefix.length);

        switch (annotation) {
            case "navigationLinkUrl":
                jsonLightApplyNavigationUrlAnnotation(annotation, target, targetType, value, data, obj, baseURI);
                return;
            case "nextLink":
            case "count":
                jsonLightApplyFeedAnnotation(annotation, target, value, obj, baseURI);
                return;
            case "mediaReadLink":
            case "mediaEditLink":
            case "mediaContentType":
            case "mediaETag":
                jsonLightApplyMediaAnnotation(annotation, target, targetType, value, obj, baseURI);
                return;
            default:
                jsonLightApplyMetadataAnnotation(annotation, target, value, obj, baseURI);
                return;
        }
    };

    var jsonLightApplyMetadataAnnotation = function (name, target, value, obj, baseURI) {
        /// <summary>
        ///    Converts a JSON light annotation that applies to entry metadata only (i.e. odata.editLink or odata.readLink) and its value
        ///    into their library's internal representation and saves it back to data.
        /// </summary>
        /// <param name="name" type="String">Annotation name.</param>
        /// <param name="target" type="String">Name of the property on which the annotation should be applied.</param>
        /// <param name="value" type="Object">Annotation value.</param>
        /// <param name="obj" type="Object">Object that will hold properties produced by the annotation.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>

        var metadata = obj.__metadata = obj.__metadata || {};
        var mappedName = jsonLightNameMap[name] || name;

        if (name === "editLink") {
            metadata.uri = normalizeURI(value, baseURI);
            metadata[mappedName] = metadata.uri;
            return;
        }

        if (name === "readLink" || name === "associationLinkUrl") {
            value = normalizeURI(value, baseURI);
        }

        if (target) {
            var propertiesMetadata = metadata.properties = metadata.properties || {};
            var propertyMetadata = propertiesMetadata[target] = propertiesMetadata[target] || {};

            if (name === "type") {
                propertyMetadata[mappedName] = propertyMetadata[mappedName] || value;
                return;
            }
            propertyMetadata[mappedName] = value;
            return;
        }
        metadata[mappedName] = value;
    };

    var jsonLightApplyFeedAnnotation = function (name, target, value, obj, baseURI) {
        /// <summary>
        ///    Converts a JSON light annotation that applies to feeds only (i.e. odata.count or odata.nextlink) and its value
        ///    into their library's internal representation and saves it back to data.
        /// </summary>
        /// <param name="name" type="String">Annotation name.</param>
        /// <param name="target" type="String">Name of the property on which the annotation should be applied.</param>
        /// <param name="value" type="Object">Annotation value.</param>
        /// <param name="obj" type="Object">Object that will hold properties produced by the annotation.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>

        var mappedName = jsonLightNameMap[name];
        var feed = target ? obj[target] : obj;
        feed[mappedName] = (name === "nextLink") ? normalizeURI(value, baseURI) : value;
    };

    var jsonLightApplyMediaAnnotation = function (name, target, targetType, value, obj, baseURI) {
        /// <summary>
        ///    Converts a JSON light media annotation in and its value into their library's internal representation
        ///    and saves it back to data or metadata.
        /// </summary>
        /// <param name="name" type="String">Annotation name.</param>
        /// <param name="target" type="String">Name of the property on which the annotation should be applied.</param>
        /// <param name="targetType" type="String">Type name of the target property.</param>
        /// <param name="value" type="Object">Annotation value.</param>
        /// <param name="obj" type="Object">Object that will hold properties produced by the annotation.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>

        var metadata = obj.__metadata = obj.__metadata || {};
        var mappedName = jsonLightNameMap[name];

        if (name === "mediaReadLink" || name === "mediaEditLink") {
            value = normalizeURI(value, baseURI);
        }

        if (target) {
            var propertiesMetadata = metadata.properties = metadata.properties || {};
            var propertyMetadata = propertiesMetadata[target] = propertiesMetadata[target] || {};
            propertyMetadata.type = propertyMetadata.type || targetType;

            obj.__metadata = metadata;
            obj[target] = obj[target] || { __mediaresource: {} };
            obj[target].__mediaresource[mappedName] = value;
            return;
        }

        metadata[mappedName] = value;
    };

    var jsonLightApplyNavigationUrlAnnotation = function (name, target, targetType, value, data, obj, baseURI) {
        /// <summary>
        ///    Converts a JSON light navigation property annotation and its value into their library's internal representation
        ///    and saves it back to data o metadata.
        /// </summary>
        /// <param name="name" type="String">Annotation name.</param>
        /// <param name="target" type="String">Name of the property on which the annotation should be applied.</param>
        /// <param name="targetType" type="String">Type name of the target property.</param>
        /// <param name="value" type="Object">Annotation value.</param>
        /// <param name="data" type="Object">JSON light object containing the annotation.</param>
        /// <param name="obj" type="Object">Object that will hold properties produced by the annotation.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>

        var metadata = obj.__metadata = obj.__metadata || {};
        var propertiesMetadata = metadata.properties = metadata.properties || {};
        var propertyMetadata = propertiesMetadata[target] = propertiesMetadata[target] || {};
        var uri = normalizeURI(value, baseURI);

        if (data.hasOwnProperty(target)) {
            // The navigation property is inlined in the payload,
            // so the navigation link url should be pushed to the object's
            // property metadata instead.
            propertyMetadata.navigationLinkUrl = uri;
            return;
        }
        obj[target] = { __deferred: { uri: uri} };
        propertyMetadata.type = propertyMetadata.type || targetType;
    };


    var jsonLightReadDataItemValue = function (value, typeName, dataItemMetadata, baseURI, dataItemModel, model, recognizeDates) {
        /// <summary>Converts the value of a data item in a JSON light object to its library representation.</summary>
        /// <param name="value">Data item value to convert.</param>
        /// <param name="typeName" type="String">Type name of the data item.</param>
        /// <param name="dataItemMetadata" type="Object">Object containing metadata about the data item.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
        /// <param name="dataItemModel" type="Object" optional="true">Object describing the data item in an OData conceptual schema.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
        /// <returns>Data item value in its library representation.</param>

        if (typeof value === "string") {
            return jsonLightReadStringPropertyValue(value, typeName, recognizeDates);
        }

        if (!jsonLightIsPrimitiveType(typeName)) {
            if (isArray(value)) {
                return jsonLightReadCollectionPropertyValue(value, typeName, dataItemMetadata, baseURI, model, recognizeDates);
            }

            if (isComplex(value)) {
                return jsonLightReadComplexPropertyValue(value, typeName, dataItemMetadata, baseURI, model, recognizeDates);
            }
        }
        return value;
    };

    var jsonLightReadStringPropertyValue = function (value, propertyType, recognizeDates) {
        /// <summary>Convertes the value of a string property in a JSON light object to its library representation.</summary>
        /// <param name="value" type="String">String value to convert.</param>
        /// <param name="propertyType" type="String">Type name of the property.</param>
        /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
        /// <returns>String property value in its library representation.</returns>

        switch (propertyType) {
            case EDM_TIME:
                return parseDuration(value);
            case EDM_DATETIME:
                return parseDateTime(value, /*nullOnError*/false);
            case EDM_DATETIMEOFFSET:
                return parseDateTimeOffset(value, /*nullOnError*/false);
        }

        if (recognizeDates) {
            return parseDateTime(value, /*nullOnError*/true) ||
                   parseDateTimeOffset(value, /*nullOnError*/true) ||
                   value;
        }
        return value;
    };

    var jsonLightReadCollectionPropertyValue = function (value, propertyType, propertyMetadata, baseURI, model, recognizeDates) {
        /// <summary>Converts the value of a collection property in a JSON light object into its library representation.</summary>
        /// <param name="value" type="Array">Collection property value to convert.</param>
        /// <param name="propertyType" type="String">Property type name.</param>
        /// <param name="propertyMetadata" type="Object">Object containing metadata about the collection property.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
        /// <returns type="Object">Collection property value in its library representation.</returns>

        var collectionType = getCollectionType(propertyType);
        var itemsMetadata = [];
        var items = [];

        var i, len;
        for (i = 0, len = value.length; i < len; i++) {
            var itemType = jsonLightDataItemType(null, value[i]) || collectionType;
            var itemMetadata = { type: itemType };
            var item = jsonLightReadDataItemValue(value[i], itemType, itemMetadata, baseURI, null, model, recognizeDates);

            if (!jsonLightIsPrimitiveType(itemType) && !isPrimitive(value[i])) {
                itemsMetadata.push(itemMetadata);
            }
            items.push(item);
        }

        if (itemsMetadata.length > 0) {
            propertyMetadata.elements = itemsMetadata;
        }

        return { __metadata: { type: propertyType }, results: items };
    };

    var jsonLightReadComplexPropertyValue = function (value, propertyType, propertyMetadata, baseURI, model, recognizeDates) {
        /// <summary>Converts the value of a comples property in a JSON light object into its library representation.</summary>
        /// <param name="value" type="Object">Complex property value to convert.</param>
        /// <param name="propertyType" type="String">Property type name.</param>
        /// <param name="propertyMetadata" type="Object">Object containing metadata about the complx type property.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
        /// <returns type="Object">Complex property value in its library representation.</returns>

        var complexValue = jsonLightReadObject(value, { type: propertyType }, baseURI, model, recognizeDates);
        var complexMetadata = complexValue.__metadata;
        var complexPropertiesMetadata = complexMetadata.properties;

        if (complexPropertiesMetadata) {
            propertyMetadata.properties = complexPropertiesMetadata;
            delete complexMetadata.properties;
        }
        return complexValue;
    };

    var jsonLightReadNavigationPropertyValue = function (value, propertyInfo, baseURI, model, recognizeDates) {
        /// <summary>Converts the value of a navigation property in a JSON light object into its library representation.</summary>
        /// <param name="value">Navigation property property value to convert.</param>
        /// <param name="propertyInfo" type="String">Information about the property whether it's an entry, feed or complex type.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
        /// <returns type="Object">Collection property value in its library representation.</returns>

        if (isArray(value)) {
            return jsonLightReadFeed(value, propertyInfo, baseURI, model, recognizeDates);
        }

        if (isComplex(value)) {
            return jsonLightReadObject(value, propertyInfo, baseURI, model, recognizeDates);
        }
        return null;
    };

    var jsonLightReadObject = function (data, objectInfo, baseURI, model, recognizeDates) {
        /// <summary>Converts a JSON light entry or complex type object into its library representation.</summary>
        /// <param name="data" type="Object">JSON light entry or complex type object to convert.</param>
        /// <param name="objectInfo" type="Object">Information about the entry or complex.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
        /// <returns type="Object">Entry or complex type object.</param>

        objectInfo = objectInfo || {};
        var actualType = data[typeAnnotation] || objectInfo.type || null;
        var dataModel = lookupEntityType(actualType, model);
        var isEntry = true;
        if (!dataModel) {
            isEntry = false;
            dataModel = lookupComplexType(actualType, model);
        }

        var metadata = { type: actualType };
        var obj = { __metadata: metadata };
        var propertiesMetadata = {};
        var baseTypeModel;
        if (isEntry && dataModel && objectInfo.entitySet && objectInfo.contentTypeOdata == "minimalmetadata") {
            var serviceURI = baseURI.substring(0, baseURI.lastIndexOf("$metadata"));
            baseTypeModel = null; // check if the key model is in a parent type.
            if (!dataModel.key) {
                baseTypeModel = dataModel;
            }
            while (!!baseTypeModel && !baseTypeModel.key && baseTypeModel.baseType) {
                baseTypeModel = lookupEntityType(baseTypeModel.baseType, model);
            }

            if (dataModel.key || (!!baseTypeModel && baseTypeModel.key)) {
                var entryKey;
                if (dataModel.key) {
                    entryKey = jsonLightGetEntryKey(data, dataModel);
                } else {
                    entryKey = jsonLightGetEntryKey(data, baseTypeModel);
                }
                if (entryKey) {
                    var entryInfo = {
                        key: entryKey,
                        entitySet: objectInfo.entitySet,
                        functionImport: objectInfo.functionImport,
                        containerName: objectInfo.containerName
                    };
                    jsonLightComputeUrisIfMissing(data, entryInfo, actualType, serviceURI, dataModel, baseTypeModel);
                }
            }
        }

        for (var name in data) {
            if (name.indexOf("#") === 0) {
                // This is an advertised function or action.
                jsonLightReadAdvertisedFunctionOrAction(name.substring(1), data[name], obj, baseURI, model);
            } else {
                // Is name NOT an annotation?
                if (name.indexOf(".") === -1) {
                    if (!metadata.properties) {
                        metadata.properties = propertiesMetadata;
                    }

                    var propertyValue = data[name];
                    var propertyModel = propertyModel = jsonLightDataItemModel(name, dataModel);
                    baseTypeModel = dataModel;
                    while (!!dataModel && propertyModel === null && baseTypeModel.baseType) {
                        baseTypeModel = lookupEntityType(baseTypeModel.baseType, model);
                        propertyModel = propertyModel = jsonLightDataItemModel(name, baseTypeModel);
                    }
                    var isNavigationProperty = jsonLightIsNavigationProperty(name, data, propertyModel);
                    var propertyType = jsonLightDataItemType(name, propertyValue, data, propertyModel, model);
                    var propertyMetadata = propertiesMetadata[name] = propertiesMetadata[name] || { type: propertyType };
                    if (isNavigationProperty) {
                        var propertyInfo = {};
                        if (objectInfo.entitySet !== undefined) {
                            var navigationPropertyEntitySetName = lookupNavigationPropertyEntitySet(propertyModel, objectInfo.entitySet.name, model);
                            propertyInfo = getEntitySetInfo(navigationPropertyEntitySetName, model);
                        }
                        propertyInfo.contentTypeOdata = objectInfo.contentTypeOdata;
                        propertyInfo.kind = objectInfo.kind;
                        propertyInfo.type = propertyType;
                        obj[name] = jsonLightReadNavigationPropertyValue(propertyValue, propertyInfo, baseURI, model, recognizeDates);
                    } else {
                        obj[name] = jsonLightReadDataItemValue(propertyValue, propertyType, propertyMetadata, baseURI, propertyModel, model, recognizeDates);
                    }
                }
            }
        }

        return jsonLightReadDataAnnotations(data, obj, baseURI, dataModel, model);
    };

    var jsonLightReadAdvertisedFunctionOrAction = function (name, value, obj, baseURI, model) {
        /// <summary>Converts a JSON light advertised action or function object into its library representation.</summary>
        /// <param name="name" type="String">Advertised action or function name.</param>
        /// <param name="value">Advertised action or function value.</param>
        /// <param name="obj" type="Object">Object that will the converted value of the advertised action or function.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing the action's or function's relative URIs.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <remarks>
        ///     Actions and functions have the same representation in json light, so to disambiguate them the function uses
        ///     the model object.  If available, the function will look for the functionImport object that describes the
        ///     the action or the function.  If for whatever reason the functionImport can't be retrieved from the model (like
        ///     there is no model available or there is no functionImport within the model), then the value is going to be treated
        ///     as an advertised action and stored under obj.__metadata.actions.
        /// </remarks>

        if (!name || !isArray(value) && !isComplex(value)) {
            return;
        }

        var isFunction = false;
        var nsEnd = name.lastIndexOf(".");
        var simpleName = name.substring(nsEnd + 1);
        var containerName = (nsEnd > -1) ? name.substring(0, nsEnd) : "";

        var container = (simpleName === name || containerName.indexOf(".") === -1) ?
            lookupDefaultEntityContainer(model) :
            lookupEntityContainer(containerName, model);

        if (container) {
            var functionImport = lookupFunctionImport(container.functionImport, simpleName);
            if (functionImport && !!functionImport.isSideEffecting) {
                isFunction = !parseBool(functionImport.isSideEffecting);
            }
        }

        var metadata = obj.__metadata;
        var targetName = isFunction ? "functions" : "actions";
        var metadataURI = normalizeURI(name, baseURI);
        var items = (isArray(value)) ? value : [value];

        var i, len;
        for (i = 0, len = items.length; i < len; i++) {
            var item = items[i];
            if (item) {
                var targetCollection = metadata[targetName] = metadata[targetName] || [];
                var actionOrFunction = { metadata: metadataURI, title: item.title, target: normalizeURI(item.target, baseURI) };
                targetCollection.push(actionOrFunction);
            }
        }
    };

    var jsonLightReadFeed = function (data, feedInfo, baseURI, model, recognizeDates) {
        /// <summary>Converts a JSON light feed or top level collection property object into its library representation.</summary>
        /// <param name="data" type="Object">JSON light feed object to convert.</param>
        /// <param name="typeName" type="String">Type name of the feed or collection items.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
        /// <returns type="Object">Feed or top level collection object.</param>

        var items = isArray(data) ? data : data.value;
        var entries = [];
        var i, len, entry;
        for (i = 0, len = items.length; i < len; i++) {
            entry = jsonLightReadObject(items[i], feedInfo, baseURI, model, recognizeDates);
            entries.push(entry);
        }

        var feed = { results: entries };

        if (isComplex(data)) {
            for (var name in data) {
                if (name.indexOf("#") === 0) {
                    // This is an advertised function or action.
                    feed.__metadata = feed.__metadata || {};
                    jsonLightReadAdvertisedFunctionOrAction(name.substring(1), data[name], feed, baseURI, model);
                }
            }
            feed = jsonLightReadDataAnnotations(data, feed, baseURI);
        }
        return feed;
    };

    var jsonLightGetEntryKey = function (data, entityModel) {
        /// <summary>Gets the key of an entry.</summary>
        /// <param name="data" type="Object">JSON light entry.</param>
        /// <param name="entityModel" type="String">Object describing the entry Model</param>
        /// <returns type="string">Entry instance key.</returns>

        var entityInstanceKey;
        var entityKeys = entityModel.key.propertyRef;
        var type;
        entityInstanceKey = "(";
        if (entityKeys.length == 1) {
            type = lookupProperty(entityModel.property, entityKeys[0].name).type;
            entityInstanceKey += formatLiteral(data[entityKeys[0].name], type);
        } else {
            var first = true;
            for (var i = 0; i < entityKeys.length; i++) {
                if (!first) {
                    entityInstanceKey += ",";
                } else {
                    first = false;
                }
                type = lookupProperty(entityModel.property, entityKeys[i].name).type;
                entityInstanceKey += entityKeys[i].name + "=" + formatLiteral(data[entityKeys[i].name], type);
            }
        }
        entityInstanceKey += ")";
        return entityInstanceKey;
    };


    var jsonLightComputeUrisIfMissing = function (data, entryInfo, actualType, serviceURI, entityModel, baseTypeModel) {
        /// <summary>Compute the URI according to OData conventions if it doesn't exist</summary>
        /// <param name="data" type="Object">JSON light entry.</param>
        /// <param name="entryInfo" type="Object">Information about the entry includes type, key, entitySet and entityContainerName.</param>
        /// <param name="actualType" type="String">Type of the entry</param>
        /// <param name="serviceURI" type="String">Base URI the service.</param>
        /// <param name="entityModel" type="Object">Object describing an OData conceptual schema of the entry.</param>
        /// <param name="baseTypeModel" type="Object" optional="true">Object escribing an OData conceptual schema of the baseType if it exists.</param>

        var lastIdSegment = data[jsonLightAnnotations.id] || data[jsonLightAnnotations.read] || data[jsonLightAnnotations.edit] || entryInfo.entitySet.name + entryInfo.key;
        data[jsonLightAnnotations.id] = serviceURI + lastIdSegment;
        if (!data[jsonLightAnnotations.edit]) {
            data[jsonLightAnnotations.edit] = entryInfo.entitySet.name + entryInfo.key;
            if (entryInfo.entitySet.entityType != actualType) {
                data[jsonLightAnnotations.edit] += "/" + actualType;
            }
        }
        data[jsonLightAnnotations.read] = data[jsonLightAnnotations.read] || data[jsonLightAnnotations.edit];
        if (!data[jsonLightAnnotations.etag]) {
            var etag = jsonLightComputeETag(data, entityModel, baseTypeModel);
            if (!!etag) {
                data[jsonLightAnnotations.etag] = etag;
            }
        }

        jsonLightComputeStreamLinks(data, entityModel, baseTypeModel);
        jsonLightComputeNavigationAndAssociationProperties(data, entityModel, baseTypeModel);
        jsonLightComputeFunctionImports(data, entryInfo);
    };

    var jsonLightComputeETag = function (data, entityModel, baseTypeModel) {
        /// <summary>Computes the etag of an entry</summary>
        /// <param name="data" type="Object">JSON light entry.</param>
        /// <param name="entryInfo" type="Object">Object describing the entry model.</param>
        /// <param name="baseTypeModel" type="Object"  optional="true">Object describing an OData conceptual schema of the baseType if it exists.</param>
        /// <returns type="string">Etag value</returns>
        var etag = "";
        var propertyModel;
        for (var i = 0; entityModel.property && i < entityModel.property.length; i++) {
            propertyModel = entityModel.property[i];
            etag = jsonLightAppendValueToEtag(data, etag, propertyModel);

        }
        if (baseTypeModel) {
            for (i = 0; baseTypeModel.property && i < baseTypeModel.property.length; i++) {
                propertyModel = baseTypeModel.property[i];
                etag = jsonLightAppendValueToEtag(data, etag, propertyModel);
            }
        }
        if (etag.length > 0) {
            return etag + "\"";
        }
        return null;
    };

    var jsonLightAppendValueToEtag = function (data, etag, propertyModel) {
        /// <summary>Adds a propery value to the etag after formatting.</summary>
        /// <param name="data" type="Object">JSON light entry.</param>
        /// <param name="etag" type="Object">value of the etag.</param>
        /// <param name="propertyModel" type="Object">Object describing an OData conceptual schema of the property.</param>
        /// <returns type="string">Etag value</returns>

        if (propertyModel.concurrencyMode == "Fixed") {
            if (etag.length > 0) {
                etag += ",";
            } else {
                etag += "W/\"";
            }
            if (data[propertyModel.name] !== null) {
                etag += formatLiteral(data[propertyModel.name], propertyModel.type);
            } else {
                etag += "null";
            }
        }
        return etag;
    };

    var jsonLightComputeNavigationAndAssociationProperties = function (data, entityModel, baseTypeModel) {
        /// <summary>Adds navigation links to the entry metadata</summary>
        /// <param name="data" type="Object">JSON light entry.</param>
        /// <param name="entityModel" type="Object">Object describing the entry model.</param>
        /// <param name="baseTypeModel" type="Object"  optional="true">Object describing an OData conceptual schema of the baseType if it exists.</param>

        var navigationLinkAnnotation = "@odata.navigationLinkUrl";
        var associationLinkAnnotation = "@odata.associationLinkUrl";
        var navigationPropertyName, navigationPropertyAnnotation, associationPropertyAnnotation;
        for (var i = 0; entityModel.navigationProperty && i < entityModel.navigationProperty.length; i++) {
            navigationPropertyName = entityModel.navigationProperty[i].name;
            navigationPropertyAnnotation = navigationPropertyName + navigationLinkAnnotation;
            if (data[navigationPropertyAnnotation] === undefined) {
                data[navigationPropertyAnnotation] = data[jsonLightAnnotations.edit] + "/" + encodeURIComponent(navigationPropertyName);
            }
            associationPropertyAnnotation = navigationPropertyName + associationLinkAnnotation;
            if (data[associationPropertyAnnotation] === undefined) {
                data[associationPropertyAnnotation] = data[jsonLightAnnotations.edit] + "/$links/" + encodeURIComponent(navigationPropertyName);
            }
        }

        if (baseTypeModel && baseTypeModel.navigationProperty) {
            for (i = 0; i < baseTypeModel.navigationProperty.length; i++) {
                navigationPropertyName = baseTypeModel.navigationProperty[i].name;
                navigationPropertyAnnotation = navigationPropertyName + navigationLinkAnnotation;
                if (data[navigationPropertyAnnotation] === undefined) {
                    data[navigationPropertyAnnotation] = data[jsonLightAnnotations.edit] + "/" + encodeURIComponent(navigationPropertyName);
                }
                associationPropertyAnnotation = navigationPropertyName + associationLinkAnnotation;
                if (data[associationPropertyAnnotation] === undefined) {
                    data[associationPropertyAnnotation] = data[jsonLightAnnotations.edit] + "/$links/" + encodeURIComponent(navigationPropertyName);
                }
            }
        }
    };

    var formatLiteral = function (value, type) {
        /// <summary>Formats a value according to Uri literal format</summary>
        /// <param name="value">Value to be formatted.</param>
        /// <param name="type">Edm type of the value</param>
        /// <returns type="string">Value after formatting</returns>

        value = "" + formatRowLiteral(value, type);
        value = encodeURIComponent(value.replace("'", "''"));
        switch ((type)) {
            case "Edm.Binary":
                return "X'" + value + "'";
            case "Edm.DateTime":
                return "datetime" + "'" + value + "'";
            case "Edm.DateTimeOffset":
                return "datetimeoffset" + "'" + value + "'";
            case "Edm.Decimal":
                return value + "M";
            case "Edm.Guid":
                return "guid" + "'" + value + "'";
            case "Edm.Int64":
                return value + "L";
            case "Edm.Float":
                return value + "f";
            case "Edm.Double":
                return value + "D";
            case "Edm.Geography":
                return "geography" + "'" + value + "'";
            case "Edm.Geometry":
                return "geometry" + "'" + value + "'";
            case "Edm.Time":
                return "time" + "'" + value + "'";
            case "Edm.String":
                return "'" + value + "'";
            default:
                return value;
        }
    };


    var formatRowLiteral = function (value, type) {
        switch (type) {
            case "Edm.Binary":
                return convertByteArrayToHexString(value);
            default:
                return value;
        }
    };

    var jsonLightComputeFunctionImports = function (data, entryInfo) {
        /// <summary>Adds functions and actions links to the entry metadata</summary>
        /// <param name="entry" type="Object">JSON light entry.</param>
        /// <param name="entityInfo" type="Object">Object describing the entry</param>

        var functionImport = entryInfo.functionImport || [];
        for (var i = 0; i < functionImport.length; i++) {
            if (functionImport[i].isBindable && functionImport[i].parameter[0] && functionImport[i].parameter[0].type == entryInfo.entitySet.entityType) {
                var functionImportAnnotation = "#" + entryInfo.containerName + "." + functionImport[i].name;
                if (data[functionImportAnnotation] == undefined) {
                    data[functionImportAnnotation] = {
                        title: functionImport[i].name,
                        target: data[jsonLightAnnotations.edit] + "/" + functionImport[i].name
                    };
                }
            }
        }
    };

    var jsonLightComputeStreamLinks = function (data, entityModel, baseTypeModel) {
        /// <summary>Adds stream links to the entry metadata</summary>
        /// <param name="data" type="Object">JSON light entry.</param>
        /// <param name="entityModel" type="Object">Object describing the entry model.</param>
        /// <param name="baseTypeModel" type="Object"  optional="true">Object describing an OData conceptual schema of the baseType if it exists.</param>

        if (entityModel.hasStream || (baseTypeModel && baseTypeModel.hasStream)) {
            data[jsonLightAnnotations.mediaEdit] = data[jsonLightAnnotations.mediaEdit] || data[jsonLightAnnotations.mediaEdit] + "/$value";
            data[jsonLightAnnotations.mediaRead] = data[jsonLightAnnotations.mediaRead] || data[jsonLightAnnotations.mediaEdit];
        }
    };

    var jsonLightReadTopPrimitiveProperty = function (data, typeName, baseURI, recognizeDates) {
        /// <summary>Converts a JSON light top level primitive property object into its library representation.</summary>
        /// <param name="data" type="Object">JSON light feed object to convert.</param>
        /// <param name="typeName" type="String">Type name of the primitive property.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
        /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
        /// <returns type="Object">Top level primitive property object.</param>

        var metadata = { type: typeName };
        var value = jsonLightReadDataItemValue(data.value, typeName, metadata, baseURI, null, null, recognizeDates);
        return jsonLightReadDataAnnotations(data, { __metadata: metadata, value: value }, baseURI);
    };

    var jsonLightReadTopCollectionProperty = function (data, typeName, baseURI, model, recognizeDates) {
        /// <summary>Converts a JSON light top level collection property object into its library representation.</summary>
        /// <param name="data" type="Object">JSON light feed object to convert.</param>
        /// <param name="typeName" type="String">Type name of the collection property.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
        /// <returns type="Object">Top level collection property object.</param>

        var propertyMetadata = {};
        var value = jsonLightReadCollectionPropertyValue(data.value, typeName, propertyMetadata, baseURI, model, recognizeDates);
        extend(value.__metadata, propertyMetadata);
        return jsonLightReadDataAnnotations(data, value, baseURI);
    };

    var jsonLightReadLinksDocument = function (data, baseURI) {
        /// <summary>Converts a JSON light links collection object to its library representation.</summary>
        /// <param name="data" type="Object">JSON light link object to convert.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
        /// <returns type="Object">Links collection object.</param>

        var items = data.value;
        if (!isArray(items)) {
            return jsonLightReadLink(data, baseURI);
        }

        var results = [];
        var i, len;
        for (i = 0, len = items.length; i < len; i++) {
            results.push(jsonLightReadLink(items[i], baseURI));
        }

        var links = { results: results };
        return jsonLightReadDataAnnotations(data, links, baseURI);
    };

    var jsonLightReadLink = function (data, baseURI) {
        /// <summary>Converts a JSON light link object to its library representation.</summary>
        /// <param name="data" type="Object">JSON light link object to convert.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
        /// <returns type="Object">Link object.</param>

        var link = { uri: normalizeURI(data.url, baseURI) };

        link = jsonLightReadDataAnnotations(data, link, baseURI);
        var metadata = link.__metadata || {};
        var metadataProperties = metadata.properties || {};

        jsonLightRemoveTypePropertyMetadata(metadataProperties.url);
        renameProperty(metadataProperties, "url", "uri");

        return link;
    };

    var jsonLightRemoveTypePropertyMetadata = function (propertyMetadata) {
        /// <summary>Removes the type property from a property metadata object.</summary>
        /// <param name="propertyMetadata" type="Object">Property metadata object.</param>

        if (propertyMetadata) {
            delete propertyMetadata.type;
        }
    };

    var jsonLightReadSvcDocument = function (data, baseURI) {
        /// <summary>Converts a JSON light service document object to its library representation.</summary>
        /// <param name="data" type="Object">JSON light service document object to convert.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
        /// <returns type="Object">Link object.</param>

        var items = data.value;
        var collections = [];
        var workspace = jsonLightReadDataAnnotations(data, { collections: collections }, baseURI);

        var metadata = workspace.__metadata || {};
        var metadataProperties = metadata.properties || {};

        jsonLightRemoveTypePropertyMetadata(metadataProperties.value);
        renameProperty(metadataProperties, "value", "collections");

        var i, len;
        for (i = 0, len = items.length; i < len; i++) {
            var item = items[i];
            var collection = { title: item.name, href: normalizeURI(item.url, baseURI) };

            collection = jsonLightReadDataAnnotations(item, collection, baseURI);
            metadata = collection.__metadata || {};
            metadataProperties = metadata.properties || {};

            jsonLightRemoveTypePropertyMetadata(metadataProperties.name);
            jsonLightRemoveTypePropertyMetadata(metadataProperties.url);

            renameProperty(metadataProperties, "name", "title");
            renameProperty(metadataProperties, "url", "href");

            collections.push(collection);
        }

        return { workspaces: [workspace] };
    };

    var jsonLightMakePayloadInfo = function (kind, type) {
        /// <summary>Creates an object containing information for the json light payload.</summary>
        /// <param name="kind" type="String">JSON light payload kind, one of the PAYLOADTYPE_XXX constant values.</param>
        /// <param name="typeName" type="String">Type name of the JSON light payload.</param>
        /// <returns type="Object">Object with kind and type fields.</returns>

        /// <field name="kind" type="String">Kind of the JSON light payload. One of the PAYLOADTYPE_XXX constant values.</field>
        /// <field name="type" type="String">Data type of the JSON light payload.</field>

        return { kind: kind, type: type || null };
    };

    var jsonLightPayloadInfo = function (data, model, inferFeedAsComplexType) {
        /// <summary>Infers the information describing the JSON light payload from its metadata annotation, structure, and data model.</summary>
        /// <param name="data" type="Object">Json light response payload object.</param>
        /// <param name="model" type="Object">Object describing an OData conceptual schema.</param>
        /// <param name="inferFeedAsComplexType" type="Boolean">True if a JSON light payload that looks like a feed should be treated as a complex type property instead.</param>
        /// <remarks>
        ///     If the arguments passed to the function don't convey enough information about the payload to determine without doubt that the payload is a feed then it
        ///     will try to use the payload object structure instead.  If the payload looks like a feed (has value property that is an array or non-primitive values) then
        ///     the function will report its kind as PAYLOADTYPE_FEED unless the inferFeedAsComplexType flag is set to true. This flag comes from the user request
        ///     and allows the user to control how the library behaves with an ambigous JSON light payload.
        /// </remarks>
        /// <returns type="Object">
        ///     Object with kind and type fields. Null if there is no metadata annotation or the payload info cannot be obtained..
        /// </returns>

        var metadataUri = data[metadataAnnotation];
        if (!metadataUri || typeof metadataUri !== "string") {
            return null;
        }

        var fragmentStart = metadataUri.lastIndexOf("#");
        if (fragmentStart === -1) {
            return jsonLightMakePayloadInfo(PAYLOADTYPE_SVCDOC);
        }

        var elementStart = metadataUri.indexOf("@Element", fragmentStart);
        var fragmentEnd = elementStart - 1;

        if (fragmentEnd < 0) {
            fragmentEnd = metadataUri.indexOf("?", fragmentStart);
            if (fragmentEnd === -1) {
                fragmentEnd = metadataUri.length;
            }
        }

        var fragment = metadataUri.substring(fragmentStart + 1, fragmentEnd);
        if (fragment.indexOf("/$links/") > 0) {
            return jsonLightMakePayloadInfo(PAYLOADTYPE_LINKS);
        }

        var fragmentParts = fragment.split("/");
        if (fragmentParts.length >= 0) {
            var qualifiedName = fragmentParts[0];
            var typeCast = fragmentParts[1];

            if (jsonLightIsPrimitiveType(qualifiedName)) {
                return jsonLightMakePayloadInfo(PAYLOADTYPE_PRIMITIVE, qualifiedName);
            }

            if (isCollectionType(qualifiedName)) {
                return jsonLightMakePayloadInfo(PAYLOADTYPE_COLLECTION, qualifiedName);
            }

            var entityType = typeCast;
            var entitySet, functionImport, containerName;
            if (!typeCast) {
                var nsEnd = qualifiedName.lastIndexOf(".");
                var simpleName = qualifiedName.substring(nsEnd + 1);
                var container = (simpleName === qualifiedName) ?
                    lookupDefaultEntityContainer(model) :
                    lookupEntityContainer(qualifiedName.substring(0, nsEnd), model);

                if (container) {
                    entitySet = lookupEntitySet(container.entitySet, simpleName);
                    functionImport = container.functionImport;
                    containerName = container.name;
                    entityType = !!entitySet ? entitySet.entityType : null;
                }
            }

            var info;
            if (elementStart > 0) {
                info = jsonLightMakePayloadInfo(PAYLOADTYPE_OBJECT, entityType);
                info.entitySet = entitySet;
                info.functionImport = functionImport;
                info.containerName = containerName;
                return info;
            }

            if (entityType) {
                info = jsonLightMakePayloadInfo(PAYLOADTYPE_FEED, entityType);
                info.entitySet = entitySet;
                info.functionImport = functionImport;
                info.containerName = containerName;
                return info;
            }

            if (isArray(data.value) && !lookupComplexType(qualifiedName, model)) {
                var item = data.value[0];
                if (!isPrimitive(item)) {
                    if (jsonLightIsEntry(item) || !inferFeedAsComplexType) {
                        return jsonLightMakePayloadInfo(PAYLOADTYPE_FEED, null);
                    }
                }
            }

            return jsonLightMakePayloadInfo(PAYLOADTYPE_OBJECT, qualifiedName);
        }

        return null;
    };

    var jsonLightReadPayload = function (data, model, recognizeDates, inferFeedAsComplexType, contentTypeOdata) {
        /// <summary>Converts a JSON light response payload object into its library's internal representation.</summary>
        /// <param name="data" type="Object">Json light response payload object.</param>
        /// <param name="model" type="Object">Object describing an OData conceptual schema.</param>
        /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
        /// <param name="inferFeedAsComplexType" type="Boolean">True if a JSON light payload that looks like a feed should be reported as a complex type property instead.</param>
        /// <param name="contentTypeOdata" type="string">Includes the type of json ( minimalmetadata, fullmetadata .. etc )</param>
        /// <returns type="Object">Object in the library's representation.</returns>

        if (!isComplex(data)) {
            return data;
        }

        contentTypeOdata = contentTypeOdata || "minimalmetadata";
        var baseURI = data[metadataAnnotation];
        var payloadInfo = jsonLightPayloadInfo(data, model, inferFeedAsComplexType);
        if (assigned(payloadInfo)) {
            payloadInfo.contentTypeOdata = contentTypeOdata;
        }
        var typeName = null;
        if (payloadInfo) {
            delete data[metadataAnnotation];

            typeName = payloadInfo.type;
            switch (payloadInfo.kind) {
                case PAYLOADTYPE_FEED:
                    return jsonLightReadFeed(data, payloadInfo, baseURI, model, recognizeDates);
                case PAYLOADTYPE_COLLECTION:
                    return jsonLightReadTopCollectionProperty(data, typeName, baseURI, model, recognizeDates);
                case PAYLOADTYPE_PRIMITIVE:
                    return jsonLightReadTopPrimitiveProperty(data, typeName, baseURI, recognizeDates);
                case PAYLOADTYPE_SVCDOC:
                    return jsonLightReadSvcDocument(data, baseURI);
                case PAYLOADTYPE_LINKS:
                    return jsonLightReadLinksDocument(data, baseURI);
            }
        }
        return jsonLightReadObject(data, payloadInfo, baseURI, model, recognizeDates);
    };

    var jsonLightSerializableMetadata = ["type", "etag", "media_src", "edit_media", "content_type", "media_etag"];

    var formatJsonLight = function (obj, context) {
        /// <summary>Converts an object in the library's internal representation to its json light representation.</summary>
        /// <param name="obj" type="Object">Object the library's internal representation.</param>
        /// <param name="context" type="Object">Object with the serialization context.</param>
        /// <returns type="Object">Object in its json light representation.</returns>

        // Regular expression used to test that the uri is for a $links document.
        var linksUriRE = /\/\$links\//;
        var data = {};
        var metadata = obj.__metadata;

        var islinks = context && linksUriRE.test(context.request.requestUri);
        formatJsonLightData(obj, (metadata && metadata.properties), data, islinks);
        return data;
    };

    var formatJsonLightMetadata = function (metadata, data) {
        /// <summary>Formats an object's metadata into the appropriate json light annotations and saves them to data.</summary>
        /// <param name="obj" type="Object">Object whose metadata is going to be formatted as annotations.</param>
        /// <param name="data" type="Object">Object on which the annotations are going to be stored.</param>

        if (metadata) {
            var i, len;
            for (i = 0, len = jsonLightSerializableMetadata.length; i < len; i++) {
                // There is only a subset of metadata values that are interesting during update requests.
                var name = jsonLightSerializableMetadata[i];
                var qName = odataAnnotationPrefix + (jsonLightNameMap[name] || name);
                formatJsonLightAnnotation(qName, null, metadata[name], data);
            }
        }
    };

    var formatJsonLightData = function (obj, pMetadata, data, isLinks) {
        /// <summary>Formats an object's data into the appropriate json light values and saves them to data.</summary>
        /// <param name="obj" type="Object">Object whose data is going to be formatted.</param>
        /// <param name="pMetadata" type="Object">Object that contains metadata for the properties that are being formatted.</param>
        /// <param name="data" type="Object">Object on which the formatted values are going to be stored.</param>
        /// <param name="isLinks" type="Boolean">True if a links document is being formatted.  False otherwise.</param>

        for (var key in obj) {
            var value = obj[key];
            if (key === "__metadata") {
                // key is the object metadata.
                formatJsonLightMetadata(value, data);
            } else if (key.indexOf(".") === -1) {
                // key is an regular property or array element.
                if (isLinks && key === "uri") {
                    formatJsonLightEntityLink(value, data);
                } else {
                    formatJsonLightProperty(key, value, pMetadata, data, isLinks);
                }
            } else {
                data[key] = value;
            }
        }
    };

    var formatJsonLightProperty = function (name, value, pMetadata, data) {
        /// <summary>Formats an object's value identified by name to its json light representation and saves it to data.</summary>
        /// <param name="name" type="String">Property name.</param>
        /// <param name="value">Property value.</param>
        /// <param name="pMetadata" type="Object">Object that contains metadata for the property that is being formatted.</param>
        /// <param name="data" type="Object">Object on which the formatted value is going to be stored.</param>

        // Get property type from property metadata
        var propertyMetadata = pMetadata && pMetadata[name] || { properties: undefined, type: undefined };
        var typeName = dataItemTypeName(value, propertyMetadata);

        if (isPrimitive(value) || !value) {
            // It is a primitive value then.
            formatJsonLightAnnotation(typeAnnotation, name, typeName, data);
            data[name] = value;
            return;
        }

        if (isFeed(value, typeName) || isEntry(value)) {
            formatJsonLightInlineProperty(name, value, data);
            return;
        }

        if (!typeName && isDeferred(value)) {
            // It is really a deferred property.
            formatJsonLightDeferredProperty(name, value, data);
            return;
        }

        if (isCollection(value, typeName)) {
            // The thing is a collection, format it as one.
            if (getCollectionType(typeName)) {
                formatJsonLightAnnotation(typeAnnotation, name, typeName, data);
            }
            formatJsonLightCollectionProperty(name, value, data);
            return;
        }

        djsassert(isComplex(value), "formatJsonLightProperty - Value is not a complex type value");

        // Format the complex property value in a new object in data[name].
        data[name] = {};
        formatJsonLightAnnotation(typeAnnotation, null, typeName, data[name]);
        formatJsonLightData(value, propertyMetadata.properties, data[name]);
    };

    var formatJsonLightEntityLink = function (value, data) {
        /// <summary>Formats an entity link in a $links document and saves it into data.</summary>
        /// <param name="value" type="String">Entity link value.</summary>
        /// <param name="data" type="Object">Object on which the formatted value is going to be stored.</param>
        data.url = value;
    };

    var formatJsonLightDeferredProperty = function (name, value, data) {
        /// <summary>Formats the object value's identified by name as an odata.navigalinkurl annotation and saves it to data.</summary>
        /// <param name="name" type="String">Name of the deferred property to be formatted.</param>
        /// <param name="value" type="Object">Deferred property value to be formatted.</param>
        /// <param name="data" type="Object">Object on which the formatted value is going to be stored.</param>

        formatJsonLightAnnotation(navUrlAnnotation, name, value.__deferred.uri, data);
    };

    var formatJsonLightCollectionProperty = function (name, value, data) {
        /// <summary>Formats a collection property in obj identified by name as a json light collection property and saves it to data.</summary>
        /// <param name="name" type="String">Name of the collection property to be formatted.</param>
        /// <param name="value" type="Object">Collection property value to be formatted.</param>
        /// <param name="data" type="Object">Object on which the formatted value is going to be stored.</param>

        data[name] = [];
        var items = isArray(value) ? value : value.results;
        formatJsonLightData(items, null, data[name]);
    };

    var formatJsonLightInlineProperty = function (name, value, data) {
        /// <summary>Formats an inline feed or entry property in obj identified by name as a json light value and saves it to data.</summary>
        /// <param name="name" type="String">Name of the inline feed or entry property to be formatted.</param>
        /// <param name="value" type="Object or Array">Value of the inline feed or entry property.</param>
        /// <param name="data" type="Object">Object on which the formatted value is going to be stored.</param>

        if (isFeed(value)) {
            data[name] = [];
            // Format each of the inline feed entries
            var entries = isArray(value) ? value : value.results;
            var i, len;
            for (i = 0, len = entries.length; i < len; i++) {
                formatJsonLightInlineEntry(name, entries[i], true, data);
            }
            return;
        }
        formatJsonLightInlineEntry(name, value, false, data);
    };

    var formatJsonLightInlineEntry = function (name, value, inFeed, data) {
        /// <summary>Formats an inline entry value in the property identified by name as a json light value and saves it to data.</summary>
        /// <param name="name" type="String">Name of the inline feed or entry property that owns the entry formatted.</param>
        /// <param name="value" type="Object">Inline entry value to be formatted.</param>
        /// <param name="inFeed" type="Boolean">True if the entry is in an inline feed; false otherwise.
        /// <param name="data" type="Object">Object on which the formatted value is going to be stored.</param>

        // This might be a bind instead of a deep insert.
        var uri = value.__metadata && value.__metadata.uri;
        if (uri) {
            formatJsonLightBinding(name, uri, inFeed, data);
            return;
        }

        var entry = formatJsonLight(value);
        if (inFeed) {
            data[name].push(entry);
            return;
        }
        data[name] = entry;
    };

    var formatJsonLightBinding = function (name, uri, inFeed, data) {
        /// <summary>Formats an entry binding in the inline property in obj identified by name as an odata.bind annotation and saves it to data.</summary>
        /// <param name="name" type="String">Name of the inline property that has the binding to be formated.</param>
        /// <param name="uri" type="String">Uri to the bound entry.</param>
        /// <param name="inFeed" type="Boolean">True if the binding is in an inline feed; false otherwise.
        /// <param name="data" type="Object">Object on which the formatted value is going to be stored.</param>

        var bindingName = name + bindAnnotation;
        if (inFeed) {
            // The binding is inside an inline feed, so merge it with whatever other bindings already exist in data.
            data[bindingName] = data[bindingName] || [];
            data[bindingName].push(uri);
            return;
        }
        // The binding is on an inline entry; it can be safely overwritten.
        data[bindingName] = uri;
    };

    var formatJsonLightAnnotation = function (qName, target, value, data) {
        /// <summary>Formats a value as a json light annotation and stores it in data</summary>
        /// <param name="qName" type="String">Qualified name of the annotation.</param>
        /// <param name="target" type="String">Name of the property that the metadata value targets.</param>
        /// <param name="value">Annotation value.</param>
        /// <param name="data" type="Object">Object on which the annotation is going to be stored.</param>

        if (value !== undefined) {
            if(target) {
                data[target + "@" + qName] = value;
            }
            else {
                data[qName] = value;
            }
        }
    };

    // DATAJS INTERNAL START
    odata.jsonLightReadPayload = jsonLightReadPayload;
    odata.formatJsonLight = formatJsonLight;
    // DATAJS INTERNAL END

    // CONTENT END
})(this);



