// Copyright (c) Microsoft.  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.

// datajs.js

(function (window, undefined) {

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

    // AMD support
    if (typeof define === 'function' && define.amd) {
        define('datajs', datajs);
        define('OData', odata);
    } else {
        window.datajs = datajs;
        window.OData = odata;
    }

    datajs.version = {
        major: 1,
        minor: 1,
        build: 1
    };


    var activeXObject = function (progId) {
        /// <summary>Creates a new ActiveXObject from the given progId.</summary>
        /// <param name="progId" type="String" mayBeNull="false" optional="false">
        ///    ProgId string of the desired ActiveXObject.
        /// </param>
        /// <remarks>
        ///    This function throws whatever exception might occur during the creation
        ///    of the ActiveXObject.
        /// </remarks>
        /// <returns type="Object">
        ///     The ActiveXObject instance. Null if ActiveX is not supported by the
        ///     browser.
        /// </returns>
        if (window.ActiveXObject) {
            return new window.ActiveXObject(progId);
        }
        return null;
    };

    var assigned = function (value) {
        /// <summary>Checks whether the specified value is different from null and undefined.</summary>
        /// <param name="value" mayBeNull="true" optional="true">Value to check.</param>
        /// <returns type="Boolean">true if the value is assigned; false otherwise.</returns>
        return value !== null && value !== undefined;
    };

    var contains = function (arr, item) {
        /// <summary>Checks whether the specified item is in the array.</summary>
        /// <param name="arr" type="Array" optional="false" mayBeNull="false">Array to check in.</param>
        /// <param name="item">Item to look for.</param>
        /// <returns type="Boolean">true if the item is contained, false otherwise.</returns>

        var i, len;
        for (i = 0, len = arr.length; i < len; i++) {
            if (arr[i] === item) {
                return true;
            }
        }

        return false;
    };

    var defined = function (a, b) {
        /// <summary>Given two values, picks the first one that is not undefined.</summary>
        /// <param name="a">First value.</param>
        /// <param name="b">Second value.</param>
        /// <returns>a if it's a defined value; else b.</returns>
        return (a !== undefined) ? a : b;
    };

    var delay = function (callback) {
        /// <summary>Delays the invocation of the specified function until execution unwinds.</summary>
        /// <param name="callback" type="Function">Callback function.</param>
        if (arguments.length === 1) {
            window.setTimeout(callback, 0);
            return;
        }

        var args = Array.prototype.slice.call(arguments, 1);
        window.setTimeout(function () {
            callback.apply(this, args);
        }, 0);
    };


    var extend = function (target, values) {
        /// <summary>Extends the target with the specified values.</summary>
        /// <param name="target" type="Object">Object to add properties to.</param>
        /// <param name="values" type="Object">Object with properties to add into target.</param>
        /// <returns type="Object">The target object.</returns>

        for (var name in values) {
            target[name] = values[name];
        }

        return target;
    };

    var find = function (arr, callback) {
        /// <summary>Returns the first item in the array that makes the callback function true.</summary>
        /// <param name="arr" type="Array" optional="false" mayBeNull="true">Array to check in.</param>
        /// <param name="callback" type="Function">Callback function to invoke once per item in the array.</param>
        /// <returns>The first item that makes the callback return true; null otherwise or if the array is null.</returns>

        if (arr) {
            var i, len;
            for (i = 0, len = arr.length; i < len; i++) {
                if (callback(arr[i])) {
                    return arr[i];
                }
            }
        }
        return null;
    };

    var isArray = function (value) {
        /// <summary>Checks whether the specified value is an array object.</summary>
        /// <param name="value">Value to check.</param>
        /// <returns type="Boolean">true if the value is an array object; false otherwise.</returns>

        return Object.prototype.toString.call(value) === "[object Array]";
    };

    var isDate = function (value) {
        /// <summary>Checks whether the specified value is a Date object.</summary>
        /// <param name="value">Value to check.</param>
        /// <returns type="Boolean">true if the value is a Date object; false otherwise.</returns>

        return Object.prototype.toString.call(value) === "[object Date]";
    };

    var isObject = function (value) {
        /// <summary>Tests whether a value is an object.</summary>
        /// <param name="value">Value to test.</param>
        /// <remarks>
        ///     Per javascript rules, null and array values are objects and will cause this function to return true.
        /// </remarks>
        /// <returns type="Boolean">True is the value is an object; false otherwise.</returns>

        return typeof value === "object";
    };

    var parseInt10 = function (value) {
        /// <summary>Parses a value in base 10.</summary>
        /// <param name="value" type="String">String value to parse.</param>
        /// <returns type="Number">The parsed value, NaN if not a valid value.</returns>

        return parseInt(value, 10);
    };

    var renameProperty = function (obj, oldName, newName) {
        /// <summary>Renames a property in an object.</summary>
        /// <param name="obj" type="Object">Object in which the property will be renamed.</param>
        /// <param name="oldName" type="String">Name of the property that will be renamed.</param>
        /// <param name="newName" type="String">New name of the property.</param>
        /// <remarks>
        ///    This function will not do anything if the object doesn't own a property with the specified old name.
        /// </remarks>

        if (obj.hasOwnProperty(oldName)) {
            obj[newName] = obj[oldName];
            delete obj[oldName];
        }
    };

    var throwErrorCallback = function (error) {
        /// <summary>Default error handler.</summary>
        /// <param name="error" type="Object">Error to handle.</param>
        throw error;
    };

    var trimString = function (str) {
        /// <summary>Removes leading and trailing whitespaces from a string.</summary>
        /// <param name="str" type="String" optional="false" mayBeNull="false">String to trim</param>
        /// <returns type="String">The string with no leading or trailing whitespace.</returns>

        if (str.trim) {
            return str.trim();
        }

        return str.replace(/^\s+|\s+$/g, '');
    };

    var undefinedDefault = function (value, defaultValue) {
        /// <summary>Returns a default value in place of undefined.</summary>
        /// <param name="value" mayBeNull="true" optional="true">Value to check.</param>
        /// <param name="defaultValue">Value to return if value is undefined.</param>
        /// <returns>value if it's defined; defaultValue otherwise.</returns>
        /// <remarks>
        /// This should only be used for cases where falsy values are valid;
        /// otherwise the pattern should be 'x = (value) ? value : defaultValue;'.
        /// </remarks>
        return (value !== undefined) ? value : defaultValue;
    };

    // Regular expression that splits a uri into its components:
    // 0 - is the matched string.
    // 1 - is the scheme.
    // 2 - is the authority.
    // 3 - is the path.
    // 4 - is the query.
    // 5 - is the fragment.
    var uriRegEx = /^([^:\/?#]+:)?(\/\/[^\/?#]*)?([^?#:]+)?(\?[^#]*)?(#.*)?/;
    var uriPartNames = ["scheme", "authority", "path", "query", "fragment"];

    var getURIInfo = function (uri) {
        /// <summary>Gets information about the components of the specified URI.</summary>
        /// <param name="uri" type="String">URI to get information from.</param>
        /// <returns type="Object">
        /// An object with an isAbsolute flag and part names (scheme, authority, etc.) if available.
        /// </returns>

        var result = { isAbsolute: false };

        if (uri) {
            var matches = uriRegEx.exec(uri);
            if (matches) {
                var i, len;
                for (i = 0, len = uriPartNames.length; i < len; i++) {
                    if (matches[i + 1]) {
                        result[uriPartNames[i]] = matches[i + 1];
                    }
                }
            }
            if (result.scheme) {
                result.isAbsolute = true;
            }
        }

        return result;
    };

    var getURIFromInfo = function (uriInfo) {
        /// <summary>Builds a URI string from its components.</summary>
        /// <param name="uriInfo" type="Object"> An object with uri parts (scheme, authority, etc.).</param>
        /// <returns type="String">URI string.</returns>

        return "".concat(
            uriInfo.scheme || "",
            uriInfo.authority || "",
            uriInfo.path || "",
            uriInfo.query || "",
            uriInfo.fragment || "");
    };

    // Regular expression that splits a uri authority into its subcomponents:
    // 0 - is the matched string.
    // 1 - is the userinfo subcomponent.
    // 2 - is the host subcomponent.
    // 3 - is the port component.
    var uriAuthorityRegEx = /^\/{0,2}(?:([^@]*)@)?([^:]+)(?::{1}(\d+))?/;

    // Regular expression that matches percentage enconded octects (i.e %20 or %3A);
    var pctEncodingRegEx = /%[0-9A-F]{2}/ig;

    var normalizeURICase = function (uri) {
        /// <summary>Normalizes the casing of a URI.</summary>
        /// <param name="uri" type="String">URI to normalize, absolute or relative.</param>
        /// <returns type="String">The URI normalized to lower case.</returns>

        var uriInfo = getURIInfo(uri);
        var scheme = uriInfo.scheme;
        var authority = uriInfo.authority;

        if (scheme) {
            uriInfo.scheme = scheme.toLowerCase();
            if (authority) {
                var matches = uriAuthorityRegEx.exec(authority);
                if (matches) {
                    uriInfo.authority = "//" +
                    (matches[1] ? matches[1] + "@" : "") +
                    (matches[2].toLowerCase()) +
                    (matches[3] ? ":" + matches[3] : "");
                }
            }
        }

        uri = getURIFromInfo(uriInfo);

        return uri.replace(pctEncodingRegEx, function (str) {
            return str.toLowerCase();
        });
    };

    var normalizeURI = function (uri, base) {
        /// <summary>Normalizes a possibly relative URI with a base URI.</summary>
        /// <param name="uri" type="String">URI to normalize, absolute or relative.</param>
        /// <param name="base" type="String" mayBeNull="true">Base URI to compose with.</param>
        /// <returns type="String">The composed URI if relative; the original one if absolute.</returns>

        if (!base) {
            return uri;
        }

        var uriInfo = getURIInfo(uri);
        if (uriInfo.isAbsolute) {
            return uri;
        }

        var baseInfo = getURIInfo(base);
        var normInfo = {};
        var path;

        if (uriInfo.authority) {
            normInfo.authority = uriInfo.authority;
            path = uriInfo.path;
            normInfo.query = uriInfo.query;
        } else {
            if (!uriInfo.path) {
                path = baseInfo.path;
                normInfo.query = uriInfo.query || baseInfo.query;
            } else {
                if (uriInfo.path.charAt(0) === '/') {
                    path = uriInfo.path;
                } else {
                    path = mergeUriPathWithBase(uriInfo.path, baseInfo.path);
                }
                normInfo.query = uriInfo.query;
            }
            normInfo.authority = baseInfo.authority;
        }

        normInfo.path = removeDotsFromPath(path);

        normInfo.scheme = baseInfo.scheme;
        normInfo.fragment = uriInfo.fragment;

        return getURIFromInfo(normInfo);
    };

    var mergeUriPathWithBase = function (uriPath, basePath) {
        /// <summary>Merges the path of a relative URI and a base URI.</summary>
        /// <param name="uriPath" type="String>Relative URI path.</param>
        /// <param name="basePath" type="String">Base URI path.</param>
        /// <returns type="String">A string with the merged path.</returns>

        var path = "/";
        var end;

        if (basePath) {
            end = basePath.lastIndexOf("/");
            path = basePath.substring(0, end);

            if (path.charAt(path.length - 1) !== "/") {
                path = path + "/";
            }
        }

        return path + uriPath;
    };

    var removeDotsFromPath = function (path) {
        /// <summary>Removes the special folders . and .. from a URI's path.</summary>
        /// <param name="path" type="string">URI path component.</param>
        /// <returns type="String">Path without any . and .. folders.</returns>

        var result = "";
        var segment = "";
        var end;

        while (path) {
            if (path.indexOf("..") === 0 || path.indexOf(".") === 0) {
                path = path.replace(/^\.\.?\/?/g, "");
            } else if (path.indexOf("/..") === 0) {
                path = path.replace(/^\/\..\/?/g, "/");
                end = result.lastIndexOf("/");
                if (end === -1) {
                    result = "";
                } else {
                    result = result.substring(0, end);
                }
            } else if (path.indexOf("/.") === 0) {
                path = path.replace(/^\/\.\/?/g, "/");
            } else {
                segment = path;
                end = path.indexOf("/", 1);
                if (end !== -1) {
                    segment = path.substring(0, end);
                }
                result = result + segment;
                path = path.replace(segment, "");
            }
        }
        return result;
    };

    var convertByteArrayToHexString = function (str) {
        var arr = [];
        if (window.atob === undefined) {
            arr = decodeBase64(str);
        } else {
            var binaryStr = window.atob(str);
            for (var i = 0; i < binaryStr.length; i++) {
                arr.push(binaryStr.charCodeAt(i));
            }
        }
        var hexValue = "";
        var hexValues = "0123456789ABCDEF";
        for (var j = 0; j < arr.length; j++) {
            var t = arr[j];
            hexValue += hexValues[t >> 4];
            hexValue += hexValues[t & 0x0F];
        }
        return hexValue;
    };

    var decodeBase64 = function (str) {
        var binaryString = "";
        for (var i = 0; i < str.length; i++) {
            var base65IndexValue = getBase64IndexValue(str[i]);
            var binaryValue = "";
            if (base65IndexValue !== null) {
                binaryValue = base65IndexValue.toString(2);
                binaryString += addBase64Padding(binaryValue);
            }
        }
        var byteArray = [];
        var numberOfBytes = parseInt(binaryString.length / 8, 10);
        for (i = 0; i < numberOfBytes; i++) {
            var intValue = parseInt(binaryString.substring(i * 8, (i + 1) * 8), 2);
            byteArray.push(intValue);
        }
        return byteArray;
    };

    var getBase64IndexValue = function (character) {
        var asciiCode = character.charCodeAt(0);
        var asciiOfA = 65;
        var differenceBetweenZanda = 6;
        if (asciiCode >= 65 && asciiCode <= 90) {           // between "A" and "Z" inclusive
            return asciiCode - asciiOfA;
        } else if (asciiCode >= 97 && asciiCode <= 122) {   // between 'a' and 'z' inclusive
            return asciiCode - asciiOfA - differenceBetweenZanda;
        } else if (asciiCode >= 48 && asciiCode <= 57) {    // between '0' and '9' inclusive
            return asciiCode + 4;
        } else if (character == "+") {
            return 62;
        } else if (character == "/") {
            return 63;
        } else {
            return null;
        }
    };

    var addBase64Padding = function (binaryString) {
        while (binaryString.length < 6) {
            binaryString = "0" + binaryString;
        }
        return binaryString;
    };

    var getJsonValueArraryLength = function (data) {
        if (data && data.value) {
            return data.value.length;
        }

        return 0;
    };

    var sliceJsonValueArray = function (data, start, end) {
        if (data == undefined || data.value == undefined) {
            return data;
        }

        if (start < 0) {
            start = 0;
        }

        var length = getJsonValueArraryLength(data);
        if (length < end) {
            end = length;
        }

        var newdata = {};
        for (var property in data) {
            if (property == "value") {
                newdata[property] = data[property].slice(start, end);
            } else {
                newdata[property] = data[property];
            }
        }

        return newdata;
    };

    var concatJsonValueArray = function (data, concatData) {
        if (concatData == undefined || concatData.value == undefined) {
            return data;
        }

        if (data == undefined || Object.keys(data).length == 0) {
            return concatData;
        }

        if (data.value == undefined) {
            data.value = concatData.value;
            return data;
        }

        data.value = data.value.concat(concatData.value);

        return data;
    };



    // URI prefixes to generate smaller code.
    var http = "http://";
    var w3org = http + "www.w3.org/";               // http://www.w3.org/

    var xhtmlNS = w3org + "1999/xhtml";             // http://www.w3.org/1999/xhtml
    var xmlnsNS = w3org + "2000/xmlns/";            // http://www.w3.org/2000/xmlns/
    var xmlNS = w3org + "XML/1998/namespace";       // http://www.w3.org/XML/1998/namespace

    var mozillaParserErroNS = http + "www.mozilla.org/newlayout/xml/parsererror.xml";

    var hasLeadingOrTrailingWhitespace = function (text) {
        /// <summary>Checks whether the specified string has leading or trailing spaces.</summary>
        /// <param name="text" type="String">String to check.</param>
        /// <returns type="Boolean">true if text has any leading or trailing whitespace; false otherwise.</returns>

        var re = /(^\s)|(\s$)/;
        return re.test(text);
    };

    var isWhitespace = function (text) {
        /// <summary>Determines whether the specified text is empty or whitespace.</summary>
        /// <param name="text" type="String">Value to inspect.</param>
        /// <returns type="Boolean">true if the text value is empty or all whitespace; false otherwise.</returns>

        var ws = /^\s*$/;
        return text === null || ws.test(text);
    };

    var isWhitespacePreserveContext = function (domElement) {
        /// <summary>Determines whether the specified element has xml:space='preserve' applied.</summary>
        /// <param name="domElement">Element to inspect.</param>
        /// <returns type="Boolean">Whether xml:space='preserve' is in effect.</returns>

        while (domElement !== null && domElement.nodeType === 1) {
            var val = xmlAttributeValue(domElement, "space", xmlNS);
            if (val === "preserve") {
                return true;
            } else if (val === "default") {
                break;
            } else {
                domElement = domElement.parentNode;
            }
        }

        return false;
    };

    var isXmlNSDeclaration = function (domAttribute) {
        /// <summary>Determines whether the attribute is a XML namespace declaration.</summary>
        /// <param name="domAttribute">Element to inspect.</param>
        /// <returns type="Boolean">
        ///    True if the attribute is a namespace declaration (its name is 'xmlns' or starts with 'xmlns:'; false otherwise.
        /// </returns>

        var nodeName = domAttribute.nodeName;
        return nodeName == "xmlns" || nodeName.indexOf("xmlns:") === 0;
    };

    var safeSetProperty = function (obj, name, value) {
        /// <summary>Safely set as property in an object by invoking obj.setProperty.</summary>
        /// <param name="obj">Object that exposes a setProperty method.</param>
        /// <param name="name" type="String" mayBeNull="false">Property name.</param>
        /// <param name="value">Property value.</param>

        try {
            obj.setProperty(name, value);
        } catch (_) { }
    };

    var msXmlDom3 = function () {
        /// <summary>Creates an configures new MSXML 3.0 ActiveX object.</summary>
        /// <remakrs>
        ///    This function throws any exception that occurs during the creation
        ///    of the MSXML 3.0 ActiveX object.
        /// <returns type="Object">New MSXML 3.0 ActiveX object.</returns>

        var msxml3 = activeXObject("Msxml2.DOMDocument.3.0");
        if (msxml3) {
            safeSetProperty(msxml3, "ProhibitDTD", true);
            safeSetProperty(msxml3, "MaxElementDepth", 256);
            safeSetProperty(msxml3, "AllowDocumentFunction", false);
            safeSetProperty(msxml3, "AllowXsltScript", false);
        }
        return msxml3;
    };

    var msXmlDom = function () {
        /// <summary>Creates an configures new MSXML 6.0 or MSXML 3.0 ActiveX object.</summary>
        /// <remakrs>
        ///    This function will try to create a new MSXML 6.0 ActiveX object. If it fails then
        ///    it will fallback to create a new MSXML 3.0 ActiveX object. Any exception that
        ///    happens during the creation of the MSXML 6.0 will be handled by the function while
        ///    the ones that happend during the creation of the MSXML 3.0 will be thrown.
        /// <returns type="Object">New MSXML 3.0 ActiveX object.</returns>

        try {
            var msxml = activeXObject("Msxml2.DOMDocument.6.0");
            if (msxml) {
                msxml.async = true;
            }
            return msxml;
        } catch (_) {
            return msXmlDom3();
        }
    };

    var msXmlParse = function (text) {
        /// <summary>Parses an XML string using the MSXML DOM.</summary>
        /// <remakrs>
        ///    This function throws any exception that occurs during the creation
        ///    of the MSXML ActiveX object.  It also will throw an exception
        ///    in case of a parsing error.
        /// <returns type="Object">New MSXML DOMDocument node representing the parsed XML string.</returns>

        var dom = msXmlDom();
        if (!dom) {
            return null;
        }

        dom.loadXML(text);
        var parseError = dom.parseError;
        if (parseError.errorCode !== 0) {
            xmlThrowParserError(parseError.reason, parseError.srcText, text);
        }
        return dom;
    };

    var xmlThrowParserError = function (exceptionOrReason, srcText, errorXmlText) {
        /// <summary>Throws a new exception containing XML parsing error information.</summary>
        /// <param name="exceptionOrReason">
        ///    String indicatin the reason of the parsing failure or
        ///    Object detailing the parsing error.
        /// </param>
        /// <param name="srcText" type="String">
        ///    String indicating the part of the XML string that caused the parsing error.
        /// </param>
        /// <param name="errorXmlText" type="String">XML string for wich the parsing failed.</param>

        if (typeof exceptionOrReason === "string") {
            exceptionOrReason = { message: exceptionOrReason };
        }
        throw extend(exceptionOrReason, { srcText: srcText || "", errorXmlText: errorXmlText || "" });
    };

    var xmlParse = function (text) {
        /// <summary>Returns an XML DOM document from the specified text.</summary>
        /// <param name="text" type="String">Document text.</param>
        /// <returns>XML DOM document.</returns>
        /// <remarks>This function will throw an exception in case of a parse error.</remarks>

        var domParser = window.DOMParser && new window.DOMParser();
        var dom;

        if (!domParser) {
            dom = msXmlParse(text);
            if (!dom) {
                xmlThrowParserError("XML DOM parser not supported");
            }
            return dom;
        }

        try {
            dom = domParser.parseFromString(text, "text/xml");
        } catch (e) {
            xmlThrowParserError(e, "", text);
        }

        var element = dom.documentElement;
        var nsURI = element.namespaceURI;
        var localName = xmlLocalName(element);

        // Firefox reports errors by returing the DOM for an xml document describing the problem.
        if (localName === "parsererror" && nsURI === mozillaParserErroNS) {
            var srcTextElement = xmlFirstChildElement(element, mozillaParserErroNS, "sourcetext");
            var srcText = srcTextElement ? xmlNodeValue(srcTextElement) : "";
            xmlThrowParserError(xmlInnerText(element) || "", srcText, text);
        }

        // Chrome (and maybe other webkit based browsers) report errors by injecting a header with an error message.
        // The error may be localized, so instead we simply check for a header as the
        // top element or descendant child of the document.
        if (localName === "h3" && nsURI === xhtmlNS || xmlFirstDescendantElement(element, xhtmlNS, "h3")) {
            var reason = "";
            var siblings = [];
            var cursor = element.firstChild;
            while (cursor) {
                if (cursor.nodeType === 1) {
                    reason += xmlInnerText(cursor) || "";
                }
                siblings.push(cursor.nextSibling);
                cursor = cursor.firstChild || siblings.shift();
            }
            reason += xmlInnerText(element) || "";
            xmlThrowParserError(reason, "", text);
        }

        return dom;
    };

    var xmlQualifiedName = function (prefix, name) {
        /// <summary>Builds a XML qualified name string in the form of "prefix:name".</summary>
        /// <param name="prefix" type="String" maybeNull="true">Prefix string.</param>
        /// <param name="name" type="String">Name string to qualify with the prefix.</param>
        /// <returns type="String">Qualified name.</returns>

        return prefix ? prefix + ":" + name : name;
    };

    var xmlAppendText = function (domNode, textNode) {
        /// <summary>Appends a text node into the specified DOM element node.</summary>
        /// <param name="domNode">DOM node for the element.</param>
        /// <param name="text" type="String" mayBeNull="false">Text to append as a child of element.</param>
        if (hasLeadingOrTrailingWhitespace(textNode.data)) {
            var attr = xmlAttributeNode(domNode, xmlNS, "space");
            if (!attr) {
                attr = xmlNewAttribute(domNode.ownerDocument, xmlNS, xmlQualifiedName("xml", "space"));
                xmlAppendChild(domNode, attr);
            }
            attr.value = "preserve";
        }
        domNode.appendChild(textNode);
        return domNode;
    };

    var xmlAttributes = function (element, onAttributeCallback) {
        /// <summary>Iterates through the XML element's attributes and invokes the callback function for each one.</summary>
        /// <param name="element">Wrapped element to iterate over.</param>
        /// <param name="onAttributeCallback" type="Function">Callback function to invoke with wrapped attribute nodes.</param>

        var attributes = element.attributes;
        var i, len;
        for (i = 0, len = attributes.length; i < len; i++) {
            onAttributeCallback(attributes.item(i));
        }
    };

    var xmlAttributeValue = function (domNode, localName, nsURI) {
        /// <summary>Returns the value of a DOM element's attribute.</summary>
        /// <param name="domNode">DOM node for the owning element.</param>
        /// <param name="localName" type="String">Local name of the attribute.</param>
        /// <param name="nsURI" type="String">Namespace URI of the attribute.</param>
        /// <returns type="String" maybeNull="true">The attribute value, null if not found.</returns>

        var attribute = xmlAttributeNode(domNode, localName, nsURI);
        return attribute ? xmlNodeValue(attribute) : null;
    };

    var xmlAttributeNode = function (domNode, localName, nsURI) {
        /// <summary>Gets an attribute node from a DOM element.</summary>
        /// <param name="domNode">DOM node for the owning element.</param>
        /// <param name="localName" type="String">Local name of the attribute.</param>
        /// <param name="nsURI" type="String">Namespace URI of the attribute.</param>
        /// <returns>The attribute node, null if not found.</returns>

        var attributes = domNode.attributes;
        if (attributes.getNamedItemNS) {
            return attributes.getNamedItemNS(nsURI || null, localName);
        }

        return attributes.getQualifiedItem(localName, nsURI) || null;
    };

    var xmlBaseURI = function (domNode, baseURI) {
        /// <summary>Gets the value of the xml:base attribute on the specified element.</summary>
        /// <param name="domNode">Element to get xml:base attribute value from.</param>
        /// <param name="baseURI" mayBeNull="true" optional="true">Base URI used to normalize the value of the xml:base attribute.</param>
        /// <returns type="String">Value of the xml:base attribute if found; the baseURI or null otherwise.</returns>

        var base = xmlAttributeNode(domNode, "base", xmlNS);
        return (base ? normalizeURI(base.value, baseURI) : baseURI) || null;
    };


    var xmlChildElements = function (domNode, onElementCallback) {
        /// <summary>Iterates through the XML element's child DOM elements and invokes the callback function for each one.</summary>
        /// <param name="element">DOM Node containing the DOM elements to iterate over.</param>
        /// <param name="onElementCallback" type="Function">Callback function to invoke for each child DOM element.</param>

        xmlTraverse(domNode, /*recursive*/false, function (child) {
            if (child.nodeType === 1) {
                onElementCallback(child);
            }
            // continue traversing.
            return true;
        });
    };

    var xmlFindElementByPath = function (root, namespaceURI, path) {
        /// <summary>Gets the descendant element under root that corresponds to the specified path and namespace URI.</summary>
        /// <param name="root">DOM element node from which to get the descendant element.</param>
        /// <param name="namespaceURI" type="String">The namespace URI of the element to match.</param>
        /// <param name="path" type="String">Path to the desired descendant element.</param>
        /// <returns>The element specified by path and namespace URI.</returns>
        /// <remarks>
        ///     All the elements in the path are matched against namespaceURI.
        ///     The function will stop searching on the first element that doesn't match the namespace and the path.
        /// </remarks>

        var parts = path.split("/");
        var i, len;
        for (i = 0, len = parts.length; i < len; i++) {
            root = root && xmlFirstChildElement(root, namespaceURI, parts[i]);
        }
        return root || null;
    };

    var xmlFindNodeByPath = function (root, namespaceURI, path) {
        /// <summary>Gets the DOM element or DOM attribute node under root that corresponds to the specified path and namespace URI.</summary>
        /// <param name="root">DOM element node from which to get the descendant node.</param>
        /// <param name="namespaceURI" type="String">The namespace URI of the node to match.</param>
        /// <param name="path" type="String">Path to the desired descendant node.</param>
        /// <returns>The node specified by path and namespace URI.</returns>
        /// <remarks>
        ///     This function will traverse the path and match each node associated to a path segement against the namespace URI.
        ///     The traversal stops when the whole path has been exahusted or a node that doesn't belogong the specified namespace is encountered.
        ///
        ///     The last segment of the path may be decorated with a starting @ character to indicate that the desired node is a DOM attribute.
        /// </remarks>

        var lastSegmentStart = path.lastIndexOf("/");
        var nodePath = path.substring(lastSegmentStart + 1);
        var parentPath = path.substring(0, lastSegmentStart);

        var node = parentPath ? xmlFindElementByPath(root, namespaceURI, parentPath) : root;
        if (node) {
            if (nodePath.charAt(0) === "@") {
                return xmlAttributeNode(node, nodePath.substring(1), namespaceURI);
            }
            return xmlFirstChildElement(node, namespaceURI, nodePath);
        }
        return null;
    };

    var xmlFirstChildElement = function (domNode, namespaceURI, localName) {
        /// <summary>Returns the first child DOM element under the specified DOM node that matches the specified namespace URI and local name.</summary>
        /// <param name="domNode">DOM node from which the child DOM element is going to be retrieved.</param>
        /// <param name="namespaceURI" type="String" optional="true">The namespace URI of the element to match.</param>
        /// <param name="localName" type="String" optional="true">Name of the element to match.</param>
        /// <returns>The node's first child DOM element that matches the specified namespace URI and local name; null otherwise.</returns>

        return xmlFirstElementMaybeRecursive(domNode, namespaceURI, localName, /*recursive*/false);
    };

    var xmlFirstDescendantElement = function (domNode, namespaceURI, localName) {
        /// <summary>Returns the first descendant DOM element under the specified DOM node that matches the specified namespace URI and local name.</summary>
        /// <param name="domNode">DOM node from which the descendant DOM element is going to be retrieved.</param>
        /// <param name="namespaceURI" type="String" optional="true">The namespace URI of the element to match.</param>
        /// <param name="localName" type="String" optional="true">Name of the element to match.</param>
        /// <returns>The node's first descendant DOM element that matches the specified namespace URI and local name; null otherwise.</returns>

        if (domNode.getElementsByTagNameNS) {
            var result = domNode.getElementsByTagNameNS(namespaceURI, localName);
            return result.length > 0 ? result[0] : null;
        }
        return xmlFirstElementMaybeRecursive(domNode, namespaceURI, localName, /*recursive*/true);
    };

    var xmlFirstElementMaybeRecursive = function (domNode, namespaceURI, localName, recursive) {
        /// <summary>Returns the first descendant DOM element under the specified DOM node that matches the specified namespace URI and local name.</summary>
        /// <param name="domNode">DOM node from which the descendant DOM element is going to be retrieved.</param>
        /// <param name="namespaceURI" type="String" optional="true">The namespace URI of the element to match.</param>
        /// <param name="localName" type="String" optional="true">Name of the element to match.</param>
        /// <param name="recursive" type="Boolean">
        ///     True if the search should include all the descendants of the DOM node.
        ///     False if the search should be scoped only to the direct children of the DOM node.
        /// </param>
        /// <returns>The node's first descendant DOM element that matches the specified namespace URI and local name; null otherwise.</returns>

        var firstElement = null;
        xmlTraverse(domNode, recursive, function (child) {
            if (child.nodeType === 1) {
                var isExpectedNamespace = !namespaceURI || xmlNamespaceURI(child) === namespaceURI;
                var isExpectedNodeName = !localName || xmlLocalName(child) === localName;

                if (isExpectedNamespace && isExpectedNodeName) {
                    firstElement = child;
                }
            }
            return firstElement === null;
        });
        return firstElement;
    };

    var xmlInnerText = function (xmlElement) {
        /// <summary>Gets the concatenated value of all immediate child text and CDATA nodes for the specified element.</summary>
        /// <param name="domElement">Element to get values for.</param>
        /// <returns type="String">Text for all direct children.</returns>

        var result = null;
        var root = (xmlElement.nodeType === 9 && xmlElement.documentElement) ? xmlElement.documentElement : xmlElement;
        var whitespaceAlreadyRemoved = root.ownerDocument.preserveWhiteSpace === false;
        var whitespacePreserveContext;

        xmlTraverse(root, false, function (child) {
            if (child.nodeType === 3 || child.nodeType === 4) {
                // isElementContentWhitespace indicates that this is 'ignorable whitespace',
                // but it's not defined by all browsers, and does not honor xml:space='preserve'
                // in some implementations.
                //
                // If we can't tell either way, we walk up the tree to figure out whether
                // xml:space is set to preserve; otherwise we discard pure-whitespace.
                //
                // For example <a>  <b>1</b></a>. The space between <a> and <b> is usually 'ignorable'.
                var text = xmlNodeValue(child);
                var shouldInclude = whitespaceAlreadyRemoved || !isWhitespace(text);
                if (!shouldInclude) {
                    // Walk up the tree to figure out whether we are in xml:space='preserve' context
                    // for the cursor (needs to happen only once).
                    if (whitespacePreserveContext === undefined) {
                        whitespacePreserveContext = isWhitespacePreserveContext(root);
                    }

                    shouldInclude = whitespacePreserveContext;
                }

                if (shouldInclude) {
                    if (!result) {
                        result = text;
                    } else {
                        result += text;
                    }
                }
            }
            // Continue traversing?
            return true;
        });
        return result;
    };

    var xmlLocalName = function (domNode) {
        /// <summary>Returns the localName of a XML node.</summary>
        /// <param name="domNode">DOM node to get the value from.</param>
        /// <returns type="String">localName of domNode.</returns>

        return domNode.localName || domNode.baseName;
    };

    var xmlNamespaceURI = function (domNode) {
        /// <summary>Returns the namespace URI of a XML node.</summary>
        /// <param name="node">DOM node to get the value from.</param>
        /// <returns type="String">Namespace URI of domNode.</returns>

        return domNode.namespaceURI || null;
    };

    var xmlNodeValue = function (domNode) {
        /// <summary>Returns the value or the inner text of a XML node.</summary>
        /// <param name="node">DOM node to get the value from.</param>
        /// <returns>Value of the domNode or the inner text if domNode represents a DOM element node.</returns>
        
        if (domNode.nodeType === 1) {
            return xmlInnerText(domNode);
        }
        return domNode.nodeValue;
    };

    var xmlTraverse = function (domNode, recursive, onChildCallback) {
        /// <summary>Walks through the descendants of the domNode and invokes a callback for each node.</summary>
        /// <param name="domNode">DOM node whose descendants are going to be traversed.</param>
        /// <param name="recursive" type="Boolean">
        ///    True if the traversal should include all the descenants of the DOM node.
        ///    False if the traversal should be scoped only to the direct children of the DOM node.
        /// </param>
        /// <returns type="String">Namespace URI of node.</returns>

        var subtrees = [];
        var child = domNode.firstChild;
        var proceed = true;
        while (child && proceed) {
            proceed = onChildCallback(child);
            if (proceed) {
                if (recursive && child.firstChild) {
                    subtrees.push(child.firstChild);
                }
                child = child.nextSibling || subtrees.shift();
            }
        }
    };

    var xmlSiblingElement = function (domNode, namespaceURI, localName) {
        /// <summary>Returns the next sibling DOM element of the specified DOM node.</summary>
        /// <param name="domNode">DOM node from which the next sibling is going to be retrieved.</param>
        /// <param name="namespaceURI" type="String" optional="true">The namespace URI of the element to match.</param>
        /// <param name="localName" type="String" optional="true">Name of the element to match.</param>
        /// <returns>The node's next sibling DOM element, null if there is none.</returns>

        var sibling = domNode.nextSibling;
        while (sibling) {
            if (sibling.nodeType === 1) {
                var isExpectedNamespace = !namespaceURI || xmlNamespaceURI(sibling) === namespaceURI;
                var isExpectedNodeName = !localName || xmlLocalName(sibling) === localName;

                if (isExpectedNamespace && isExpectedNodeName) {
                    return sibling;
                }
            }
            sibling = sibling.nextSibling;
        }
        return null;
    };

    var xmlDom = function () {
        /// <summary>Creates a new empty DOM document node.</summary>
        /// <returns>New DOM document node.</returns>
        /// <remarks>
        ///    This function will first try to create a native DOM document using
        ///    the browsers createDocument function.  If the browser doesn't
        ///    support this but supports ActiveXObject, then an attempt to create
        ///    an MSXML 6.0 DOM will be made. If this attempt fails too, then an attempt
        ///    for creating an MXSML 3.0 DOM will be made.  If this last attemp fails or
        ///    the browser doesn't support ActiveXObject then an exception will be thrown.
        /// </remarks>

        var implementation = window.document.implementation;
        return (implementation && implementation.createDocument) ?
           implementation.createDocument(null, null, null) :
           msXmlDom();
    };

    var xmlAppendChildren = function (parent, children) {
        /// <summary>Appends a collection of child nodes or string values to a parent DOM node.</summary>
        /// <param name="parent">DOM node to which the children will be appended.</param>
        /// <param name="children" type="Array">Array containing DOM nodes or string values that will be appended to the parent.</param>
        /// <returns>The parent with the appended children or string values.</returns>
        /// <remarks>
        ///    If a value in the children collection is a string, then a new DOM text node is going to be created
        ///    for it and then appended to the parent.
        /// </remarks>

        if (!isArray(children)) {
            return xmlAppendChild(parent, children);
        }

        var i, len;
        for (i = 0, len = children.length; i < len; i++) {
            children[i] && xmlAppendChild(parent, children[i]);
        }
        return parent;
    };

    var xmlAppendChild = function (parent, child) {
        /// <summary>Appends a child node or a string value to a parent DOM node.</summary>
        /// <param name="parent">DOM node to which the child will be appended.</param>
        /// <param name="child">Child DOM node or string value to append to the parent.</param>
        /// <returns>The parent with the appended child or string value.</returns>
        /// <remarks>
        ///    If child is a string value, then a new DOM text node is going to be created
        ///    for it and then appended to the parent.
        /// </remarks>

        if (child) {
            if (typeof child === "string") {
                return xmlAppendText(parent, xmlNewText(parent.ownerDocument, child));
            }
            if (child.nodeType === 2) {
                parent.setAttributeNodeNS ? parent.setAttributeNodeNS(child) : parent.setAttributeNode(child);
            } else {
                parent.appendChild(child);
            }
        }
        return parent;
    };

    var xmlNewAttribute = function (dom, namespaceURI, qualifiedName, value) {
        /// <summary>Creates a new DOM attribute node.</summary>
        /// <param name="dom">DOM document used to create the attribute.</param>
        /// <param name="prefix" type="String">Namespace prefix.</param>
        /// <param name="namespaceURI" type="String">Namespace URI.</param>
        /// <returns>DOM attribute node for the namespace declaration.</returns>

        var attribute =
            dom.createAttributeNS && dom.createAttributeNS(namespaceURI, qualifiedName) ||
            dom.createNode(2, qualifiedName, namespaceURI || undefined);

        attribute.value = value || "";
        return attribute;
    };

    var xmlNewElement = function (dom, nampespaceURI, qualifiedName, children) {
        /// <summary>Creates a new DOM element node.</summary>
        /// <param name="dom">DOM document used to create the DOM element.</param>
        /// <param name="namespaceURI" type="String">Namespace URI of the new DOM element.</param>
        /// <param name="qualifiedName" type="String">Qualified name in the form of "prefix:name" of the new DOM element.</param>
        /// <param name="children" type="Array" optional="true">
        ///     Collection of child DOM nodes or string values that are going to be appended to the new DOM element.
        /// </param>
        /// <returns>New DOM element.</returns>
        /// <remarks>
        ///    If a value in the children collection is a string, then a new DOM text node is going to be created
        ///    for it and then appended to the new DOM element.
        /// </remarks>

        var element =
            dom.createElementNS && dom.createElementNS(nampespaceURI, qualifiedName) ||
            dom.createNode(1, qualifiedName, nampespaceURI || undefined);

        return xmlAppendChildren(element, children || []);
    };

    var xmlNewNSDeclaration = function (dom, namespaceURI, prefix) {
        /// <summary>Creates a namespace declaration attribute.</summary>
        /// <param name="dom">DOM document used to create the attribute.</param>
        /// <param name="namespaceURI" type="String">Namespace URI.</param>
        /// <param name="prefix" type="String">Namespace prefix.</param>
        /// <returns>DOM attribute node for the namespace declaration.</returns>

        return xmlNewAttribute(dom, xmlnsNS, xmlQualifiedName("xmlns", prefix), namespaceURI);
    };

    var xmlNewFragment = function (dom, text) {
        /// <summary>Creates a new DOM document fragment node for the specified xml text.</summary>
        /// <param name="dom">DOM document from which the fragment node is going to be created.</param>
        /// <param name="text" type="String" mayBeNull="false">XML text to be represented by the XmlFragment.</param>
        /// <returns>New DOM document fragment object.</returns>

        var value = "<c>" + text + "</c>";
        var tempDom = xmlParse(value);
        var tempRoot = tempDom.documentElement;
        var imported = ("importNode" in dom) ? dom.importNode(tempRoot, true) : tempRoot;
        var fragment = dom.createDocumentFragment();

        var importedChild = imported.firstChild;
        while (importedChild) {
            fragment.appendChild(importedChild);
            importedChild = importedChild.nextSibling;
        }
        return fragment;
    };

    var xmlNewText = function (dom, text) {
        /// <summary>Creates new DOM text node.</summary>
        /// <param name="dom">DOM document used to create the text node.</param>
        /// <param name="text" type="String">Text value for the DOM text node.</param>
        /// <returns>DOM text node.</returns>

        return dom.createTextNode(text);
    };

    var xmlNewNodeByPath = function (dom, root, namespaceURI, prefix, path) {
        /// <summary>Creates a new DOM element or DOM attribute node as specified by path and appends it to the DOM tree pointed by root.</summary>
        /// <param name="dom">DOM document used to create the new node.</param>
        /// <param name="root">DOM element node used as root of the subtree on which the new nodes are going to be created.</param>
        /// <param name="namespaceURI" type="String">Namespace URI of the new DOM element or attribute.</param>
        /// <param name="namespacePrefix" type="String">Prefix used to qualify the name of the new DOM element or attribute.</param>
        /// <param name="Path" type="String">Path string describing the location of the new DOM element or attribute from the root element.</param>
        /// <returns>DOM element or attribute node for the last segment of the path.</returns>
        /// <remarks>
        ///     This function will traverse the path and will create a new DOM element with the specified namespace URI and prefix
        ///     for each segment that doesn't have a matching element under root.
        ///
        ///     The last segment of the path may be decorated with a starting @ character. In this case a new DOM attribute node
        ///     will be created.
        /// </remarks>

        var name = "";
        var parts = path.split("/");
        var xmlFindNode = xmlFirstChildElement;
        var xmlNewNode = xmlNewElement;
        var xmlNode = root;

        var i, len;
        for (i = 0, len = parts.length; i < len; i++) {
            name = parts[i];
            if (name.charAt(0) === "@") {
                name = name.substring(1);
                xmlFindNode = xmlAttributeNode;
                xmlNewNode = xmlNewAttribute;
            }

            var childNode = xmlFindNode(xmlNode, namespaceURI, name);
            if (!childNode) {
                childNode = xmlNewNode(dom, namespaceURI, xmlQualifiedName(prefix, name));
                xmlAppendChild(xmlNode, childNode);
            }
            xmlNode = childNode;
        }
        return xmlNode;
    };

    var xmlSerialize = function (domNode) {
        /// <summary>
        /// Returns the text representation of the document to which the specified node belongs.
        /// </summary>
        /// <param name="root">Wrapped element in the document to serialize.</param>
        /// <returns type="String">Serialized document.</returns>

        var xmlSerializer = window.XMLSerializer;
        if (xmlSerializer) {
            var serializer = new xmlSerializer();
            return serializer.serializeToString(domNode);
        }

        if (domNode.xml) {
            return domNode.xml;
        }

        throw { message: "XML serialization unsupported" };
    };

    var xmlSerializeDescendants = function (domNode) {
        /// <summary>Returns the XML representation of the all the descendants of the node.</summary>
        /// <param name="domNode" optional="false" mayBeNull="false">Node to serialize.</param>
        /// <returns type="String">The XML representation of all the descendants of the node.</returns>

        var children = domNode.childNodes;
        var i, len = children.length;
        if (len === 0) {
            return "";
        }

        // Some implementations of the XMLSerializer don't deal very well with fragments that
        // don't have a DOMElement as their first child. The work around is to wrap all the
        // nodes in a dummy root node named "c", serialize it and then just extract the text between
        // the <c> and the </c> substrings.

        var dom = domNode.ownerDocument;
        var fragment = dom.createDocumentFragment();
        var fragmentRoot = dom.createElement("c");

        fragment.appendChild(fragmentRoot);
        // Move the children to the fragment tree.
        for (i = 0; i < len; i++) {
            fragmentRoot.appendChild(children[i]);
        }

        var xml = xmlSerialize(fragment);
        xml = xml.substr(3, xml.length - 7);

        // Move the children back to the original dom tree.
        for (i = 0; i < len; i++) {
            domNode.appendChild(fragmentRoot.childNodes[i]);
        }

        return xml;
    };

    var xmlSerializeNode = function (domNode) {
        /// <summary>Returns the XML representation of the node and all its descendants.</summary>
        /// <param name="domNode" optional="false" mayBeNull="false">Node to serialize.</param>
        /// <returns type="String">The XML representation of the node and all its descendants.</returns>

        var xml = domNode.xml;
        if (xml !== undefined) {
            return xml;
        }

        if (window.XMLSerializer) {
            var serializer = new window.XMLSerializer();
            return serializer.serializeToString(domNode);
        }

        throw { message: "XML serialization unsupported" };
    };




    var forwardCall = function (thisValue, name, returnValue) {
        /// <summary>Creates a new function to forward a call.</summary>
        /// <param name="thisValue" type="Object">Value to use as the 'this' object.</param>
        /// <param name="name" type="String">Name of function to forward to.</param>
        /// <param name="returnValue" type="Object">Return value for the forward call (helps keep identity when chaining calls).</param>
        /// <returns type="Function">A new function that will forward a call.</returns>

        return function () {
            thisValue[name].apply(thisValue, arguments);
            return returnValue;
        };
    };

    var DjsDeferred = function () {
        /// <summary>Initializes a new DjsDeferred object.</summary>
        /// <remarks>
        /// Compability Note A - Ordering of callbacks through chained 'then' invocations
        ///
        /// The Wiki entry at http://wiki.commonjs.org/wiki/Promises/A
        /// implies that .then() returns a distinct object.
        ////
        /// For compatibility with http://api.jquery.com/category/deferred-object/
        /// we return this same object. This affects ordering, as
        /// the jQuery version will fire callbacks in registration
        /// order regardless of whether they occur on the result
        /// or the original object.
        ///
        /// Compability Note B - Fulfillment value
        ///
        /// The Wiki entry at http://wiki.commonjs.org/wiki/Promises/A
        /// implies that the result of a success callback is the
        /// fulfillment value of the object and is received by
        /// other success callbacks that are chained.
        ///
        /// For compatibility with http://api.jquery.com/category/deferred-object/
        /// we disregard this value instead.
        /// </remarks>

        this._arguments = undefined;
        this._done = undefined;
        this._fail = undefined;
        this._resolved = false;
        this._rejected = false;
    };

    DjsDeferred.prototype = {
        then: function (fulfilledHandler, errorHandler /*, progressHandler */) {
            /// <summary>Adds success and error callbacks for this deferred object.</summary>
            /// <param name="fulfilledHandler" type="Function" mayBeNull="true" optional="true">Success callback.</param>
            /// <param name="errorHandler" type="Function" mayBeNull="true" optional="true">Error callback.</param>
            /// <remarks>See Compatibility Note A.</remarks>

            if (fulfilledHandler) {
                if (!this._done) {
                    this._done = [fulfilledHandler];
                } else {
                    this._done.push(fulfilledHandler);
                }
            }

            if (errorHandler) {
                if (!this._fail) {
                    this._fail = [errorHandler];
                } else {
                    this._fail.push(errorHandler);
                }
            }

            //// See Compatibility Note A in the DjsDeferred constructor.
            //// if (!this._next) {
            ////    this._next = createDeferred();
            //// }
            //// return this._next.promise();

            if (this._resolved) {
                this.resolve.apply(this, this._arguments);
            } else if (this._rejected) {
                this.reject.apply(this, this._arguments);
            }

            return this;
        },

        resolve: function (/* args */) {
            /// <summary>Invokes success callbacks for this deferred object.</summary>
            /// <remarks>All arguments are forwarded to success callbacks.</remarks>


            if (this._done) {
                var i, len;
                for (i = 0, len = this._done.length; i < len; i++) {
                    //// See Compability Note B - Fulfillment value.
                    //// var nextValue =
                    this._done[i].apply(null, arguments);
                }

                //// See Compatibility Note A in the DjsDeferred constructor.
                //// this._next.resolve(nextValue);
                //// delete this._next;

                this._done = undefined;
                this._resolved = false;
                this._arguments = undefined;
            } else {
                this._resolved = true;
                this._arguments = arguments;
            }
        },

        reject: function (/* args */) {
            /// <summary>Invokes error callbacks for this deferred object.</summary>
            /// <remarks>All arguments are forwarded to error callbacks.</remarks>
            if (this._fail) {
                var i, len;
                for (i = 0, len = this._fail.length; i < len; i++) {
                    this._fail[i].apply(null, arguments);
                }

                this._fail = undefined;
                this._rejected = false;
                this._arguments = undefined;
            } else {
                this._rejected = true;
                this._arguments = arguments;
            }
        },

        promise: function () {
            /// <summary>Returns a version of this object that has only the read-only methods available.</summary>
            /// <returns>An object with only the promise object.</returns>

            var result = {};
            result.then = forwardCall(this, "then", result);
            return result;
        }
    };

    var createDeferred = function () {
        /// <summary>Creates a deferred object.</summary>
        /// <returns type="DjsDeferred">
        /// A new deferred object. If jQuery is installed, then a jQuery
        /// Deferred object is returned, which provides a superset of features.
        /// </returns>

        if (window.jQuery && window.jQuery.Deferred) {
            return new window.jQuery.Deferred();
        } else {
            return new DjsDeferred();
        }
    };




    var dataItemTypeName = function (value, metadata) {
        /// <summary>Gets the type name of a data item value that belongs to a feed, an entry, a complex type property, or a collection property.</summary>
        /// <param name="value">Value of the data item from which the type name is going to be retrieved.</param>
        /// <param name="metadata" type="object" optional="true">Object containing metadata about the data tiem.</param>
        /// <remarks>
        ///    This function will first try to get the type name from the data item's value itself if it is an object with a __metadata property; otherwise
        ///    it will try to recover it from the metadata.  If both attempts fail, it will return null.
        /// </remarks>
        /// <returns type="String">Data item type name; null if the type name cannot be found within the value or the metadata</returns>

        var valueTypeName = ((value && value.__metadata) || {}).type;
        return valueTypeName || (metadata ? metadata.type : null);
    };

    var EDM = "Edm.";
    var EDM_BINARY = EDM + "Binary";
    var EDM_BOOLEAN = EDM + "Boolean";
    var EDM_BYTE = EDM + "Byte";
    var EDM_DATETIME = EDM + "DateTime";
    var EDM_DATETIMEOFFSET = EDM + "DateTimeOffset";
    var EDM_DECIMAL = EDM + "Decimal";
    var EDM_DOUBLE = EDM + "Double";
    var EDM_GUID = EDM + "Guid";
    var EDM_INT16 = EDM + "Int16";
    var EDM_INT32 = EDM + "Int32";
    var EDM_INT64 = EDM + "Int64";
    var EDM_SBYTE = EDM + "SByte";
    var EDM_SINGLE = EDM + "Single";
    var EDM_STRING = EDM + "String";
    var EDM_TIME = EDM + "Time";

    var EDM_GEOGRAPHY = EDM + "Geography";
    var EDM_GEOGRAPHY_POINT = EDM_GEOGRAPHY + "Point";
    var EDM_GEOGRAPHY_LINESTRING = EDM_GEOGRAPHY + "LineString";
    var EDM_GEOGRAPHY_POLYGON = EDM_GEOGRAPHY + "Polygon";
    var EDM_GEOGRAPHY_COLLECTION = EDM_GEOGRAPHY + "Collection";
    var EDM_GEOGRAPHY_MULTIPOLYGON = EDM_GEOGRAPHY + "MultiPolygon";
    var EDM_GEOGRAPHY_MULTILINESTRING = EDM_GEOGRAPHY + "MultiLineString";
    var EDM_GEOGRAPHY_MULTIPOINT = EDM_GEOGRAPHY + "MultiPoint";

    var EDM_GEOMETRY = EDM + "Geometry";
    var EDM_GEOMETRY_POINT = EDM_GEOMETRY + "Point";
    var EDM_GEOMETRY_LINESTRING = EDM_GEOMETRY + "LineString";
    var EDM_GEOMETRY_POLYGON = EDM_GEOMETRY + "Polygon";
    var EDM_GEOMETRY_COLLECTION = EDM_GEOMETRY + "Collection";
    var EDM_GEOMETRY_MULTIPOLYGON = EDM_GEOMETRY + "MultiPolygon";
    var EDM_GEOMETRY_MULTILINESTRING = EDM_GEOMETRY + "MultiLineString";
    var EDM_GEOMETRY_MULTIPOINT = EDM_GEOMETRY + "MultiPoint";

    var GEOJSON_POINT = "Point";
    var GEOJSON_LINESTRING = "LineString";
    var GEOJSON_POLYGON = "Polygon";
    var GEOJSON_MULTIPOINT = "MultiPoint";
    var GEOJSON_MULTILINESTRING = "MultiLineString";
    var GEOJSON_MULTIPOLYGON = "MultiPolygon";
    var GEOJSON_GEOMETRYCOLLECTION = "GeometryCollection";

    var primitiveEdmTypes = [
        EDM_STRING,
        EDM_INT32,
        EDM_INT64,
        EDM_BOOLEAN,
        EDM_DOUBLE,
        EDM_SINGLE,
        EDM_DATETIME,
        EDM_DATETIMEOFFSET,
        EDM_TIME,
        EDM_DECIMAL,
        EDM_GUID,
        EDM_BYTE,
        EDM_INT16,
        EDM_SBYTE,
        EDM_BINARY
    ];

    var geometryEdmTypes = [
        EDM_GEOMETRY,
        EDM_GEOMETRY_POINT,
        EDM_GEOMETRY_LINESTRING,
        EDM_GEOMETRY_POLYGON,
        EDM_GEOMETRY_COLLECTION,
        EDM_GEOMETRY_MULTIPOLYGON,
        EDM_GEOMETRY_MULTILINESTRING,
        EDM_GEOMETRY_MULTIPOINT
    ];

    var geographyEdmTypes = [
        EDM_GEOGRAPHY,
        EDM_GEOGRAPHY_POINT,
        EDM_GEOGRAPHY_LINESTRING,
        EDM_GEOGRAPHY_POLYGON,
        EDM_GEOGRAPHY_COLLECTION,
        EDM_GEOGRAPHY_MULTIPOLYGON,
        EDM_GEOGRAPHY_MULTILINESTRING,
        EDM_GEOGRAPHY_MULTIPOINT
    ];

    var forEachSchema = function (metadata, callback) {
        /// <summary>Invokes a function once per schema in metadata.</summary>
        /// <param name="metadata">Metadata store; one of edmx, schema, or an array of any of them.</param>
        /// <param name="callback" type="Function">Callback function to invoke once per schema.</param>
        /// <returns>
        /// The first truthy value to be returned from the callback; null or the last falsy value otherwise.
        /// </returns>

        if (!metadata) {
            return null;
        }

        if (isArray(metadata)) {
            var i, len, result;
            for (i = 0, len = metadata.length; i < len; i++) {
                result = forEachSchema(metadata[i], callback);
                if (result) {
                    return result;
                }
            }

            return null;
        } else {
            if (metadata.dataServices) {
                return forEachSchema(metadata.dataServices.schema, callback);
            }

            return callback(metadata);
        }
    };

    var formatMilliseconds = function (ms, ns) {
        /// <summary>Formats a millisecond and a nanosecond value into a single string.</summary>
        /// <param name="ms" type="Number" mayBeNull="false">Number of milliseconds to format.</param>
        /// <param name="ns" type="Number" mayBeNull="false">Number of nanoseconds to format.</param>
        /// <returns type="String">Formatted text.</returns>
        /// <remarks>If the value is already as string it's returned as-is.</remarks>

        // Avoid generating milliseconds if not necessary.
        if (ms === 0) {
            ms = "";
        } else {
            ms = "." + formatNumberWidth(ms.toString(), 3);
        }
        if (ns > 0) {
            if (ms === "") {
                ms = ".000";
            }
            ms += formatNumberWidth(ns.toString(), 4);
        }
        return ms;
    };

    var formatDateTimeOffset = function (value) {
        /// <summary>Formats a DateTime or DateTimeOffset value a string.</summary>
        /// <param name="value" type="Date" mayBeNull="false">Value to format.</param>
        /// <returns type="String">Formatted text.</returns>
        /// <remarks>If the value is already as string it's returned as-is.</remarks>

        if (typeof value === "string") {
            return value;
        }

        var hasOffset = isDateTimeOffset(value);
        var offset = getCanonicalTimezone(value.__offset);
        if (hasOffset && offset !== "Z") {
            // We're about to change the value, so make a copy.
            value = new Date(value.valueOf());

            var timezone = parseTimezone(offset);
            var hours = value.getUTCHours() + (timezone.d * timezone.h);
            var minutes = value.getUTCMinutes() + (timezone.d * timezone.m);

            value.setUTCHours(hours, minutes);
        } else if (!hasOffset) {
            // Don't suffix a 'Z' for Edm.DateTime values.
            offset = "";
        }

        var year = value.getUTCFullYear();
        var month = value.getUTCMonth() + 1;
        var sign = "";
        if (year <= 0) {
            year = -(year - 1);
            sign = "-";
        }

        var ms = formatMilliseconds(value.getUTCMilliseconds(), value.__ns);

        return sign +
            formatNumberWidth(year, 4) + "-" +
            formatNumberWidth(month, 2) + "-" +
            formatNumberWidth(value.getUTCDate(), 2) + "T" +
            formatNumberWidth(value.getUTCHours(), 2) + ":" +
            formatNumberWidth(value.getUTCMinutes(), 2) + ":" +
            formatNumberWidth(value.getUTCSeconds(), 2) +
            ms + offset;
    };

    var formatDuration = function (value) {
        /// <summary>Converts a duration to a string in xsd:duration format.</summary>
        /// <param name="value" type="Object">Object with ms and __edmType properties.</param>
        /// <returns type="String">String representation of the time object in xsd:duration format.</returns>

        var ms = value.ms;

        var sign = "";
        if (ms < 0) {
            sign = "-";
            ms = -ms;
        }

        var days = Math.floor(ms / 86400000);
        ms -= 86400000 * days;
        var hours = Math.floor(ms / 3600000);
        ms -= 3600000 * hours;
        var minutes = Math.floor(ms / 60000);
        ms -= 60000 * minutes;
        var seconds = Math.floor(ms / 1000);
        ms -= seconds * 1000;

        return sign + "P" +
               formatNumberWidth(days, 2) + "DT" +
               formatNumberWidth(hours, 2) + "H" +
               formatNumberWidth(minutes, 2) + "M" +
               formatNumberWidth(seconds, 2) +
               formatMilliseconds(ms, value.ns) + "S";
    };

    var formatNumberWidth = function (value, width, append) {
        /// <summary>Formats the specified value to the given width.</summary>
        /// <param name="value" type="Number">Number to format (non-negative).</param>
        /// <param name="width" type="Number">Minimum width for number.</param>
        /// <param name="append" type="Boolean">Flag indicating if the value is padded at the beginning (false) or at the end (true).</param>
        /// <returns type="String">Text representation.</returns>
        var result = value.toString(10);
        while (result.length < width) {
            if (append) {
                result += "0";
            } else {
                result = "0" + result;
            }
        }

        return result;
    };

    var getCanonicalTimezone = function (timezone) {
        /// <summary>Gets the canonical timezone representation.</summary>
        /// <param name="timezone" type="String">Timezone representation.</param>
        /// <returns type="String">An 'Z' string if the timezone is absent or 0; the timezone otherwise.</returns>

        return (!timezone || timezone === "Z" || timezone === "+00:00" || timezone === "-00:00") ? "Z" : timezone;
    };

    var getCollectionType = function (typeName) {
        /// <summary>Gets the type of a collection type name.</summary>
        /// <param name="typeName" type="String">Type name of the collection.</param>
        /// <returns type="String">Type of the collection; null if the type name is not a collection type.</returns>

        if (typeof typeName === "string") {
            var end = typeName.indexOf(")", 10);
            if (typeName.indexOf("Collection(") === 0 && end > 0) {
                return typeName.substring(11, end);
            }
        }
        return null;
    };

    var invokeRequest = function (request, success, error, handler, httpClient, context) {
        /// <summary>Sends a request containing OData payload to a server.</summary>
        /// <param name="request">Object that represents the request to be sent..</param>
        /// <param name="success">Callback for a successful read operation.</param>
        /// <param name="error">Callback for handling errors.</param>
        /// <param name="handler">Handler for data serialization.</param>
        /// <param name="httpClient">HTTP client layer.</param>
        /// <param name="context">Context used for processing the request</param>

        return httpClient.request(request, function (response) {
            try {
                if (response.headers) {
                    normalizeHeaders(response.headers);
                }

                if (response.data === undefined && response.statusCode !== 204) {
                    handler.read(response, context);
                }
            } catch (err) {
                if (err.request === undefined) {
                    err.request = request;
                }
                if (err.response === undefined) {
                    err.response = response;
                }
                error(err);
                return;
            }

            success(response.data, response);
        }, error);
    };

    var isBatch = function (value) {
        /// <summary>Tests whether a value is a batch object in the library's internal representation.</summary>
        /// <param name="value">Value to test.</param>
        /// <returns type="Boolean">True is the value is a batch object; false otherwise.</returns>

        return isComplex(value) && isArray(value.__batchRequests);
    };

    // Regular expression used for testing and parsing for a collection type.
    var collectionTypeRE = /Collection\((.*)\)/;

    var isCollection = function (value, typeName) {
        /// <summary>Tests whether a value is a collection value in the library's internal representation.</summary>
        /// <param name="value">Value to test.</param>
        /// <param name="typeName" type="Sting">Type name of the value. This is used to disambiguate from a collection property value.</param>
        /// <returns type="Boolean">True is the value is a feed value; false otherwise.</returns>

        var colData = value && value.results || value;
        return !!colData &&
            (isCollectionType(typeName)) ||
            (!typeName && isArray(colData) && !isComplex(colData[0]));
    };

    var isCollectionType = function (typeName) {
        /// <summary>Checks whether the specified type name is a collection type.</summary>
        /// <param name="typeName" type="String">Name of type to check.</param>
        /// <returns type="Boolean">True if the type is the name of a collection type; false otherwise.</returns>
        return collectionTypeRE.test(typeName);
    };

    var isComplex = function (value) {
        /// <summary>Tests whether a value is a complex type value in the library's internal representation.</summary>
        /// <param name="value">Value to test.</param>
        /// <returns type="Boolean">True is the value is a complex type value; false otherwise.</returns>

        return !!value &&
            isObject(value) &&
            !isArray(value) &&
            !isDate(value);
    };

    var isDateTimeOffset = function (value) {
        /// <summary>Checks whether a Date object is DateTimeOffset value</summary>
        /// <param name="value" type="Date" mayBeNull="false">Value to check.</param>
        /// <returns type="Boolean">true if the value is a DateTimeOffset, false otherwise.</returns>
        return (value.__edmType === "Edm.DateTimeOffset" || (!value.__edmType && value.__offset));
    };

    var isDeferred = function (value) {
        /// <summary>Tests whether a value is a deferred navigation property in the library's internal representation.</summary>
        /// <param name="value">Value to test.</param>
        /// <returns type="Boolean">True is the value is a deferred navigation property; false otherwise.</returns>

        if (!value && !isComplex(value)) {
            return false;
        }
        var metadata = value.__metadata || {};
        var deferred = value.__deferred || {};
        return !metadata.type && !!deferred.uri;
    };

    var isEntry = function (value) {
        /// <summary>Tests whether a value is an entry object in the library's internal representation.</summary>
        /// <param name="value">Value to test.</param>
        /// <returns type="Boolean">True is the value is an entry object; false otherwise.</returns>

        return isComplex(value) && value.__metadata && "uri" in value.__metadata;
    };

    var isFeed = function (value, typeName) {
        /// <summary>Tests whether a value is a feed value in the library's internal representation.</summary>
        /// <param name="value">Value to test.</param>
        /// <param name="typeName" type="Sting">Type name of the value. This is used to disambiguate from a collection property value.</param>
        /// <returns type="Boolean">True is the value is a feed value; false otherwise.</returns>

        var feedData = value && value.results || value;
        return isArray(feedData) && (
            (!isCollectionType(typeName)) &&
            (isComplex(feedData[0]))
        );
    };

    var isGeographyEdmType = function (typeName) {
        /// <summary>Checks whether the specified type name is a geography EDM type.</summary>
        /// <param name="typeName" type="String">Name of type to check.</param>
        /// <returns type="Boolean">True if the type is a geography EDM type; false otherwise.</returns>

        return contains(geographyEdmTypes, typeName);
    };

    var isGeometryEdmType = function (typeName) {
        /// <summary>Checks whether the specified type name is a geometry EDM type.</summary>
        /// <param name="typeName" type="String">Name of type to check.</param>
        /// <returns type="Boolean">True if the type is a geometry EDM type; false otherwise.</returns>

        return contains(geometryEdmTypes, typeName);
    };

    var isNamedStream = function (value) {
        /// <summary>Tests whether a value is a named stream value in the library's internal representation.</summary>
        /// <param name="value">Value to test.</param>
        /// <returns type="Boolean">True is the value is a named stream; false otherwise.</returns>

        if (!value && !isComplex(value)) {
            return false;
        }
        var metadata = value.__metadata;
        var mediaResource = value.__mediaresource;
        return !metadata && !!mediaResource && !!mediaResource.media_src;
    };

    var isPrimitive = function (value) {
        /// <summary>Tests whether a value is a primitive type value in the library's internal representation.</summary>
        /// <param name="value">Value to test.</param>
        /// <remarks>
        ///    Date objects are considered primitive types by the library.
        /// </remarks>
        /// <returns type="Boolean">True is the value is a primitive type value.</returns>

        return isDate(value) ||
            typeof value === "string" ||
            typeof value === "number" ||
            typeof value === "boolean";
    };

    var isPrimitiveEdmType = function (typeName) {
        /// <summary>Checks whether the specified type name is a primitive EDM type.</summary>
        /// <param name="typeName" type="String">Name of type to check.</param>
        /// <returns type="Boolean">True if the type is a primitive EDM type; false otherwise.</returns>

        return contains(primitiveEdmTypes, typeName);
    };

    var navigationPropertyKind = function (value, propertyModel) {
        /// <summary>Gets the kind of a navigation property value.</summary>
        /// <param name="value">Value of the navigation property.</param>
        /// <param name="propertyModel" type="Object" optional="true">
        ///     Object that describes the navigation property in an OData conceptual schema.
        /// </param>
        /// <remarks>
        ///     The returned string is as follows
        /// </remarks>
        /// <returns type="String">String value describing the kind of the navigation property; null if the kind cannot be determined.</returns>

        if (isDeferred(value)) {
            return "deferred";
        }
        if (isEntry(value)) {
            return "entry";
        }
        if (isFeed(value)) {
            return "feed";
        }
        if (propertyModel && propertyModel.relationship) {
            if (value === null || value === undefined || !isFeed(value)) {
                return "entry";
            }
            return "feed";
        }
        return null;
    };

    var lookupProperty = function (properties, name) {
        /// <summary>Looks up a property by name.</summary>
        /// <param name="properties" type="Array" mayBeNull="true">Array of property objects as per EDM metadata.</param>
        /// <param name="name" type="String">Name to look for.</param>
        /// <returns type="Object">The property object; null if not found.</returns>

        return find(properties, function (property) {
            return property.name === name;
        });
    };

    var lookupInMetadata = function (name, metadata, kind) {
        /// <summary>Looks up a type object by name.</summary>
        /// <param name="name" type="String">Name, possibly null or empty.</param>
        /// <param name="metadata">Metadata store; one of edmx, schema, or an array of any of them.</param>
        /// <param name="kind" type="String">Kind of object to look for as per EDM metadata.</param>
        /// <returns>An type description if the name is found; null otherwise.</returns>

        return (name) ? forEachSchema(metadata, function (schema) {
            return lookupInSchema(name, schema, kind);
        }) : null;
    };

    var lookupEntitySet = function (entitySets, name) {
        /// <summary>Looks up a entity set by name.</summary>
        /// <param name="properties" type="Array" mayBeNull="true">Array of entity set objects as per EDM metadata.</param>
        /// <param name="name" type="String">Name to look for.</param>
        /// <returns type="Object">The entity set object; null if not found.</returns>

        return find(entitySets, function (entitySet) {
            return entitySet.name === name;
        });
    };

    var lookupComplexType = function (name, metadata) {
        /// <summary>Looks up a complex type object by name.</summary>
        /// <param name="name" type="String">Name, possibly null or empty.</param>
        /// <param name="metadata">Metadata store; one of edmx, schema, or an array of any of them.</param>
        /// <returns>A complex type description if the name is found; null otherwise.</returns>

        return lookupInMetadata(name, metadata, "complexType");
    };

    var lookupEntityType = function (name, metadata) {
        /// <summary>Looks up an entity type object by name.</summary>
        /// <param name="name" type="String">Name, possibly null or empty.</param>
        /// <param name="metadata">Metadata store; one of edmx, schema, or an array of any of them.</param>
        /// <returns>An entity type description if the name is found; null otherwise.</returns>

        return lookupInMetadata(name, metadata, "entityType");
    };

    var lookupDefaultEntityContainer = function (metadata) {
        /// <summary>Looks up an</summary>
        /// <param name="name" type="String">Name, possibly null or empty.</param>
        /// <param name="metadata">Metadata store; one of edmx, schema, or an array of any of them.</param>
        /// <returns>An entity container description if the name is found; null otherwise.</returns>

        return forEachSchema(metadata, function (schema) {
            return find(schema.entityContainer, function (container) {
                return parseBool(container.isDefaultEntityContainer);
            });
        });
    };

    var lookupEntityContainer = function (name, metadata) {
        /// <summary>Looks up an entity container object by name.</summary>
        /// <param name="name" type="String">Name, possibly null or empty.</param>
        /// <param name="metadata">Metadata store; one of edmx, schema, or an array of any of them.</param>
        /// <returns>An entity container description if the name is found; null otherwise.</returns>

        return lookupInMetadata(name, metadata, "entityContainer");
    };

    var lookupFunctionImport = function (functionImports, name) {
        /// <summary>Looks up a function import by name.</summary>
        /// <param name="properties" type="Array" mayBeNull="true">Array of function import objects as per EDM metadata.</param>
        /// <param name="name" type="String">Name to look for.</param>
        /// <returns type="Object">The entity set object; null if not found.</returns>

        return find(functionImports, function (functionImport) {
            return functionImport.name === name;
        });
    };

    var lookupNavigationPropertyType = function (navigationProperty, metadata) {
        /// <summary>Looks up the target entity type for a navigation property.</summary>
        /// <param name="navigationProperty" type="Object"></param>
        /// <param name="metadata" type="Object"></param>
        /// <returns type="String">The entity type name for the specified property, null if not found.</returns>

        var result = null;
        if (navigationProperty) {
            var rel = navigationProperty.relationship;
            var association = forEachSchema(metadata, function (schema) {
                // The name should be the namespace qualified name in 'ns'.'type' format.
                var nameOnly = removeNamespace(schema["namespace"], rel);
                var associations = schema.association;
                if (nameOnly && associations) {
                    var i, len;
                    for (i = 0, len = associations.length; i < len; i++) {
                        if (associations[i].name === nameOnly) {
                            return associations[i];
                        }
                    }
                }
                return null;
            });

            if (association) {
                var end = association.end[0];
                if (end.role !== navigationProperty.toRole) {
                    end = association.end[1];
                    // For metadata to be valid, end.role === navigationProperty.toRole now.
                }
                result = end.type;
            }
        }
        return result;
    };

    var lookupNavigationPropertyEntitySet = function (navigationProperty, sourceEntitySetName, metadata) {
        /// <summary>Looks up the target entityset name for a navigation property.</summary>
        /// <param name="navigationProperty" type="Object"></param>
        /// <param name="metadata" type="Object"></param>
        /// <returns type="String">The entityset name for the specified property, null if not found.</returns>

        if (navigationProperty) {
            var rel = navigationProperty.relationship;
            var associationSet = forEachSchema(metadata, function (schema) {
                var containers = schema.entityContainer;
                for (var i = 0; i < containers.length; i++) {
                    var associationSets = containers[i].associationSet;
                    if (associationSets) {
                        for (var j = 0; j < associationSets.length; j++) {
                            if (associationSets[j].association == rel) {
                                return associationSets[j];
                            }
                        }
                    }
                }
                return null;
            });
            if (associationSet && associationSet.end[0] && associationSet.end[1]) {
                return (associationSet.end[0].entitySet == sourceEntitySetName) ? associationSet.end[1].entitySet : associationSet.end[0].entitySet;
            }
        }
        return null;
    };

    var getEntitySetInfo = function (entitySetName, metadata) {
        /// <summary>Gets the entitySet info, container name and functionImports for an entitySet</summary>
        /// <param name="navigationProperty" type="Object"></param>
        /// <param name="metadata" type="Object"></param>
        /// <returns type="Object">The info about the entitySet.</returns>

        var info = forEachSchema(metadata, function (schema) {
            var containers = schema.entityContainer;
            for (var i = 0; i < containers.length; i++) {
                var entitySets = containers[i].entitySet;
                if (entitySets) {
                    for (var j = 0; j < entitySets.length; j++) {
                        if (entitySets[j].name == entitySetName) {
                            return { entitySet: entitySets[j], containerName: containers[i].name, functionImport: containers[i].functionImport };
                        }
                    }
                }
            }
            return null;
        });

        return info;
    };

    var removeNamespace = function (ns, fullName) {
        /// <summary>Given an expected namespace prefix, removes it from a full name.</summary>
        /// <param name="ns" type="String">Expected namespace.</param>
        /// <param name="fullName" type="String">Full name in 'ns'.'name' form.</param>
        /// <returns type="String">The local name, null if it isn't found in the expected namespace.</returns>

        if (fullName.indexOf(ns) === 0 && fullName.charAt(ns.length) === ".") {
            return fullName.substr(ns.length + 1);
        }

        return null;
    };

    var lookupInSchema = function (name, schema, kind) {
        /// <summary>Looks up a schema object by name.</summary>
        /// <param name="name" type="String">Name (assigned).</param>
        /// <param name="schema">Schema object as per EDM metadata.</param>
        /// <param name="kind" type="String">Kind of object to look for as per EDM metadata.</param>
        /// <returns>An entity type description if the name is found; null otherwise.</returns>

        if (name && schema) {
            // The name should be the namespace qualified name in 'ns'.'type' format.
            var nameOnly = removeNamespace(schema["namespace"], name);
            if (nameOnly) {
                return find(schema[kind], function (item) {
                    return item.name === nameOnly;
                });
            }
        }
        return null;
    };

    var maxVersion = function (left, right) {
        /// <summary>Compares to version strings and returns the higher one.</summary>
        /// <param name="left" type="String">Version string in the form "major.minor.rev"</param>
        /// <param name="right" type="String">Version string in the form "major.minor.rev"</param>
        /// <returns type="String">The higher version string.</returns>

        if (left === right) {
            return left;
        }

        var leftParts = left.split(".");
        var rightParts = right.split(".");

        var len = (leftParts.length >= rightParts.length) ?
            leftParts.length :
            rightParts.length;

        for (var i = 0; i < len; i++) {
            var leftVersion = leftParts[i] && parseInt10(leftParts[i]);
            var rightVersion = rightParts[i] && parseInt10(rightParts[i]);
            if (leftVersion > rightVersion) {
                return left;
            }
            if (leftVersion < rightVersion) {
                return right;
            }
        }
    };

    var normalHeaders = {
        // Headers shared by request and response
        "content-type": "Content-Type",
        "content-encoding": "Content-Encoding",
        "content-length": "Content-Length",
        "odata-version": "OData-Version",
        
        // Headers used by request
        "accept": "Accept",
        "accept-charset": "Accept-Charset",
        "if-match": "If-Match",
        "if-none-match": "If-None-Match",
        "odata-isolation": "OData-Isolation",
        "odata-maxversion": "OData-MaxVersion",
        "prefer": "Prefer",
        
        // Headers used by response
        "etag": "ETag",
        "location": "Location",
        "odata-entityid": "OData-EntityId",
        "preference-applied": "Preference-Applied",
        "retry-after": "Retry-After"
    };

    var normalizeHeaders = function (headers) {
        /// <summary>Normalizes headers so they can be found with consistent casing.</summary>
        /// <param name="headers" type="Object">Dictionary of name/value pairs.</param>

        for (var name in headers) {
            var lowerName = name.toLowerCase();
            var normalName = normalHeaders[lowerName];
            if (normalName && name !== normalName) {
                var val = headers[name];
                delete headers[name];
                headers[normalName] = val;
            }
        }
    };

    var parseBool = function (propertyValue) {
        /// <summary>Parses a string into a boolean value.</summary>
        /// <param name="propertyValue">Value to parse.</param>
        /// <returns type="Boolean">true if the property value is 'true'; false otherwise.</returns>

        if (typeof propertyValue === "boolean") {
            return propertyValue;
        }

        return typeof propertyValue === "string" && propertyValue.toLowerCase() === "true";
    };


    // The captured indices for this expression are:
    // 0     - complete input
    // 1,2,3 - year with optional minus sign, month, day
    // 4,5,6 - hours, minutes, seconds
    // 7     - optional milliseconds
    // 8     - everything else (presumably offset information)
    var parseDateTimeRE = /^(-?\d{4,})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2}))?(?:\.(\d+))?(.*)$/;

    var parseDateTimeMaybeOffset = function (value, withOffset, nullOnError) {
        /// <summary>Parses a string into a DateTime value.</summary>
        /// <param name="value" type="String">Value to parse.</param>
        /// <param name="withOffset" type="Boolean">Whether offset is expected.</param>
        /// <returns type="Date">The parsed value.</returns>

        // We cannot parse this in cases of failure to match or if offset information is specified.
        var parts = parseDateTimeRE.exec(value);
        var offset = (parts) ? getCanonicalTimezone(parts[8]) : null;

        if (!parts || (!withOffset && offset !== "Z")) {
            if (nullOnError) {
                return null;
            }
            throw { message: "Invalid date/time value" };
        }

        // Pre-parse years, account for year '0' being invalid in dateTime.
        var year = parseInt10(parts[1]);
        if (year <= 0) {
            year++;
        }

        // Pre-parse optional milliseconds, fill in default. Fail if value is too precise.
        var ms = parts[7];
        var ns = 0;
        if (!ms) {
            ms = 0;
        } else {
            if (ms.length > 7) {
                if (nullOnError) {
                    return null;
                }
                throw { message: "Cannot parse date/time value to given precision." };
            }

            ns = formatNumberWidth(ms.substring(3), 4, true);
            ms = formatNumberWidth(ms.substring(0, 3), 3, true);

            ms = parseInt10(ms);
            ns = parseInt10(ns);
        }

        // Pre-parse other time components and offset them if necessary.
        var hours = parseInt10(parts[4]);
        var minutes = parseInt10(parts[5]);
        var seconds = parseInt10(parts[6]) || 0;
        if (offset !== "Z") {
            // The offset is reversed to get back the UTC date, which is
            // what the API will eventually have.
            var timezone = parseTimezone(offset);
            var direction = -(timezone.d);
            hours += timezone.h * direction;
            minutes += timezone.m * direction;
        }

        // Set the date and time separately with setFullYear, so years 0-99 aren't biased like in Date.UTC.
        var result = new Date();
        result.setUTCFullYear(
            year,                       // Year.
            parseInt10(parts[2]) - 1,   // Month (zero-based for Date.UTC and setFullYear).
            parseInt10(parts[3])        // Date.
            );
        result.setUTCHours(hours, minutes, seconds, ms);

        if (isNaN(result.valueOf())) {
            if (nullOnError) {
                return null;
            }
            throw { message: "Invalid date/time value" };
        }

        if (withOffset) {
            result.__edmType = "Edm.DateTimeOffset";
            result.__offset = offset;
        }

        if (ns) {
            result.__ns = ns;
        }

        return result;
    };

    var parseDateTime = function (propertyValue, nullOnError) {
        /// <summary>Parses a string into a DateTime value.</summary>
        /// <param name="propertyValue" type="String">Value to parse.</param>
        /// <returns type="Date">The parsed value.</returns>

        return parseDateTimeMaybeOffset(propertyValue, false, nullOnError);
    };

    var parseDateTimeOffset = function (propertyValue, nullOnError) {
        /// <summary>Parses a string into a DateTimeOffset value.</summary>
        /// <param name="propertyValue" type="String">Value to parse.</param>
        /// <returns type="Date">The parsed value.</returns>
        /// <remarks>
        /// The resulting object is annotated with an __edmType property and
        /// an __offset property reflecting the original intended offset of
        /// the value. The time is adjusted for UTC time, as the current
        /// timezone-aware Date APIs will only work with the local timezone.
        /// </remarks>

        return parseDateTimeMaybeOffset(propertyValue, true, nullOnError);
    };

    // The captured indices for this expression are:
    // 0       - complete input
    // 1       - direction
    // 2,3,4   - years, months, days
    // 5,6,7,8 - hours, minutes, seconds, miliseconds

    var parseTimeRE = /^([+-])?P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)(?:\.(\d+))?S)?)?/;

    var isEdmDurationValue = function(value) {
        parseTimeRE.test(value);
    };

    var parseDuration = function (duration) {
        /// <summary>Parses a string in xsd:duration format.</summary>
        /// <param name="duration" type="String">Duration value.</param>
        /// <remarks>
        /// This method will throw an exception if the input string has a year or a month component.
        /// </remarks>
        /// <returns type="Object">Object representing the time</returns>

        var parts = parseTimeRE.exec(duration);

        if (parts === null) {
            throw { message: "Invalid duration value." };
        }

        var years = parts[2] || "0";
        var months = parts[3] || "0";
        var days = parseInt10(parts[4] || 0);
        var hours = parseInt10(parts[5] || 0);
        var minutes = parseInt10(parts[6] || 0);
        var seconds = parseFloat(parts[7] || 0);

        if (years !== "0" || months !== "0") {
            throw { message: "Unsupported duration value." };
        }

        var ms = parts[8];
        var ns = 0;
        if (!ms) {
            ms = 0;
        } else {
            if (ms.length > 7) {
                throw { message: "Cannot parse duration value to given precision." };
            }

            ns = formatNumberWidth(ms.substring(3), 4, true);
            ms = formatNumberWidth(ms.substring(0, 3), 3, true);

            ms = parseInt10(ms);
            ns = parseInt10(ns);
        }

        ms += seconds * 1000 + minutes * 60000 + hours * 3600000 + days * 86400000;

        if (parts[1] === "-") {
            ms = -ms;
        }

        var result = { ms: ms, __edmType: "Edm.Time" };

        if (ns) {
            result.ns = ns;
        }
        return result;
    };

    var parseTimezone = function (timezone) {
        /// <summary>Parses a timezone description in (+|-)nn:nn format.</summary>
        /// <param name="timezone" type="String">Timezone offset.</param>
        /// <returns type="Object">
        /// An object with a (d)irection property of 1 for + and -1 for -,
        /// offset (h)ours and offset (m)inutes.
        /// </returns>

        var direction = timezone.substring(0, 1);
        direction = (direction === "+") ? 1 : -1;

        var offsetHours = parseInt10(timezone.substring(1));
        var offsetMinutes = parseInt10(timezone.substring(timezone.indexOf(":") + 1));
        return { d: direction, h: offsetHours, m: offsetMinutes };
    };

    var prepareRequest = function (request, handler, context) {
        /// <summary>Prepares a request object so that it can be sent through the network.</summary>
        /// <param name="request">Object that represents the request to be sent.</param>
        /// <param name="handler">Handler for data serialization</param>
        /// <param name="context">Context used for preparing the request</param>

        // Default to GET if no method has been specified.
        if (!request.method) {
            request.method = "GET";
        }

        if (!request.headers) {
            request.headers = {};
        } else {
            normalizeHeaders(request.headers);
        }

        if (request.headers.Accept === undefined) {
            request.headers.Accept = handler.accept;
        }

        if (assigned(request.data) && request.body === undefined) {
            handler.write(request, context);
        }

        if (!assigned(request.headers["OData-MaxVersion"])) {
            request.headers["OData-MaxVersion"] = handler.maxDataServiceVersion || "4.0";
        }
    };

    var traverseInternal = function (item, owner, callback) {
        /// <summary>Traverses a tree of objects invoking callback for every value.</summary>
        /// <param name="item" type="Object">Object or array to traverse.</param>
        /// <param name="callback" type="Function">
        /// Callback function with key and value, similar to JSON.parse reviver.
        /// </param>
        /// <returns type="Object">The object with traversed properties.</returns>
        /// <remarks>Unlike the JSON reviver, this won't delete null members.</remarks>

        if (item && typeof item === "object") {
            for (var name in item) {
                var value = item[name];
                var result = traverseInternal(value, name, callback);
                result = callback(name, result, owner);
                if (result !== value) {
                    if (value === undefined) {
                        delete item[name];
                    } else {
                        item[name] = result;
                    }
                }
            }
        }

        return item;
    };

    var traverse = function (item, callback) {
        /// <summary>Traverses a tree of objects invoking callback for every value.</summary>
        /// <param name="item" type="Object">Object or array to traverse.</param>
        /// <param name="callback" type="Function">
        /// Callback function with key and value, similar to JSON.parse reviver.
        /// </param>
        /// <returns type="Object">The traversed object.</returns>
        /// <remarks>Unlike the JSON reviver, this won't delete null members.</remarks>

        return callback("", traverseInternal(item, "", callback));
    };


    var ticks = 0;

    var canUseJSONP = function (request) {
        /// <summary>
        /// Checks whether the specified request can be satisfied with a JSONP request.
        /// </summary>
        /// <param name="request">Request object to check.</param>
        /// <returns type="Boolean">true if the request can be satisfied; false otherwise.</returns>

        // Requests that 'degrade' without changing their meaning by going through JSONP
        // are considered usable.
        //
        // We allow data to come in a different format, as the servers SHOULD honor the Accept
        // request but may in practice return content with a different MIME type.
        if (request.method && request.method !== "GET") {
            return false;
        }

        return true;
    };

    var createIFrame = function (url) {
        /// <summary>Creates an IFRAME tag for loading the JSONP script</summary>
        /// <param name="url" type="String">The source URL of the script</param>
        /// <returns type="HTMLElement">The IFRAME tag</returns>
        var iframe = window.document.createElement("IFRAME");
        iframe.style.display = "none";

        var attributeEncodedUrl = url.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/\</g, "&lt;");
        var html = "<html><head><script type=\"text/javascript\" src=\"" + attributeEncodedUrl + "\"><\/script><\/head><body><\/body><\/html>";

        var body = window.document.getElementsByTagName("BODY")[0];
        body.appendChild(iframe);

        writeHtmlToIFrame(iframe, html);
        return iframe;
    };

    var createXmlHttpRequest = function () {
        /// <summary>Creates a XmlHttpRequest object.</summary>
        /// <returns type="XmlHttpRequest">XmlHttpRequest object.</returns>
        if (window.XMLHttpRequest) {
            return new window.XMLHttpRequest();
        }
        var exception;
        if (window.ActiveXObject) {
            try {
                return new window.ActiveXObject("Msxml2.XMLHTTP.6.0");
            } catch (_) {
                try {
                    return new window.ActiveXObject("Msxml2.XMLHTTP.3.0");
                } catch (e) {
                    exception = e;
                }
            }
        } else {
            exception = { message: "XMLHttpRequest not supported" };
        }
        throw exception;
    };

    var isAbsoluteUrl = function (url) {
        /// <summary>Checks whether the specified URL is an absolute URL.</summary>
        /// <param name="url" type="String">URL to check.</param>
        /// <returns type="Boolean">true if the url is an absolute URL; false otherwise.</returns>

        return url.indexOf("http://") === 0 ||
            url.indexOf("https://") === 0 ||
            url.indexOf("file://") === 0;
    };

    var isLocalUrl = function (url) {
        /// <summary>Checks whether the specified URL is local to the current context.</summary>
        /// <param name="url" type="String">URL to check.</param>
        /// <returns type="Boolean">true if the url is a local URL; false otherwise.</returns>

        if (!isAbsoluteUrl(url)) {
            return true;
        }

        // URL-embedded username and password will not be recognized as same-origin URLs.
        var location = window.location;
        var locationDomain = location.protocol + "//" + location.host + "/";
        return (url.indexOf(locationDomain) === 0);
    };

    var removeCallback = function (name, tick) {
        /// <summary>Removes a callback used for a JSONP request.</summary>
        /// <param name="name" type="String">Function name to remove.</param>
        /// <param name="tick" type="Number">Tick count used on the callback.</param>
        try {
            delete window[name];
        } catch (err) {
            window[name] = undefined;
            if (tick === ticks - 1) {
                ticks -= 1;
            }
        }
    };

    var removeIFrame = function (iframe) {
        /// <summary>Removes an iframe.</summary>
        /// <param name="iframe" type="Object">The iframe to remove.</param>
        /// <returns type="Object">Null value to be assigned to iframe reference.</returns>
        if (iframe) {
            writeHtmlToIFrame(iframe, "");
            iframe.parentNode.removeChild(iframe);
        }

        return null;
    };

    var readResponseHeaders = function (xhr, headers) {
        /// <summary>Reads response headers into array.</summary>
        /// <param name="xhr" type="XMLHttpRequest">HTTP request with response available.</param>
        /// <param name="headers" type="Array">Target array to fill with name/value pairs.</param>

        var responseHeaders = xhr.getAllResponseHeaders().split(/\r?\n/);
        var i, len;
        for (i = 0, len = responseHeaders.length; i < len; i++) {
            if (responseHeaders[i]) {
                var header = responseHeaders[i].split(": ");
                headers[header[0]] = header[1];
            }
        }
    };

    var writeHtmlToIFrame = function (iframe, html) {
        /// <summary>Writes HTML to an IFRAME document.</summary>
        /// <param name="iframe" type="HTMLElement">The IFRAME element to write to.</param>
        /// <param name="html" type="String">The HTML to write.</param>
        var frameDocument = (iframe.contentWindow) ? iframe.contentWindow.document : iframe.contentDocument.document;
        frameDocument.open();
        frameDocument.write(html);
        frameDocument.close();
    };

    odata.defaultHttpClient = {
        callbackParameterName: "$callback",

        formatQueryString: "$format=json",

        enableJsonpCallback: false,

        request: function (request, success, error) {
            /// <summary>Performs a network request.</summary>
            /// <param name="request" type="Object">Request description.</request>
            /// <param name="success" type="Function">Success callback with the response object.</param>
            /// <param name="error" type="Function">Error callback with an error object.</param>
            /// <returns type="Object">Object with an 'abort' method for the operation.</returns>

            var result = {};
            var xhr = null;
            var done = false;
            var iframe;

            result.abort = function () {
                iframe = removeIFrame(iframe);
                if (done) {
                    return;
                }

                done = true;
                if (xhr) {
                    xhr.abort();
                    xhr = null;
                }

                error({ message: "Request aborted" });
            };

            var handleTimeout = function () {
                iframe = removeIFrame(iframe);
                if (!done) {
                    done = true;
                    xhr = null;
                    error({ message: "Request timed out" });
                }
            };

            var name;
            var url = request.requestUri;
            var enableJsonpCallback = defined(request.enableJsonpCallback, this.enableJsonpCallback);
            var callbackParameterName = defined(request.callbackParameterName, this.callbackParameterName);
            var formatQueryString = defined(request.formatQueryString, this.formatQueryString);
            if (!enableJsonpCallback || isLocalUrl(url)) {

                xhr = createXmlHttpRequest();
                xhr.onreadystatechange = function () {
                    if (done || xhr === null || xhr.readyState !== 4) {
                        return;
                    }

                    // Workaround for XHR behavior on IE.
                    var statusText = xhr.statusText;
                    var statusCode = xhr.status;
                    if (statusCode === 1223) {
                        statusCode = 204;
                        statusText = "No Content";
                    }

                    var headers = [];
                    readResponseHeaders(xhr, headers);

                    var response = { requestUri: url, statusCode: statusCode, statusText: statusText, headers: headers, body: xhr.responseText };

                    done = true;
                    xhr = null;
                    if (statusCode >= 200 && statusCode <= 299) {
                        success(response);
                    } else {
                        error({ message: "HTTP request failed", request: request, response: response });
                    }
                };

                xhr.open(request.method || "GET", url, true, request.user, request.password);

                // Set the name/value pairs.
                if (request.headers) {
                    for (name in request.headers) {
                        xhr.setRequestHeader(name, request.headers[name]);
                    }
                }

                // Set the timeout if available.
                if (request.timeoutMS) {
                    xhr.timeout = request.timeoutMS;
                    xhr.ontimeout = handleTimeout;
                }

                xhr.send(request.body);
            } else {
                if (!canUseJSONP(request)) {
                    throw { message: "Request is not local and cannot be done through JSONP." };
                }

                var tick = ticks;
                ticks += 1;
                var tickText = tick.toString();
                var succeeded = false;
                var timeoutId;
                name = "handleJSONP_" + tickText;
                window[name] = function (data) {
                    iframe = removeIFrame(iframe);
                    if (!done) {
                        succeeded = true;
                        window.clearTimeout(timeoutId);
                        removeCallback(name, tick);

                        // Workaround for IE8 and IE10 below where trying to access data.constructor after the IFRAME has been removed
                        // throws an "unknown exception"
                        if (window.ActiveXObject) {
                            data = window.JSON.parse(window.JSON.stringify(data));
                        }

                        var headers;
                        if (!formatQueryString || formatQueryString == "$format=json") {
                            headers = { "Content-Type": "application/json;odata.metadata=minimal", "OData-Version": "4.0" };
                        } else {
                            // the formatQueryString should be in the format of "$format=xxx", xxx should be one of the application/json;odata.metadata=minimal(none or full)
                            // set the content-type with the string xxx which stars from index 8.
                            headers = { "Content-Type": formatQueryString.substring(8), "OData-Version": "4.0" };
                        }

                        // Call the success callback in the context of the parent window, instead of the IFRAME
                        delay(function () {
                            removeIFrame(iframe);
                            success({ body: data, statusCode: 200, headers: headers });
                        });
                    }
                };

                // Default to two minutes before timing out, 1000 ms * 60 * 2 = 120000.
                var timeoutMS = (request.timeoutMS) ? request.timeoutMS : 120000;
                timeoutId = window.setTimeout(handleTimeout, timeoutMS);

                var queryStringParams = callbackParameterName + "=parent." + name;
                if (formatQueryString) {
                    queryStringParams += "&" + formatQueryString;
                }

                var qIndex = url.indexOf("?");
                if (qIndex === -1) {
                    url = url + "?" + queryStringParams;
                } else if (qIndex === url.length - 1) {
                    url = url + queryStringParams;
                } else {
                    url = url + "&" + queryStringParams;
                }

                iframe = createIFrame(url);
            }

            return result;
        }
    };



    var MAX_DATA_SERVICE_VERSION = "4.0";

    var contentType = function (str) {
        /// <summary>Parses a string into an object with media type and properties.</summary>
        /// <param name="str" type="String">String with media type to parse.</param>
        /// <returns>null if the string is empty; an object with 'mediaType' and a 'properties' dictionary otherwise.</returns>

        if (!str) {
            return null;
        }

        var contentTypeParts = str.split(";");
        var properties = {};

        var i, len;
        for (i = 1, len = contentTypeParts.length; i < len; i++) {
            var contentTypeParams = contentTypeParts[i].split("=");
            properties[trimString(contentTypeParams[0])] = contentTypeParams[1];
        }

        return { mediaType: trimString(contentTypeParts[0]), properties: properties };
    };

    var contentTypeToString = function (contentType) {
        /// <summary>Serializes an object with media type and properties dictionary into a string.</summary>
        /// <param name="contentType">Object with media type and properties dictionary to serialize.</param>
        /// <returns>String representation of the media type object; undefined if contentType is null or undefined.</returns>

        if (!contentType) {
            return undefined;
        }

        var result = contentType.mediaType;
        var property;
        for (property in contentType.properties) {
            result += ";" + property + "=" + contentType.properties[property];
        }
        return result;
    };

    var createReadWriteContext = function (contentType, dataServiceVersion, context, handler) {
        /// <summary>Creates an object that is going to be used as the context for the handler's parser and serializer.</summary>
        /// <param name="contentType">Object with media type and properties dictionary.</param>
        /// <param name="dataServiceVersion" type="String">String indicating the version of the protocol to use.</param>
        /// <param name="context">Operation context.</param>
        /// <param name="handler">Handler object that is processing a resquest or response.</param>
        /// <returns>Context object.</returns>

        var rwContext = {};
        extend(rwContext, context);
        extend(rwContext, {
            contentType: contentType,
            dataServiceVersion: dataServiceVersion,
            handler: handler
        });

        return rwContext;
    };

    var fixRequestHeader = function (request, name, value) {
        /// <summary>Sets a request header's value. If the header has already a value other than undefined, null or empty string, then this method does nothing.</summary>
        /// <param name="request">Request object on which the header will be set.</param>
        /// <param name="name" type="String">Header name.</param>
        /// <param name="value" type="String">Header value.</param>
        if (!request) {
            return;
        }

        var headers = request.headers;
        if (!headers[name]) {
            headers[name] = value;
        }
    };

    var fixDataServiceVersionHeader = function (request, version) {
        /// <summary>Sets the DataServiceVersion header of the request if its value is not yet defined or of a lower version.</summary>
        /// <param name="request">Request object on which the header will be set.</param>
        /// <param name="version" type="String">Version value.</param>
        /// <remarks>
        /// If the request has already a version value higher than the one supplied the this function does nothing.
        /// </remarks>

        if (request) {
            var headers = request.headers;
            var dsv = headers["OData-Version"];
            headers["OData-Version"] = dsv ? maxVersion(dsv, version) : version;
        }
    };

    var getRequestOrResponseHeader = function (requestOrResponse, name) {
        /// <summary>Gets the value of a request or response header.</summary>
        /// <param name="requestOrResponse">Object representing a request or a response.</param>
        /// <param name="name" type="String">Name of the header to retrieve.</param>
        /// <returns type="String">String value of the header; undefined if the header cannot be found.</returns>

        var headers = requestOrResponse.headers;
        return (headers && headers[name]) || undefined;
    };

    var getContentType = function (requestOrResponse) {
        /// <summary>Gets the value of the Content-Type header from a request or response.</summary>
        /// <param name="requestOrResponse">Object representing a request or a response.</param>
        /// <returns type="Object">Object with 'mediaType' and a 'properties' dictionary; null in case that the header is not found or doesn't have a value.</returns>

        return contentType(getRequestOrResponseHeader(requestOrResponse, "Content-Type"));
    };

    var versionRE = /^\s?(\d+\.\d+);?.*$/;
    var getDataServiceVersion = function (requestOrResponse) {
        /// <summary>Gets the value of the DataServiceVersion header from a request or response.</summary>
        /// <param name="requestOrResponse">Object representing a request or a response.</param>
        /// <returns type="String">Data service version; undefined if the header cannot be found.</returns>

        var value = getRequestOrResponseHeader(requestOrResponse, "OData-Version");
        if (value) {
            var matches = versionRE.exec(value);
            if (matches && matches.length) {
                return matches[1];
            }
        }

        // Fall through and return undefined.
    };

    var handlerAccepts = function (handler, cType) {
        /// <summary>Checks that a handler can process a particular mime type.</summary>
        /// <param name="handler">Handler object that is processing a resquest or response.</param>
        /// <param name="cType">Object with 'mediaType' and a 'properties' dictionary.</param>
        /// <returns type="Boolean">True if the handler can process the mime type; false otherwise.</returns>

        // The following check isn't as strict because if cType.mediaType = application/; it will match an accept value of "application/xml";
        // however in practice we don't not expect to see such "suffixed" mimeTypes for the handlers.
        return handler.accept.indexOf(cType.mediaType) >= 0;
    };

    var handlerRead = function (handler, parseCallback, response, context) {
        /// <summary>Invokes the parser associated with a handler for reading the payload of a HTTP response.</summary>
        /// <param name="handler">Handler object that is processing the response.</param>
        /// <param name="parseCallback" type="Function">Parser function that will process the response payload.</param>
        /// <param name="response">HTTP response whose payload is going to be processed.</param>
        /// <param name="context">Object used as the context for processing the response.</param>
        /// <returns type="Boolean">True if the handler processed the response payload and the response.data property was set; false otherwise.</returns>

        if (!response || !response.headers) {
            return false;
        }

        var cType = getContentType(response);
        var version = getDataServiceVersion(response) || "";
        var body = response.body;

        if (!assigned(body)) {
            return false;
        }

        if (handlerAccepts(handler, cType)) {
            var readContext = createReadWriteContext(cType, version, context, handler);
            readContext.response = response;
            response.data = parseCallback(handler, body, readContext);
            return response.data !== undefined;
        }

        return false;
    };

    var handlerWrite = function (handler, serializeCallback, request, context) {
        /// <summary>Invokes the serializer associated with a handler for generating the payload of a HTTP request.</summary>
        /// <param name="handler">Handler object that is processing the request.</param>
        /// <param name="serializeCallback" type="Function">Serializer function that will generate the request payload.</param>
        /// <param name="response">HTTP request whose payload is going to be generated.</param>
        /// <param name="context">Object used as the context for serializing the request.</param>
        /// <returns type="Boolean">True if the handler serialized the request payload and the request.body property was set; false otherwise.</returns>
        if (!request || !request.headers) {
            return false;
        }

        var cType = getContentType(request);
        var version = getDataServiceVersion(request);

        if (!cType || handlerAccepts(handler, cType)) {
            var writeContext = createReadWriteContext(cType, version, context, handler);
            writeContext.request = request;

            request.body = serializeCallback(handler, request.data, writeContext);

            if (request.body !== undefined) {
                fixDataServiceVersionHeader(request, writeContext.dataServiceVersion || "4.0");

                fixRequestHeader(request, "Content-Type", contentTypeToString(writeContext.contentType));
                fixRequestHeader(request, "OData-MaxVersion", handler.maxDataServiceVersion);
                return true;
            }
        }

        return false;
    };

    var handler = function (parseCallback, serializeCallback, accept, maxDataServiceVersion) {
        /// <summary>Creates a handler object for processing HTTP requests and responses.</summary>
        /// <param name="parseCallback" type="Function">Parser function that will process the response payload.</param>
        /// <param name="serializeCallback" type="Function">Serializer function that will generate the request payload.</param>
        /// <param name="accept" type="String">String containing a comma separated list of the mime types that this handler can work with.</param>
        /// <param name="maxDataServiceVersion" type="String">String indicating the highest version of the protocol that this handler can work with.</param>
        /// <returns type="Object">Handler object.</returns>

        return {
            accept: accept,
            maxDataServiceVersion: maxDataServiceVersion,

            read: function (response, context) {
                return handlerRead(this, parseCallback, response, context);
            },

            write: function (request, context) {
                return handlerWrite(this, serializeCallback, request, context);
            }
        };
    };

    var textParse = function (handler, body /*, context */) {
        return body;
    };

    var textSerialize = function (handler, data /*, context */) {
        if (assigned(data)) {
            return data.toString();
        } else {
            return undefined;
        }
    };

    odata.textHandler = handler(textParse, textSerialize, "text/plain", MAX_DATA_SERVICE_VERSION);


    var gmlOpenGis = http + "www.opengis.net";           // http://www.opengis.net
    var gmlXmlNs = gmlOpenGis + "/gml";                 // http://www.opengis.net/gml
    var gmlSrsPrefix = gmlOpenGis + "/def/crs/EPSG/0/"; // http://www.opengis.net/def/crs/EPSG/0/

    var gmlPrefix = "gml";

    var gmlCreateGeoJSONOBject = function (type, member, data) {
        /// <summary>Creates a GeoJSON object with the specified type, member and value.</summary>
        /// <param name="type" type="String">GeoJSON object type.</param>
        /// <param name="member" type="String">Name for the data member in the GeoJSON object.</param>
        /// <param name="data">Data to be contained by the GeoJSON object.</param>
        /// <returns type="Object">GeoJSON object.</returns>

        var result = { type: type };
        result[member] = data;
        return result;
    };

    var gmlSwapLatLong = function (coordinates) {
        /// <summary>Swaps the longitude and latitude in the coordinates array.</summary>
        /// <param name="coordinates" type="Array">Array of doubles descrbing a set of coordinates.</param>
        /// <returns type="Array">Array of doubles with the latitude and longitude components swapped.</returns>

        if (isArray(coordinates) && coordinates.length >= 2) {
            var tmp = coordinates[0];
            coordinates[0] = coordinates[1];
            coordinates[1] = tmp;
        }
        return coordinates;
    };

    var gmlReadODataMultiItem = function (domElement, type, member, members, valueReader, isGeography) {
        /// <summary>
        ///    Reads a GML DOM element that represents a composite structure like a multi-point or a
        ///    multi-geometry returnig its GeoJSON representation.
        /// </summary>
        /// <param name="domElement">GML DOM element.</param>
        /// <param name="type" type="String">GeoJSON object type.</param>
        /// <param name="member" type="String">Name for the child element representing a single item in the composite structure.</param>
        /// <param name="members" type="String">Name for the child element representing a collection of items in the composite structure.</param>
        /// <param name="valueReader" type="Function">Callback function invoked to get the coordinates of each item in the comoposite structure.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns type="Object">GeoJSON object.</returns>

        var coordinates = gmlReadODataMultiItemValue(domElement, member, members, valueReader, isGeography);
        return gmlCreateGeoJSONOBject(type, "coordinates", coordinates);
    };

    var gmlReadODataMultiItemValue = function (domElement, member, members, valueReader, isGeography) {
        /// <summary>
        ///    Reads the value of a GML DOM element that represents a composite structure like a multi-point or a
        ///    multi-geometry returnig its items.
        /// </summary>
        /// <param name="domElement">GML DOM element.</param>
        /// <param name="type" type="String">GeoJSON object type.</param>
        /// <param name="member" type="String">Name for the child element representing a single item in the composite structure.</param>
        /// <param name="members" type="String">Name for the child element representing a collection of items in the composite structure.</param>
        /// <param name="valueReader" type="Function">Callback function invoked to get the transformed value of each item in the comoposite structure.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns type="Array">Array containing the transformed value of each item in the multi-item.</returns>

        var items = [];

        xmlChildElements(domElement, function (child) {
            if (xmlNamespaceURI(child) !== gmlXmlNs) {
                return;
            }

            var localName = xmlLocalName(child);

            if (localName === member) {
                var valueElement = xmlFirstChildElement(child, gmlXmlNs);
                if (valueElement) {
                    var value = valueReader(valueElement, isGeography);
                    if (value) {
                        items.push(value);
                    }
                }
                return;
            }

            if (localName === members) {
                xmlChildElements(child, function (valueElement) {
                    if (xmlNamespaceURI(valueElement) !== gmlXmlNs) {
                        return;
                    }

                    var value = valueReader(valueElement, isGeography);
                    if (value) {
                        items.push(value);
                    }
                });
            }
        });
        return items;
    };

    var gmlReadODataCollection = function (domElement, isGeography) {
        /// <summary>Reads a GML DOM element representing a multi-geometry returning its GeoJSON representation.</summary>
        /// <param name="domElement">DOM element.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns type="Object">MultiGeometry object in GeoJSON format.</returns>

        var geometries = gmlReadODataMultiItemValue(domElement, "geometryMember", "geometryMembers", gmlReadODataSpatialValue, isGeography);
        return gmlCreateGeoJSONOBject(GEOJSON_GEOMETRYCOLLECTION, "geometries", geometries);
    };

    var gmlReadODataLineString = function (domElement, isGeography) {
        /// <summary>Reads a GML DOM element representing a line string returning its GeoJSON representation.</summary>
        /// <param name="domElement">DOM element.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns type="Object">LineString object in GeoJSON format.</returns>

        return gmlCreateGeoJSONOBject(GEOJSON_LINESTRING, "coordinates", gmlReadODataLineValue(domElement, isGeography));
    };

    var gmlReadODataMultiLineString = function (domElement, isGeography) {
        /// <summary>Reads a GML DOM element representing a multi-line string returning its GeoJSON representation.</summary>
        /// <param name="domElement">DOM element.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns type="Object">MultiLineString object in GeoJSON format.</returns>

        return gmlReadODataMultiItem(domElement, GEOJSON_MULTILINESTRING, "curveMember", "curveMembers", gmlReadODataLineValue, isGeography);
    };

    var gmlReadODataMultiPoint = function (domElement, isGeography) {
        /// <summary>Reads a GML DOM element representing a multi-point returning its GeoJSON representation.</summary>
        /// <param name="domElement">DOM element.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns type="Object">MultiPoint object in GeoJSON format.</returns>

        return gmlReadODataMultiItem(domElement, GEOJSON_MULTIPOINT, "pointMember", "pointMembers", gmlReadODataPointValue, isGeography);
    };

    var gmlReadODataMultiPolygon = function (domElement, isGeography) {
        /// <summary>Reads a GML DOM element representing a multi-polygon returning its GeoJSON representation.</summary>
        /// <param name="domElement">DOM element.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns type="Object">MultiPolygon object in GeoJSON format.</returns>

        return gmlReadODataMultiItem(domElement, GEOJSON_MULTIPOLYGON, "surfaceMember", "surfaceMembers", gmlReadODataPolygonValue, isGeography);
    };

    var gmlReadODataPoint = function (domElement, isGeography) {
        /// <summary>Reads a GML DOM element representing a point returning its GeoJSON representation.</summary>
        /// <param name="domElement">DOM element.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns type="Object">Point object in GeoJSON format.</returns>

        return gmlCreateGeoJSONOBject(GEOJSON_POINT, "coordinates", gmlReadODataPointValue(domElement, isGeography));
    };

    var gmlReadODataPolygon = function (domElement, isGeography) {
        /// <summary>Reads a GML DOM element representing a polygon returning its GeoJSON representation.</summary>
        /// <param name="domElement">DOM element.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns type="Object">Polygon object in GeoJSON format.</returns>

        return gmlCreateGeoJSONOBject(GEOJSON_POLYGON, "coordinates", gmlReadODataPolygonValue(domElement, isGeography));
    };

    var gmlReadODataLineValue = function (domElement, isGeography) {
        /// <summary>Reads the value of a GML DOM element representing a line returning its set of coordinates.</summary>
        /// <param name="domElement">DOM element.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns type="Array">Array containing an array of doubles for each coordinate of the line.</returns>

        var coordinates = [];

        xmlChildElements(domElement, function (child) {
            var nsURI = xmlNamespaceURI(child);

            if (nsURI !== gmlXmlNs) {
                return;
            }

            var localName = xmlLocalName(child);

            if (localName === "posList") {
                coordinates = gmlReadODataPosListValue(child, isGeography);
                return;
            }
            if (localName === "pointProperty") {
                coordinates.push(gmlReadODataPointWrapperValue(child, isGeography));
                return;
            }
            if (localName === "pos") {
                coordinates.push(gmlReadODataPosValue(child, isGeography));
                return;
            }
        });

        return coordinates;
    };

    var gmlReadODataPointValue = function (domElement, isGeography) {
        /// <summary>Reads the value of a GML DOM element representing a point returning its coordinates.</summary>
        /// <param name="domElement">DOM element.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns type="Array">Array of doubles containing the point coordinates.</returns>

        var pos = xmlFirstChildElement(domElement, gmlXmlNs, "pos");
        return pos ? gmlReadODataPosValue(pos, isGeography) : [];
    };

    var gmlReadODataPointWrapperValue = function (domElement, isGeography) {
        /// <summary>Reads the value of a GML DOM element wrapping an element representing a point returning its coordinates.</summary>
        /// <param name="domElement">DOM element.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns type="Array">Array of doubles containing the point coordinates.</returns>

        var point = xmlFirstChildElement(domElement, gmlXmlNs, "Point");
        return point ? gmlReadODataPointValue(point, isGeography) : [];
    };

    var gmlReadODataPolygonValue = function (domElement, isGeography) {
        /// <summary>Reads the value of a GML DOM element representing a polygon returning its set of coordinates.</summary>
        /// <param name="domElement">DOM element.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns type="Array">Array containing an array of array of doubles for each ring of the polygon.</returns>

        var coordinates = [];
        var exteriorFound = false;
        xmlChildElements(domElement, function (child) {
            if (xmlNamespaceURI(child) !== gmlXmlNs) {
                return;
            }

            // Only the exterior and the interior rings are interesting
            var localName = xmlLocalName(child);
            if (localName === "exterior") {
                exteriorFound = true;
                coordinates.unshift(gmlReadODataPolygonRingValue(child, isGeography));
                return;
            }
            if (localName === "interior") {
                coordinates.push(gmlReadODataPolygonRingValue(child, isGeography));
                return;
            }
        });

        if (!exteriorFound && coordinates.length > 0) {
            // Push an empty exterior ring.
            coordinates.unshift([[]]);
        }

        return coordinates;
    };

    var gmlReadODataPolygonRingValue = function (domElement, isGeography) {
        /// <summary>Reads the value of a GML DOM element representing a linear ring in a GML Polygon element.</summary>
        /// <param name="domElement">DOM element.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns type="Array">Array containing an array of doubles for each coordinate of the linear ring.</returns>

        var value = [];
        xmlChildElements(domElement, function (child) {
            if (xmlNamespaceURI(child) !== gmlXmlNs || xmlLocalName(child) !== "LinearRing") {
                return;
            }
            value = gmlReadODataLineValue(child, isGeography);
        });
        return value;
    };

    var gmlReadODataPosListValue = function (domElement, isGeography) {
        /// <summary>Reads the value of a GML DOM element representing a list of positions retruning its set of coordinates.</summary>
        /// <param name="domElement">DOM element.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        ///
        ///    The positions described by the list are assumed to be 2D, so 
        ///    an exception will be thrown if the list has an odd number elements.
        /// </remarks>
        /// <returns type="Array">Array containing an array of doubles for each coordinate in the list.</returns>

        var coordinates = gmlReadODataPosValue(domElement, false);
        var len = coordinates.length;

        if (len % 2 !== 0) {
            throw { message: "GML posList element has an uneven number of numeric values" };
        }

        var value = [];
        for (var i = 0; i < len; i += 2) {
            var pos = coordinates.slice(i, i + 2);
            value.push(isGeography ? gmlSwapLatLong(pos) : pos);
        }
        return value;
    };

    var gmlReadODataPosValue = function (domElement, isGeography) {
        /// <summary>Reads the value of a GML element describing a position or a set of coordinates in an OData spatial property value.</summary>
        /// <param name="property">DOM element for the GML element.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns type="Array">Array of doubles containing the coordinates.</returns>

        var value = [];
        var delims = " \t\r\n";
        var text = xmlInnerText(domElement);

        if (text) {
            var len = text.length;
            var start = 0;
            var end = 0;

            while (end <= len) {
                if (delims.indexOf(text.charAt(end)) !== -1) {
                    var coord = text.substring(start, end);
                    if (coord) {
                        value.push(parseFloat(coord));
                    }
                    start = end + 1;
                }
                end++;
            }
        }

        return isGeography ? gmlSwapLatLong(value) : value;
    };

    var gmlReadODataSpatialValue = function (domElement, isGeography) {
        /// <summary>Reads the value of a GML DOM element a spatial value in an OData XML document.</summary>
        /// <param name="domElement">DOM element.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each position coordinates in the resulting GeoJSON object.
        /// </remarks>
        /// <returns type="Array">Array containing an array of doubles for each coordinate of the polygon.</returns>

        var localName = xmlLocalName(domElement);
        var reader;

        switch (localName) {
            case "Point":
                reader = gmlReadODataPoint;
                break;
            case "Polygon":
                reader = gmlReadODataPolygon;
                break;
            case "LineString":
                reader = gmlReadODataLineString;
                break;
            case "MultiPoint":
                reader = gmlReadODataMultiPoint;
                break;
            case "MultiCurve":
                reader = gmlReadODataMultiLineString;
                break;
            case "MultiSurface":
                reader = gmlReadODataMultiPolygon;
                break;
            case "MultiGeometry":
                reader = gmlReadODataCollection;
                break;
            default:
                throw { message: "Unsupported element: " + localName, element: domElement };
        }

        var value = reader(domElement, isGeography);
        // Read the CRS
        // WCF Data Services qualifies the srsName attribute withing the GML namespace; however
        // other end points might no do this as per the standard.

        var srsName = xmlAttributeValue(domElement, "srsName", gmlXmlNs) ||
                      xmlAttributeValue(domElement, "srsName");

        if (srsName) {
            if (srsName.indexOf(gmlSrsPrefix) !== 0) {
                throw { message: "Unsupported srs name: " + srsName, element: domElement };
            }

            var crsId = srsName.substring(gmlSrsPrefix.length);
            if (crsId) {
                value.crs = {
                    type: "name",
                    properties: {
                        name: "EPSG:" + crsId
                    }
                };
            }
        }
        return value;
    };

    var gmlNewODataSpatialValue = function (dom, value, type, isGeography) {
        /// <summary>Creates a new GML DOM element for the value of an OData spatial property or GeoJSON object.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="value" type="Object">Spatial property value in GeoJSON format.</param>
        /// <param name="type" type="String">String indicating the GeoJSON type of the value to serialize.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in the GeoJSON value is the Longitude and
        ///    will be serialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace for the spatial value. </returns>

        var gmlWriter;

        switch (type) {
            case GEOJSON_POINT:
                gmlWriter = gmlNewODataPoint;
                break;
            case GEOJSON_LINESTRING:
                gmlWriter = gmlNewODataLineString;
                break;
            case GEOJSON_POLYGON:
                gmlWriter = gmlNewODataPolygon;
                break;
            case GEOJSON_MULTIPOINT:
                gmlWriter = gmlNewODataMultiPoint;
                break;
            case GEOJSON_MULTILINESTRING:
                gmlWriter = gmlNewODataMultiLineString;
                break;
            case GEOJSON_MULTIPOLYGON:
                gmlWriter = gmlNewODataMultiPolygon;
                break;
            case GEOJSON_GEOMETRYCOLLECTION:
                gmlWriter = gmlNewODataGeometryCollection;
                break;
            default:
                return null;
        }

        var gml = gmlWriter(dom, value, isGeography);

        // Set the srsName attribute if applicable.
        var crs = value.crs;
        if (crs) {
            if (crs.type === "name") {
                var properties = crs.properties;
                var name = properties && properties.name;
                if (name && name.indexOf("ESPG:") === 0 && name.length > 5) {
                    var crsId = name.substring(5);
                    var srsName = xmlNewAttribute(dom, null, "srsName", gmlPrefix + crsId);
                    xmlAppendChild(gml, srsName);
                }
            }
        }

        return gml;
    };

    var gmlNewODataElement = function (dom, name, children) {
        /// <summary>Creates a new DOM element in the GML namespace.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Local name of the GML element to create.</param>
        /// <param name="children" type="Array">Array containing DOM nodes or string values that will be added as children of the new DOM element.</param>
        /// <returns>New DOM element in the GML namespace.</returns>
        /// <remarks>
        ///    If a value in the children collection is a string, then a new DOM text node is going to be created
        ///    for it and then appended as a child of the new DOM Element.
        /// </remarks>

        return xmlNewElement(dom, gmlXmlNs, xmlQualifiedName(gmlPrefix, name), children);
    };

    var gmlNewODataPosElement = function (dom, coordinates, isGeography) {
        /// <summary>Creates a new GML pos DOM element.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="coordinates" type="Array">Array of doubles describing the coordinates of the pos element.</param>
        /// <param name="isGeography" type="Boolean">Flag indicating if the coordinates use a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first coordinate is the Longitude and
        ///    will be serialized as the second component of the <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New pos DOM element in the GML namespace.</returns>

        var posValue = isArray(coordinates) ? coordinates : [];

        // If using a geographic reference system, then the first coordinate is the longitude and it has to
        // swapped with the latitude.
        posValue = isGeography ? gmlSwapLatLong(posValue) : posValue;

        return gmlNewODataElement(dom, "pos", posValue.join(" "));
    };

    var gmlNewODataLineElement = function (dom, name, coordinates, isGeography) {
        /// <summary>Creates a new GML DOM element representing a line.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Name of the element to create.</param>
        /// <param name="coordinates" type="Array">Array of array of doubles describing the coordinates of the line element.</param>
        /// <param name="isGeography" type="Boolean">Flag indicating if the coordinates use a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates is the Longitude and
        ///    will be serialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace.</returns>

        var element = gmlNewODataElement(dom, name);
        if (isArray(coordinates)) {
            var i, len;
            for (i = 0, len = coordinates.length; i < len; i++) {
                xmlAppendChild(element, gmlNewODataPosElement(dom, coordinates[i], isGeography));
            }

            if (len === 0) {
                xmlAppendChild(element, gmlNewODataElement(dom, "posList"));
            }
        }
        return element;
    };

    var gmlNewODataPointElement = function (dom, coordinates, isGeography) {
        /// <summary>Creates a new GML Point DOM element.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="value" type="Object">GeoJSON Point object.</param>
        /// <param name="isGeography" type="Boolean">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in the GeoJSON value is the Longitude and
        ///    will be serialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace for the GeoJSON Point.</returns>

        return gmlNewODataElement(dom, "Point", gmlNewODataPosElement(dom, coordinates, isGeography));
    };

    var gmlNewODataLineStringElement = function (dom, coordinates, isGeography) {
        /// <summary>Creates a new GML LineString DOM element.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="coordinates" type="Array">Array of array of doubles describing the coordinates of the line element.</param>
        /// <param name="isGeography" type="Boolean">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in the GeoJSON value is the Longitude and
        ///    will be serialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace for the GeoJSON LineString.</returns>

        return gmlNewODataLineElement(dom, "LineString", coordinates, isGeography);
    };

    var gmlNewODataPolygonRingElement = function (dom, name, coordinates, isGeography) {
        /// <summary>Creates a new GML DOM element representing a polygon ring.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Name of the element to create.</param>
        /// <param name="coordinates" type="Array">Array of array of doubles describing the coordinates of the polygon ring.</param>
        /// <param name="isGeography" type="Boolean">Flag indicating if the coordinates use a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates is the Longitude and
        ///    will be serialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace.</returns>

        var ringElement = gmlNewODataElement(dom, name);
        if (isArray(coordinates) && coordinates.length > 0) {
            var linearRing = gmlNewODataLineElement(dom, "LinearRing", coordinates, isGeography);
            xmlAppendChild(ringElement, linearRing);
        }
        return ringElement;
    };

    var gmlNewODataPolygonElement = function (dom, coordinates, isGeography) {
        /// <summary>Creates a new GML Polygon DOM element for a GeoJSON Polygon object.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="coordinates" type="Array">Array of array of array of doubles describing the coordinates of the polygon.</param>
        /// <param name="isGeography" type="Boolean">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in the GeoJSON value is the Longitude and
        ///    will be serialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace.</returns>

        var len = coordinates && coordinates.length;
        var element = gmlNewODataElement(dom, "Polygon");

        if (isArray(coordinates) && len > 0) {
            xmlAppendChild(element, gmlNewODataPolygonRingElement(dom, "exterior", coordinates[0], isGeography));

            var i;
            for (i = 1; i < len; i++) {
                xmlAppendChild(element, gmlNewODataPolygonRingElement(dom, "interior", coordinates[i], isGeography));
            }
        }
        return element;
    };

    var gmlNewODataPoint = function (dom, value, isGeography) {
        /// <summary>Creates a new GML Point DOM element for a GeoJSON Point object.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="value" type="Object">GeoJSON Point object.</param>
        /// <param name="isGeography" type="Boolean">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in the GeoJSON value is the Longitude and
        ///    will be serialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace for the GeoJSON Point.</returns>

        return gmlNewODataPointElement(dom, value.coordinates, isGeography);
    };

    var gmlNewODataLineString = function (dom, value, isGeography) {
        /// <summary>Creates a new GML LineString DOM element for a GeoJSON LineString object.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="value" type="Object">GeoJSON LineString object.</param>
        /// <param name="isGeography" type="Boolean">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in the GeoJSON value is the Longitude and
        ///    will be serialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace for the GeoJSON LineString.</returns>

        return gmlNewODataLineStringElement(dom, value.coordinates, isGeography);
    };

    var gmlNewODataPolygon = function (dom, value, isGeography) {
        /// <summary>Creates a new GML Polygon DOM element for a GeoJSON Polygon object.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="value" type="Object">GeoJSON Polygon object.</param>
        /// <param name="isGeography" type="Boolean">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in the GeoJSON value is the Longitude and
        ///    will be serialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace for the GeoJSON Polygon.</returns>

        return gmlNewODataPolygonElement(dom, value.coordinates, isGeography);
    };

    var gmlNewODataMultiItem = function (dom, name, members, items, itemWriter, isGeography) {
        /// <summary>Creates a new GML DOM element for a composite structure like a multi-point or a multi-geometry.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Name of the element to create.</param>
        /// <param name="items" type="Array">Array of items in the composite structure.</param>
        /// <param name="isGeography" type="Boolean">Flag indicating if the multi-item uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each of the items is the Longitude and
        ///    will be serialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace.</returns>

        var len = items && items.length;
        var element = gmlNewODataElement(dom, name);

        if (isArray(items) && len > 0) {
            var membersElement = gmlNewODataElement(dom, members);
            var i;
            for (i = 0; i < len; i++) {
                xmlAppendChild(membersElement, itemWriter(dom, items[i], isGeography));
            }
            xmlAppendChild(element, membersElement);
        }
        return element;
    };

    var gmlNewODataMultiPoint = function (dom, value, isGeography) {
        /// <summary>Creates a new GML MultiPoint DOM element for a GeoJSON MultiPoint object.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="value" type="Object">GeoJSON MultiPoint object.</param>
        /// <param name="isGeography" type="Boolean">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in the GeoJSON value is the Longitude and
        ///    will be serialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace for the GeoJSON MultiPoint.</returns>

        return gmlNewODataMultiItem(dom, "MultiPoint", "pointMembers", value.coordinates, gmlNewODataPointElement, isGeography);
    };

    var gmlNewODataMultiLineString = function (dom, value, isGeography) {
        /// <summary>Creates a new GML MultiCurve DOM element for a GeoJSON MultiLineString object.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="value" type="Object">GeoJSON MultiLineString object.</param>
        /// <param name="isGeography" type="Boolean">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in the GeoJSON value is the Longitude and
        ///    will be serialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace for the GeoJSON MultiLineString.</returns>

        return gmlNewODataMultiItem(dom, "MultiCurve", "curveMembers", value.coordinates, gmlNewODataLineStringElement, isGeography);
    };

    var gmlNewODataMultiPolygon = function (dom, value, isGeography) {
        /// <summary>Creates a new GML MultiSurface DOM element for a GeoJSON MultiPolygon object.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="value" type="Object">GeoJSON MultiPolygon object.</param>
        /// <param name="isGeography" type="Boolean">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in the GeoJSON value is the Longitude and
        ///    will be serialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace for the GeoJSON MultiPolygon.</returns>

        return gmlNewODataMultiItem(dom, "MultiSurface", "surfaceMembers", value.coordinates, gmlNewODataPolygonElement, isGeography);
    };

    var gmlNewODataGeometryCollectionItem = function (dom, value, isGeography) {
        /// <summary>Creates a new GML element for an item in a geometry collection object.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="item" type="Object">GeoJSON object in the geometry collection.</param>
        /// <param name="isGeography" type="Boolean">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in the GeoJSON value is the Longitude and
        ///    will be serialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace.</returns>

        return gmlNewODataSpatialValue(dom, value, value.type, isGeography);
    };

    var gmlNewODataGeometryCollection = function (dom, value, isGeography) {
        /// <summary>Creates a new GML MultiGeometry DOM element for a GeoJSON GeometryCollection object.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="value" type="Object">GeoJSON GeometryCollection object.</param>
        /// <param name="isGeography" type="Boolean">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in the GeoJSON value is the Longitude and
        ///    will be serialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace for the GeoJSON GeometryCollection.</returns>

        return gmlNewODataMultiItem(dom, "MultiGeometry", "geometryMembers", value.geometries, gmlNewODataGeometryCollectionItem, isGeography);
    };



    var xmlMediaType = "application/xml";

    var ado = http + "docs.oasis-open.org/odata/";      // http://docs.oasis-open.org/odata/
    var adoDs = ado + "ns";                             // http://docs.oasis-open.org/odata/ns

    var edmxNs = adoDs + "/edmx";                       // http://docs.oasis-open.org/odata/ns/edmx
    var edmNs1 = adoDs + "/edm";                        // http://docs.oasis-open.org/odata/ns/edm

    var odataXmlNs = adoDs;                             // http://docs.oasis-open.org/odata/ns
    var odataMetaXmlNs = adoDs + "/metadata";           // http://docs.oasis-open.org/odata/ns/metadata
    var odataRelatedPrefix = adoDs + "/related/";       // http://docs.oasis-open.org/odata/ns/related
    var odataScheme = adoDs + "/scheme";                // http://docs.oasis-open.org/odata/ns/scheme

    var odataPrefix = "d";
    var odataMetaPrefix = "m";

    var createAttributeExtension = function (domNode, useNamespaceURI) {
        /// <summary>Creates an extension object for the specified attribute.</summary>
        /// <param name="domNode">DOM node for the attribute.</param>
        /// <param name="useNamespaceURI" type="Boolean">Flag indicating if the namespaceURI property should be added to the extension object instead of the namespace property.</param>
        /// <remarks>
        ///    The useNamespaceURI flag is used to prevent a breaking change from older versions of datajs in which extension
        ///    objects created for Atom extension attributes have the namespaceURI property instead of the namespace one.
        ///    
        ///    This flag and the namespaceURI property should be deprecated in future major versions of the library.
        /// </remarks>
        /// <returns type="Object">The new extension object.</returns>

        var extension = { name: xmlLocalName(domNode), value: domNode.value };
        extension[useNamespaceURI ? "namespaceURI" : "namespace"] = xmlNamespaceURI(domNode);

        return extension;
    };

    var createElementExtension = function (domNode, useNamespaceURI) {
        /// <summary>Creates an extension object for the specified element.</summary>
        /// <param name="domNode">DOM node for the element.</param>
        /// <param name="useNamespaceURI" type="Boolean">Flag indicating if the namespaceURI property should be added to the extension object instead of the namespace property.</param>
        /// <remarks>
        ///    The useNamespaceURI flag is used to prevent a breaking change from older versions of datajs in which extension
        ///    objects created for Atom extension attributes have the namespaceURI property instead of the namespace one.
        ///    
        ///    This flag and the namespaceURI property should be deprecated in future major versions of the library.
        /// </remarks>
        /// <returns type="Object">The new extension object.</returns>


        var attributeExtensions = [];
        var childrenExtensions = [];

        var i, len;
        var attributes = domNode.attributes;
        for (i = 0, len = attributes.length; i < len; i++) {
            var attr = attributes[i];
            if (xmlNamespaceURI(attr) !== xmlnsNS) {
                attributeExtensions.push(createAttributeExtension(attr, useNamespaceURI));
            }
        }

        var child = domNode.firstChild;
        while (child != null) {
            if (child.nodeType === 1) {
                childrenExtensions.push(createElementExtension(child, useNamespaceURI));
            }
            child = child.nextSibling;
        }

        var extension = {
            name: xmlLocalName(domNode),
            value: xmlInnerText(domNode),
            attributes: attributeExtensions,
            children: childrenExtensions
        };

        extension[useNamespaceURI ? "namespaceURI" : "namespace"] = xmlNamespaceURI(domNode);
        return extension;
    };

    var isCollectionItemElement = function (domElement) {
        /// <summary>Checks whether the domElement is a collection item.</summary>
        /// <param name="domElement">DOM element possibliy represnting a collection item.</param>
        /// <returns type="Boolean">True if the domeElement belongs to the OData metadata namespace and its local name is "element"; false otherwise.</returns>

        return xmlNamespaceURI(domElement) === odataXmlNs && xmlLocalName(domElement) === "element";
    };

    var makePropertyMetadata = function (type, extensions) {
        /// <summary>Creates an object containing property metadata.</summary>
        /// <param type="String" name="type">Property type name.</param>
        /// <param type="Array" name="extensions">Array of attribute extension objects.</param>
        /// <returns type="Object">Property metadata object cotaining type and extensions fields.</returns>

        return { type: type, extensions: extensions };
    };

    var odataInferTypeFromPropertyXmlDom = function (domElement) {
        /// <summary>Infers type of a property based on its xml DOM tree.</summary>
        /// <param name="domElement">DOM element for the property.</param>
        /// <returns type="String">Inferred type name; null if the type cannot be determined.</returns>

        if (xmlFirstChildElement(domElement, gmlXmlNs)) {
            return EDM_GEOMETRY;
        }

        var firstChild = xmlFirstChildElement(domElement, odataXmlNs);
        if (!firstChild) {
            return EDM_STRING;
        }

        if (isCollectionItemElement(firstChild)) {
            var sibling = xmlSiblingElement(firstChild, odataXmlNs);
            if (sibling && isCollectionItemElement(sibling)) {
                // More than one <element> tag have been found, it can be safely assumed that this is a collection property.
                return "Collection()";
            }
        }

        return null;
    };

    var xmlReadODataPropertyAttributes = function (domElement) {
        /// <summary>Reads the attributes of a property DOM element in an OData XML document.</summary>
        /// <param name="domElement">DOM element for the property.</param>
        /// <returns type="Object">Object containing the property type, if it is null, and its attribute extensions.</returns>

        var type = null;
        var isNull = false;
        var extensions = [];

        xmlAttributes(domElement, function (attribute) {
            var nsURI = xmlNamespaceURI(attribute);
            var localName = xmlLocalName(attribute);
            var value = xmlNodeValue(attribute);

            if (nsURI === odataMetaXmlNs) {
                if (localName === "null") {
                    isNull = (value.toLowerCase() === "true");
                    return;
                }

                if (localName === "type") {
                    type = value;
                    return;
                }
            }

            if (nsURI !== xmlNS && nsURI !== xmlnsNS) {
                extensions.push(createAttributeExtension(attribute, true));
                return;
            }
        });

        return { type: (!type && isNull ? EDM_STRING : type), isNull: isNull, extensions: extensions };
    };

    var xmlReadODataProperty = function (domElement) {
        /// <summary>Reads a property DOM element in an OData XML document.</summary>
        /// <param name="domElement">DOM element for the property.</param>
        /// <returns type="Object">Object with name, value, and metadata for the property.</returns>

        if (xmlNamespaceURI(domElement) !== odataXmlNs) {
            // domElement is not a proprety element because it is not in the odata xml namespace.
            return null;
        }

        var propertyName = xmlLocalName(domElement);
        var propertyAttributes = xmlReadODataPropertyAttributes(domElement);

        var propertyIsNull = propertyAttributes.isNull;
        var propertyType = propertyAttributes.type;

        var propertyMetadata = makePropertyMetadata(propertyType, propertyAttributes.extensions);
        var propertyValue = propertyIsNull ? null : xmlReadODataPropertyValue(domElement, propertyType, propertyMetadata);

        return { name: propertyName, value: propertyValue, metadata: propertyMetadata };
    };

    var xmlReadODataPropertyValue = function (domElement, propertyType, propertyMetadata) {
        /// <summary>Reads the value of a property in an OData XML document.</summary>
        /// <param name="domElement">DOM element for the property.</param>
        /// <param name="propertyType" type="String">Property type name.</param>
        /// <param name="propertyMetadata" type="Object">Object that will store metadata about the property.</param>
        /// <returns>Property value.</returns>

        if (!propertyType) {
            propertyType = odataInferTypeFromPropertyXmlDom(domElement);
            propertyMetadata.type = propertyType;
        }

        var isGeograhpyType = isGeographyEdmType(propertyType);
        if (isGeograhpyType || isGeometryEdmType(propertyType)) {
            return xmlReadODataSpatialPropertyValue(domElement, propertyType, isGeograhpyType);
        }

        if (isPrimitiveEdmType(propertyType)) {
            return xmlReadODataEdmPropertyValue(domElement, propertyType);
        }

        if (isCollectionType(propertyType)) {
            return xmlReadODataCollectionPropertyValue(domElement, propertyType, propertyMetadata);
        }

        return xmlReadODataComplexPropertyValue(domElement, propertyType, propertyMetadata);
    };

    var xmlReadODataSpatialPropertyValue = function (domElement, propertyType, isGeography) {
        /// <summary>Reads the value of an spatial property in an OData XML document.</summary>
        /// <param name="property">DOM element for the spatial property.</param>
        /// <param name="propertyType" type="String">Property type name.</param>
        /// <param name="isGeography" type="Boolean" Optional="True">Flag indicating if the value uses a geographic reference system or not.<param>
        /// <remarks>
        ///    When using a geographic reference system, the first component of all the coordinates in each <pos> element in the GML DOM tree is the Latitude and
        ///    will be deserialized as the second component of each <pos> element in the GML DOM tree.
        /// </remarks>
        /// <returns>Spatial property value in GeoJSON format.</returns>

        var gmlRoot = xmlFirstChildElement(domElement, gmlXmlNs);

        var value = gmlReadODataSpatialValue(gmlRoot, isGeography);
        value.__metadata = { type: propertyType };
        return value;
    };

    var xmlReadODataEdmPropertyValue = function (domNode, propertyType) {
        /// <summary>Reads the value of an EDM property in an OData XML document.</summary>
        /// <param name="donNode">DOM node for the EDM property.</param>
        /// <param name="propertyType" type="String">Property type name.</param>
        /// <returns>EDM property value.</returns>

        var propertyValue = xmlNodeValue(domNode) || "";

        switch (propertyType) {
            case EDM_BOOLEAN:
                return parseBool(propertyValue);
            case EDM_BINARY:
            case EDM_DECIMAL:
            case EDM_GUID:
            case EDM_INT64:
            case EDM_STRING:
                return propertyValue;
            case EDM_BYTE:
            case EDM_INT16:
            case EDM_INT32:
            case EDM_SBYTE:
                return parseInt10(propertyValue);
            case EDM_DOUBLE:
            case EDM_SINGLE:
                return parseFloat(propertyValue);
            case EDM_TIME:
                return parseDuration(propertyValue);
            case EDM_DATETIME:
                return parseDateTime(propertyValue);
            case EDM_DATETIMEOFFSET:
                return parseDateTimeOffset(propertyValue);
        }

        return propertyValue;
    };

    var xmlReadODataComplexPropertyValue = function(domElement, propertyType, propertyMetadata) {
        /// <summary>Reads the value of a complex type property in an OData XML document.</summary>
        /// <param name="property">DOM element for the complex type property.</param>
        /// <param name="propertyType" type="String">Property type name.</param>
        /// <param name="propertyMetadata" type="Object">Object that will store metadata about the property.</param>
        /// <returns type="Object">Complex type property value.</returns>

        var propertyValue = { __metadata: { type: propertyType } };
        xmlChildElements(domElement, function(child) {
            var childProperty = xmlReadODataProperty(child);
            var childPropertyName = childProperty.name;

            propertyMetadata.properties = propertyMetadata.properties || {};
            propertyMetadata.properties[childPropertyName] = childProperty.metadata;
            propertyValue[childPropertyName] = childProperty.value;
        });

        return propertyValue;
    };

    var xmlReadODataCollectionPropertyValue = function (domElement, propertyType, propertyMetadata) {
        /// <summary>Reads the value of a collection property in an OData XML document.</summary>
        /// <param name="property">DOM element for the collection property.</param>
        /// <param name="propertyType" type="String">Property type name.</param>
        /// <param name="propertyMetadata" type="Object">Object that will store metadata about the property.</param>
        /// <returns type="Object">Collection property value.</returns>

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

        xmlChildElements(domElement, function (child) {
            if (isCollectionItemElement(child)) {
                var itemAttributes = xmlReadODataPropertyAttributes(child);
                var itemExtensions = itemAttributes.extensions;
                var itemType = itemAttributes.type || collectionType;
                var itemMetadata = makePropertyMetadata(itemType, itemExtensions);

                var item = xmlReadODataPropertyValue(child, itemType, itemMetadata);

                items.push(item);
                itemsMetadata.push(itemMetadata);
            }
        });

        return { __metadata: { type: propertyType === "Collection()" ? null : propertyType }, results: items };
    };

    var readODataXmlDocument = function (xmlRoot, baseURI) {
        /// <summary>Reads an OData link(s) producing an object model in return.</summary>
        /// <param name="xmlRoot">Top-level element to read.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the XML payload.</param>
        /// <returns type="Object">The object model representing the specified element.</returns>

        if (xmlNamespaceURI(xmlRoot) === odataXmlNs) {
            baseURI = xmlBaseURI(xmlRoot, baseURI);
            var localName = xmlLocalName(xmlRoot);

            if (localName === "links") {
                return readLinks(xmlRoot, baseURI);
            }
            if (localName === "uri") {
                return readUri(xmlRoot, baseURI);
            }
        }
        return undefined;
    };

    var readLinks = function (linksElement, baseURI) {
        /// <summary>Deserializes an OData XML links element.</summary>
        /// <param name="linksElement">XML links element.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the XML payload.</param>
        /// <returns type="Object">A new object representing the links collection.</returns>

        var uris = [];

        xmlChildElements(linksElement, function (child) {
            if (xmlLocalName(child) === "uri" && xmlNamespaceURI(child) === odataXmlNs) {
                uris.push(readUri(child, baseURI));
            }
        });

        return { results: uris };
    };

    var readUri = function (uriElement, baseURI) {
        /// <summary>Deserializes an OData XML uri element.</summary>
        /// <param name="uriElement">XML uri element.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the XML payload.</param>
        /// <returns type="Object">A new object representing the uri.</returns>

        var uri = xmlInnerText(uriElement) || "";
        return { uri: normalizeURI(uri, baseURI) };
    };

    var xmlODataInferSpatialValueGeoJsonType = function (value, edmType) {
        /// <summary>Infers the GeoJSON type from the spatial property value and the edm type name.</summary>
        /// <param name="value" type="Object">Spatial property value in GeoJSON format.</param>
        /// <param name="edmType" type="String" mayBeNull="true" optional="true">Spatial property edm type.<param>
        /// <remarks>
        ///   If the edmType parameter is null, undefined, "Edm.Geometry" or "Edm.Geography", then the function returns
        ///   the GeoJSON type indicated by the value's type property.
        ///
        ///   If the edmType parameter is specified or is not one of the base spatial types, then it is used to
        ///   determine the GeoJSON type and the value's type property is ignored.
        /// </remarks>
        /// <returns>New DOM element in the GML namespace for the spatial value. </returns>

        if (edmType === EDM_GEOMETRY || edmType === EDM_GEOGRAPHY) {
            return value && value.type;
        }

        if (edmType === EDM_GEOMETRY_POINT || edmType === EDM_GEOGRAPHY_POINT) {
            return GEOJSON_POINT;
        }

        if (edmType === EDM_GEOMETRY_LINESTRING || edmType === EDM_GEOGRAPHY_LINESTRING) {
            return GEOJSON_LINESTRING;
        }

        if (edmType === EDM_GEOMETRY_POLYGON || edmType === EDM_GEOGRAPHY_POLYGON) {
            return GEOJSON_POLYGON;
        }

        if (edmType === EDM_GEOMETRY_COLLECTION || edmType === EDM_GEOGRAPHY_COLLECTION) {
            return GEOJSON_GEOMETRYCOLLECTION;
        }

        if (edmType === EDM_GEOMETRY_MULTIPOLYGON || edmType === EDM_GEOGRAPHY_MULTIPOLYGON) {
            return GEOJSON_MULTIPOLYGON;
        }

        if (edmType === EDM_GEOMETRY_MULTILINESTRING || edmType === EDM_GEOGRAPHY_MULTILINESTRING) {
            return GEOJSON_MULTILINESTRING;
        }

        if (edmType === EDM_GEOMETRY_MULTIPOINT || edmType === EDM_GEOGRAPHY_MULTIPOINT) {
            return GEOJSON_MULTIPOINT;
        }

        return null;
    };

    var xmlNewODataMetaElement = function (dom, name, children) {
        /// <summary>Creates a new DOM element in the OData metadata namespace.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Local name of the OData metadata element to create.</param>
        /// <param name="children" type="Array">Array containing DOM nodes or string values that will be added as children of the new DOM element.</param>
        /// <returns>New DOM element in the OData metadata namespace.</returns>
        /// <remarks>
        ///    If a value in the children collection is a string, then a new DOM text node is going to be created
        ///    for it and then appended as a child of the new DOM Element.
        /// </remarks>

        return xmlNewElement(dom, odataMetaXmlNs, xmlQualifiedName(odataMetaPrefix, name), children);
    };

    var xmlNewODataMetaAttribute = function (dom, name, value) {
        /// <summary>Creates a new DOM attribute in the odata namespace.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Local name of the OData attribute to create.</param>
        /// <param name="value">Attribute value.</param>
        /// <returns>New DOM attribute in the odata namespace.</returns>

        return xmlNewAttribute(dom, odataMetaXmlNs, xmlQualifiedName(odataMetaPrefix, name), value);
    };

    var xmlNewODataElement = function (dom, name, children) {
        /// <summary>Creates a new DOM element in the OData namespace.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Local name of the OData element to create.</param>
        /// <param name="children" type="Array">Array containing DOM nodes or string values that will be added as children of the new DOM element.</param>
        /// <returns>New DOM element in the OData namespace.</returns>
        /// <remarks>
        ///    If a value in the children collection is a string, then a new DOM text node is going to be created
        ///    for it and then appended as a child of the new DOM Element.
        /// </remarks>

        return xmlNewElement(dom, odataXmlNs, xmlQualifiedName(odataPrefix, name), children);
    };

    var xmlNewODataPrimitiveValue = function (value, typeName) {
        /// <summary>Returns the string representation of primitive value for an OData XML document.</summary>
        /// <param name="value">Primivite value to format.</param>
        /// <param name="typeName" type="String" optional="true">Type name of the primitive value.</param>
        /// <returns type="String">Formatted primitive value.</returns>

        if (typeName === EDM_DATETIME || typeName === EDM_DATETIMEOFFSET || isDate(value)) {
            return formatDateTimeOffset(value);
        }
        if (typeName === EDM_TIME) {
            return formatDuration(value);
        }
        return value.toString();
    };

    var xmlNewODataElementInfo = function (domElement, dataServiceVersion) {
        /// <summary>Creates an object that represents a new DOM element for an OData XML document and the data service version it requires.</summary>
        /// <param name="domElement">New DOM element for an OData XML document.</param>
        /// <param name="dataServiceVersion" type="String">Required data service version by the new DOM element.</param>
        /// <returns type="Object">Object containing new DOM element and its required data service version.</returns>

        return { element: domElement, dsv: dataServiceVersion };
    };

    var xmlNewODataProperty = function (dom, name, typeName, children) {
        /// <summary>Creates a new DOM element for an entry property in an OData XML document.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Property name.</param>
        /// <param name="typeName" type="String" optional="true">Property type name.</param>
        /// <param name="children" type="Array">Array containing DOM nodes or string values that will be added as children of the new DOM element.</param>
        /// <remarks>
        ///    If a value in the children collection is a string, then a new DOM text node is going to be created
        ///    for it and then appended as a child of the new DOM Element.
        /// </remarks>
        /// <returns>New DOM element in the OData namespace for the entry property.</returns>

        var typeAttribute = typeName ? xmlNewODataMetaAttribute(dom, "type", typeName) : null;
        var property = xmlNewODataElement(dom, name, typeAttribute);
        return xmlAppendChildren(property, children);
    };

    var xmlNewODataEdmProperty = function (dom, name, value, typeName) {
        /// <summary>Creates a new DOM element for an EDM property in an OData XML document.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Property name.</param>
        /// <param name="value">Property value.</param>
        /// <param name="typeName" type="String" optional="true">Property type name.</param>
        /// <returns type="Object">
        ///     Object containing the new DOM element in the OData namespace for the EDM property and the
        ///     required data service version for this property.
        /// </returns>

        var propertyValue = xmlNewODataPrimitiveValue(value, typeName);
        var property = xmlNewODataProperty(dom, name, typeName, propertyValue);
        return xmlNewODataElementInfo(property, /*dataServiceVersion*/"4.0");
    };

    var xmlNewODataNullProperty = function (dom, name, typeName, model) {
        /// <summary>Creates a new DOM element for a null property in an OData XML document.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Property name.</param>
        /// <param name="typeName" type="String" optional="true">Property type name.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <remarks>
        ///     If no typeName is specified, then it will be assumed that this is a primitive type property.
        /// </remarks>
        /// <returns type="Object">
        ///     Object containing the new DOM element in the OData namespace for the null property and the 
        ///     required data service version for this property.
        /// </returns>

        var nullAttribute = xmlNewODataMetaAttribute(dom, "null", "true");
        var property = xmlNewODataProperty(dom, name, typeName, nullAttribute);
        var dataServiceVersion = lookupComplexType(typeName, model) ? "2.0" : "1.0";

        return xmlNewODataElementInfo(property, dataServiceVersion);
    };

    var xmlNewODataCollectionProperty = function (dom, name, value, typeName, collectionMetadata, collectionModel, model) {
        /// <summary>Creates a new DOM element for a collection property in an OData XML document.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Property name.</param>
        /// <param name="value">Property value either as an array or an object representing a collection in the library's internal representation.</param>
        /// <param name="typeName" type="String" optional="true">Property type name.</param>
        /// <param name="collectionMetadata" type="Object" optional="true">Object containing metadata about the collection property.</param>
        /// <param name="collectionModel" type="Object" optional="true">Object describing the collection property in an OData conceptual schema.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <returns type="Object">
        ///     Object containing the new DOM element in the OData namespace for the collection property and the
        ///     required data service version for this property.
        /// </returns>

        var itemTypeName = getCollectionType(typeName);
        var items = isArray(value) ? value : value.results;
        var itemMetadata = typeName ? { type: itemTypeName} : {};
        itemMetadata.properties = collectionMetadata.properties;

        var xmlProperty = xmlNewODataProperty(dom, name, itemTypeName ? typeName : null);

        var i, len;
        for (i = 0, len = items.length; i < len; i++) {
            var itemValue = items[i];
            var item = xmlNewODataDataElement(dom, "element", itemValue, itemMetadata, collectionModel, model);

            xmlAppendChild(xmlProperty, item.element);
        }
        return xmlNewODataElementInfo(xmlProperty, /*dataServiceVersion*/"4.0");
    };

    var xmlNewODataComplexProperty = function (dom, name, value, typeName, propertyMetadata, propertyModel, model) {
        /// <summary>Creates a new DOM element for a complex type property in an OData XML document.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Property name.</param>
        /// <param name="value">Property value as an object in the library's internal representation.</param>
        /// <param name="typeName" type="String" optional="true">Property type name.</param>
        /// <param name="propertyMetadata" type="Object" optional="true">Object containing metadata about the complex type property.</param>
        /// <param name="propertyModel" type="Object" optional="true">Object describing the complex type property in an OData conceptual schema.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <returns type="Object">
        ///     Object containing the new DOM element in the OData namespace for the complex type property and the
        ///     required data service version for this property.
        /// </returns>

        var xmlProperty = xmlNewODataProperty(dom, name, typeName);
        var complexTypePropertiesMetadata = propertyMetadata.properties || {};
        var complexTypeModel = lookupComplexType(typeName, model) || {};

        var dataServiceVersion = "4.0";

        for (var key in value) {
            if (key !== "__metadata") {
                var memberValue = value[key];
                var memberModel = lookupProperty(complexTypeModel.property, key);
                var memberMetadata = complexTypePropertiesMetadata[key] || {};
                var member = xmlNewODataDataElement(dom, key, memberValue, memberMetadata, memberModel, model);

                dataServiceVersion = maxVersion(dataServiceVersion, member.dsv);
                xmlAppendChild(xmlProperty, member.element);
            }
        }
        return xmlNewODataElementInfo(xmlProperty, dataServiceVersion);
    };

    var xmlNewODataSpatialProperty = function (dom, name, value, typeName, isGeography) {
        /// <summary>Creates a new DOM element for an EDM spatial property in an OData XML document.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Property name.</param>
        /// <param name="value" type="Object">GeoJSON object containing the property value.</param>
        /// <param name="typeName" type="String" optional="true">Property type name.</param>
        /// <returns type="Object">
        ///     Object containing the new DOM element in the OData namespace for the EDM property and the
        ///     required data service version for this property.
        /// </returns>

        var geoJsonType = xmlODataInferSpatialValueGeoJsonType(value, typeName);

        var gmlRoot = gmlNewODataSpatialValue(dom, value, geoJsonType, isGeography);
        var xmlProperty = xmlNewODataProperty(dom, name, typeName, gmlRoot);

        return xmlNewODataElementInfo(xmlProperty, "4.0");
    };

    var xmlNewODataDataElement = function (dom, name, value, dataItemMetadata, dataItemModel, model) {
        /// <summary>Creates a new DOM element for a data item in an entry, complex property, or collection property.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Data item name.</param>
        /// <param name="value" optional="true" mayBeNull="true">Value of the data item, if any.</param>
        /// <param name="dataItemMetadata" type="Object" optional="true">Object containing metadata about 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>
        /// <returns type="Object">
        ///     Object containing the new DOM element in the appropriate namespace for the data item and the
        ///     required data service version for it.
        /// </returns>

        var typeName = dataItemTypeName(value, dataItemMetadata, dataItemModel);
        if (isPrimitive(value)) {
            return xmlNewODataEdmProperty(dom, name, value, typeName || EDM_STRING);
        }

        var isGeography = isGeographyEdmType(typeName);
        if (isGeography || isGeometryEdmType(typeName)) {
            return xmlNewODataSpatialProperty(dom, name, value, typeName, isGeography);
        }

        if (isCollection(value, typeName)) {
            return xmlNewODataCollectionProperty(dom, name, value, typeName, dataItemMetadata, dataItemModel, model);
        }

        if (isNamedStream(value)) {
            return null;
        }

        // This may be a navigation property.
        var navPropKind = navigationPropertyKind(value, dataItemModel);
        if (navPropKind !== null) {
            return null;
        }

        if (value === null) {
            return xmlNewODataNullProperty(dom, name, typeName);
        }

        return xmlNewODataComplexProperty(dom, name, value, typeName, dataItemMetadata, dataItemModel, model);
    };

    var odataNewLinkDocument = function (data) {
        /// <summary>Writes the specified data into an OData XML document.</summary>
        /// <param name="data">Data to write.</param>
        /// <returns>The root of the DOM tree built.</returns>

        if (data && isObject(data)) {
            var dom = xmlDom();
            return xmlAppendChild(dom, xmlNewODataElement(dom, "uri", data.uri));
        }
        // Allow for undefined to be returned.
    };

    var xmlParser = function (handler, text) {
        /// <summary>Parses an OData XML document.</summary>
        /// <param name="handler">This handler.</param>
        /// <param name="text" type="String">Document text.</param>
        /// <returns>An object representation of the document; undefined if not applicable.</returns>

        if (text) {
            var doc = xmlParse(text);
            var root = xmlFirstChildElement(doc);
            if (root) {
                return readODataXmlDocument(root);
            }
        }

        // Allow for undefined to be returned.
    };

    var xmlSerializer = function (handler, data, context) {
        /// <summary>Serializes an OData XML object into a document.</summary>
        /// <param name="handler">This handler.</param>
        /// <param name="data" type="Object">Representation of feed or entry.</param>
        /// <param name="context" type="Object">Object with parsing context.</param>
        /// <returns>A text representation of the data object; undefined if not applicable.</returns>

        var cType = context.contentType = context.contentType || contentType(xmlMediaType);
        if (cType && cType.mediaType === xmlMediaType) {
            return xmlSerialize(odataNewLinkDocument(data));
        }
        return undefined;
    };

    odata.xmlHandler = handler(xmlParser, xmlSerializer, xmlMediaType, MAX_DATA_SERVICE_VERSION);



    var atomPrefix = "a";

    var atomXmlNs = w3org + "2005/Atom";                    // http://www.w3.org/2005/Atom
    var appXmlNs = w3org + "2007/app";                      // http://www.w3.org/2007/app

    var odataEditMediaPrefix = adoDs + "/edit-media/";        // http://docs.oasis-open.org/odata/ns/edit-media
    var odataMediaResourcePrefix = adoDs + "/mediaresource/"; // http://docs.oasis-open.org/odata/ns/mediaresource
    var odataRelatedLinksPrefix = adoDs + "/relatedlinks/";   // http://docs.oasis-open.org/odata/ns/relatedlinks

    var atomAcceptTypes = ["application/atom+xml", "application/atomsvc+xml", "application/xml"];
    var atomMediaType = atomAcceptTypes[0];

    // These are the namespaces that are not considered ATOM extension namespaces.
    var nonExtensionNamepaces = [atomXmlNs, appXmlNs, xmlNS, xmlnsNS];

    // These are entity property mapping paths that have well-known paths.
    var knownCustomizationPaths = {
        SyndicationAuthorEmail: "author/email",
        SyndicationAuthorName: "author/name",
        SyndicationAuthorUri: "author/uri",
        SyndicationContributorEmail: "contributor/email",
        SyndicationContributorName: "contributor/name",
        SyndicationContributorUri: "contributor/uri",
        SyndicationPublished: "published",
        SyndicationRights: "rights",
        SyndicationSummary: "summary",
        SyndicationTitle: "title",
        SyndicationUpdated: "updated"
    };

    var expandedFeedCustomizationPath = function (path) {
        /// <summary>Returns an expanded customization path if it's well-known.</summary>
        /// <param name="path" type="String">Path to expand.</param>
        /// <returns type="String">Expanded path or just 'path' otherwise.</returns>

        return knownCustomizationPaths[path] || path;
    };

    var isExtensionNs = function (nsURI) {
        /// <summary>Checks whether the specified namespace is an extension namespace to ATOM.</summary>
        /// <param type="String" name="nsURI">Namespace to check.</param>
        /// <returns type="Boolean">true if nsURI is an extension namespace to ATOM; false otherwise.</returns>

        return !(contains(nonExtensionNamepaces, nsURI));
    };

    var atomFeedCustomization = function (customizationModel, entityType, model, propertyName, suffix) {
        /// <summary>Creates an object describing a feed customization that was delcared in an OData conceptual schema.</summary>
        /// <param name="customizationModel" type="Object">Object describing the customization delcared in the conceptual schema.</param>
        /// <param name="entityType" type="Object">Object describing the entity type that owns the customization in an OData conceputal schema.</param>
        /// <param name="model" type="Object">Object describing an OData conceptual schema.</param>
        /// <param name="propertyName" type="String" optional="true">Name of the property to which this customization applies.</param>
        /// <param name="suffix" type="String" optional="true">Suffix to feed customization properties in the conceptual schema.</param>
        /// <returns type="Object">Object that describes an applicable feed customization.</returns>

        suffix = suffix || "";
        var targetPath = customizationModel["FC_TargetPath" + suffix];
        if (!targetPath) {
            return null;
        }

        var sourcePath = customizationModel["FC_SourcePath" + suffix];
        var targetXmlPath = expandedFeedCustomizationPath(targetPath);

        var propertyPath = propertyName ? propertyName + (sourcePath ? "/" + sourcePath : "") : sourcePath;
        var propertyType = propertyPath && lookupPropertyType(model, entityType, propertyPath);
        var nsURI = customizationModel["FC_NsUri" + suffix] || null;
        var nsPrefix = customizationModel["FC_NsPrefix" + suffix] || null;
        var keepinContent = customizationModel["FC_KeepInContent" + suffix] || "";

        if (targetPath !== targetXmlPath) {
            nsURI = atomXmlNs;
            nsPrefix = atomPrefix;
        }

        return {
            contentKind: customizationModel["FC_ContentKind" + suffix],
            keepInContent: keepinContent.toLowerCase() === "true",
            nsPrefix: nsPrefix,
            nsURI: nsURI,
            propertyPath: propertyPath,
            propertyType: propertyType,
            entryPath: targetXmlPath
        };
    };

    var atomApplyAllFeedCustomizations = function (entityType, model, callback) {
        /// <summary>Gets all the feed customizations that have to be applied to an entry as per the enity type declared in an OData conceptual schema.</summary>
        /// <param name="entityType" type="Object">Object describing an entity type in a conceptual schema.</param>
        /// <param name="model" type="Object">Object describing an OData conceptual schema.</param>
        /// <param name="callback" type="Function">Callback function to be invoked for each feed customization that needs to be applied.</param>

        var customizations = [];
        while (entityType) {
            var sourcePath = entityType.FC_SourcePath;
            var customization = atomFeedCustomization(entityType, entityType, model);
            if (customization) {
                callback(customization);
            }

            var properties = entityType.property || [];
            var i, len;
            for (i = 0, len = properties.length; i < len; i++) {
                var property = properties[i];
                var suffixCounter = 0;
                var suffix = "";

                while (customization = atomFeedCustomization(property, entityType, model, property.name, suffix)) {
                    callback(customization);
                    suffixCounter++;
                    suffix = "_" + suffixCounter;
                }
            }
            entityType = lookupEntityType(entityType.baseType, model);
        }
        return customizations;
    };

    var atomReadExtensionAttributes = function (domElement) {
        /// <summary>Reads ATOM extension attributes (any attribute not in the Atom namespace) from a DOM element.</summary>
        /// <param name="domElement">DOM element with zero or more extension attributes.</param>
        /// <returns type="Array">An array of extension attribute representations.</returns>

        var extensions = [];
        xmlAttributes(domElement, function (attribute) {
            var nsURI = xmlNamespaceURI(attribute);
            if (isExtensionNs(nsURI)) {
                extensions.push(createAttributeExtension(attribute, true));
            }
        });
        return extensions;
    };

    var atomReadExtensionElement = function (domElement) {
        /// <summary>Reads an ATOM extension element (an element not in the ATOM namespaces).</summary>
        /// <param name="domElement">DOM element not part of the atom namespace.</param>
        /// <returns type="Object">Object representing the extension element.</returns>

        return createElementExtension(domElement, /*addNamespaceURI*/true);
    };

    var atomReadDocument = function (domElement, baseURI, model) {
        /// <summary>Reads an ATOM entry, feed or service document, producing an object model in return.</summary>
        /// <param name="domElement">Top-level ATOM DOM element to read.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the ATOM document.</param>
        /// <param name="model" type="Object">Object that describes the conceptual schema.</param>
        /// <returns type="Object">The object model representing the specified element, undefined if the top-level element is not part of the ATOM specification.</returns>

        var nsURI = xmlNamespaceURI(domElement);
        var localName = xmlLocalName(domElement);

        // Handle service documents.
        if (nsURI === appXmlNs && localName === "service") {
            return atomReadServiceDocument(domElement, baseURI);
        }

        // Handle feed and entry elements.
        if (nsURI === atomXmlNs) {
            if (localName === "feed") {
                return atomReadFeed(domElement, baseURI, model);
            }
            if (localName === "entry") {
                return atomReadEntry(domElement, baseURI, model);
            }
        }

        // Allow undefined to be returned.
    };

    var atomReadAdvertisedActionOrFunction = function (domElement, baseURI) {
        /// <summary>Reads the DOM element for an action or a function in an OData Atom document.</summary>
        /// <param name="domElement">DOM element to read.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing the action or function target url.</param>
        /// <returns type="Object">Object with title, target, and metadata fields.</returns>

        var extensions = [];
        var result = { extensions: extensions };
        xmlAttributes(domElement, function (attribute) {
            var localName = xmlLocalName(attribute);
            var nsURI = xmlNamespaceURI(attribute);
            var value = xmlNodeValue(attribute);

            if (nsURI === null) {
                if (localName === "title" || localName === "metadata") {
                    result[localName] = value;
                    return;
                }
                if (localName === "target") {
                    result.target = normalizeURI(value, xmlBaseURI(domElement, baseURI));
                    return;
                }
            }

            if (isExtensionNs(nsURI)) {
                extensions.push(createAttributeExtension(attribute, true));
            }
        });
        return result;
    };

    var atomReadAdvertisedAction = function (domElement, baseURI, parentMetadata) {
        /// <summary>Reads the DOM element for an action in an OData Atom document.</summary>
        /// <param name="domElement">DOM element to read.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing the action or target url.</param>
        /// <param name="parentMetadata" type="Object">Object to update with the action metadata.</param>

        var actions = parentMetadata.actions = parentMetadata.actions || [];
        actions.push(atomReadAdvertisedActionOrFunction(domElement, baseURI));
    };

    var atomReadAdvertisedFunction = function (domElement, baseURI, parentMetadata) {
        /// <summary>Reads the DOM element for an action in an OData Atom document.</summary>
        /// <param name="domElement">DOM element to read.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing the action or target url.</param>
        /// <param name="parentMetadata" type="Object">Object to update with the action metadata.</param>

        var functions = parentMetadata.functions = parentMetadata.functions || [];
        functions.push(atomReadAdvertisedActionOrFunction(domElement, baseURI));
    };

    var atomReadFeed = function (domElement, baseURI, model) {
        /// <summary>Reads a DOM element for an ATOM feed, producing an object model in return.</summary>
        /// <param name="domElement">ATOM feed DOM element.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the ATOM feed.</param>
        /// <param name="model">Metadata that describes the conceptual schema.</param>
        /// <returns type="Object">A new object representing the feed.</returns>

        var extensions = atomReadExtensionAttributes(domElement);
        var feedMetadata = { feed_extensions: extensions };
        var results = [];

        var feed = { __metadata: feedMetadata, results: results };

        baseURI = xmlBaseURI(domElement, baseURI);

        xmlChildElements(domElement, function (child) {
            var nsURI = xmlNamespaceURI(child);
            var localName = xmlLocalName(child);

            if (nsURI === odataMetaXmlNs) {
                if (localName === "count") {
                    feed.__count = parseInt(xmlInnerText(child), 10);
                    return;
                }
                if (localName === "action") {
                    atomReadAdvertisedAction(child, baseURI, feedMetadata);
                    return;
                }
                if (localName === "function") {
                    atomReadAdvertisedFunction(child, baseURI, feedMetadata);
                    return;
                }
            }

            if (isExtensionNs(nsURI)) {
                extensions.push(createElementExtension(child));
                return;
            }

            // The element should belong to the ATOM namespace.

            if (localName === "entry") {
                results.push(atomReadEntry(child, baseURI, model));
                return;
            }
            if (localName === "link") {
                atomReadFeedLink(child, feed, baseURI);
                return;
            }
            if (localName === "id") {
                feedMetadata.uri = normalizeURI(xmlInnerText(child), baseURI);
                feedMetadata.uri_extensions = atomReadExtensionAttributes(child);
                return;
            }
            if (localName === "title") {
                feedMetadata.title = xmlInnerText(child) || "";
                feedMetadata.title_extensions = atomReadExtensionAttributes(child);
                return;
            }
        });

        return feed;
    };

    var atomReadFeedLink = function (domElement, feed, baseURI) {
        /// <summary>Reads an ATOM link DOM element for a feed.</summary>
        /// <param name="domElement">ATOM link DOM element.</param>
        /// <param name="feed">Feed object to be annotated with the link data.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>

        var link = atomReadLink(domElement, baseURI);
        var href = link.href;
        var rel = link.rel;
        var extensions = link.extensions;
        var metadata = feed.__metadata;

        if (rel === "next") {
            feed.__next = href;
            metadata.next_extensions = extensions;
            return;
        }
        if (rel === "self") {
            metadata.self = href;
            metadata.self_extensions = extensions;
            return;
        }
    };

    var atomReadLink = function (domElement, baseURI) {
        /// <summary>Reads an ATOM link DOM element.</summary>
        /// <param name="linkElement">DOM element to read.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing the link href.</param>
        /// <returns type="Object">A link element representation.</returns>

        baseURI = xmlBaseURI(domElement, baseURI);

        var extensions = [];
        var link = { extensions: extensions, baseURI: baseURI };

        xmlAttributes(domElement, function (attribute) {
            var nsURI = xmlNamespaceURI(attribute);
            var localName = xmlLocalName(attribute);
            var value = attribute.value;

            if (localName === "href") {
                link.href = normalizeURI(value, baseURI);
                return;
            }
            if (localName === "type" || localName === "rel") {
                link[localName] = value;
                return;
            }

            if (isExtensionNs(nsURI)) {
                extensions.push(createAttributeExtension(attribute, true));
            }
        });

        if (!link.href) {
            throw { error: "href attribute missing on link element", element: domElement };
        }

        return link;
    };

    var atomGetObjectValueByPath = function (path, item) {
        /// <summary>Gets a slashed path value from the specified item.</summary>
        /// <param name="path" type="String">Property path to read ('/'-separated).</param>
        /// <param name="item" type="Object">Object to get value from.</param>
        /// <returns>The property value, possibly undefined if any path segment is missing.</returns>

        // Fast path.
        if (path.indexOf('/') === -1) {
            return item[path];
        } else {
            var parts = path.split('/');
            var i, len;
            for (i = 0, len = parts.length; i < len; i++) {
                // Avoid traversing a null object.
                if (item === null) {
                    return undefined;
                }

                item = item[parts[i]];
                if (item === undefined) {
                    return item;
                }
            }

            return item;
        }
    };

    var atomSetEntryValueByPath = function (path, target, value, propertyType) {
        /// <summary>Sets a slashed path value on the specified target.</summary>
        /// <param name="path" type="String">Property path to set ('/'-separated).</param>
        /// <param name="target" type="Object">Object to set value on.</param>
        /// <param name="value">Value to set.</param>
        /// <param name="propertyType" type="String" optional="true">Property type to set in metadata.</param>

        var propertyName;
        if (path.indexOf('/') === -1) {
            target[path] = value;
            propertyName = path;
        } else {
            var parts = path.split('/');
            var i, len;
            for (i = 0, len = (parts.length - 1); i < len; i++) {
                // We construct each step of the way if the property is missing;
                // if it's already initialized to null, we stop further processing.
                var next = target[parts[i]];
                if (next === undefined) {
                    next = {};
                    target[parts[i]] = next;
                } else if (next === null) {
                    return;
                }
                target = next;
            }
            propertyName = parts[i];
            target[propertyName] = value;
        }

        if (propertyType) {
            var metadata = target.__metadata = target.__metadata || {};
            var properties = metadata.properties = metadata.properties || {};
            var property = properties[propertyName] = properties[propertyName] || {};
            property.type = propertyType;
        }
    };

    var atomApplyCustomizationToEntryObject = function (customization, domElement, entry) {
        /// <summary>Applies a specific feed customization item to an object.</summary>
        /// <param name="customization">Object with customization description.</param>
        /// <param name="sourcePath">Property path to set ('source' in the description).</param>
        /// <param name="entryElement">XML element for the entry that corresponds to the object being read.</param>
        /// <param name="entryObject">Object being read.</param>
        /// <param name="propertyType" type="String">Name of property type to set.</param>
        /// <param name="suffix" type="String">Suffix to feed customization properties.</param>

        var propertyPath = customization.propertyPath;
        // If keepInConent equals true or the property value is null we do nothing as this overrides any other customization.
        if (customization.keepInContent || atomGetObjectValueByPath(propertyPath, entry) === null) {
            return;
        }

        var xmlNode = xmlFindNodeByPath(domElement, customization.nsURI, customization.entryPath);

        // If the XML tree does not contain the necessary elements to read the value,
        // then it shouldn't be considered null, but rather ignored at all. This prevents
        // the customization from generating the object path down to the property.
        if (!xmlNode) {
            return;
        }

        var propertyType = customization.propertyType;
        var propertyValue;

        if (customization.contentKind === "xhtml") {
            // Treat per XHTML in http://tools.ietf.org/html/rfc4287#section-3.1.1, including the DIV
            // in the content.
            propertyValue = xmlSerializeDescendants(xmlNode);
        } else {
            propertyValue = xmlReadODataEdmPropertyValue(xmlNode, propertyType || "Edm.String");
        }
        // Set the value on the entry.
        atomSetEntryValueByPath(propertyPath, entry, propertyValue, propertyType);
    };

    var lookupPropertyType = function (metadata, owningType, path) {
        /// <summary>Looks up the type of a property given its path in an entity type.</summary>
        /// <param name="metadata">Metadata in which to search for base and complex types.</param>
        /// <param name="owningType">Type to which property belongs.</param>
        /// <param name="path" type="String" mayBeNull="false">Property path to look at.</param>
        /// <returns type="String">The name of the property type; possibly null.</returns>

        var parts = path.split("/");
        var i, len;
        while (owningType) {
            // Keep track of the type being traversed, necessary for complex types.
            var traversedType = owningType;

            for (i = 0, len = parts.length; i < len; i++) {
                // Traverse down the structure as necessary.
                var properties = traversedType.property;
                if (!properties) {
                    break;
                }

                // Find the property by scanning the property list (might be worth pre-processing).
                var propertyFound = lookupProperty(properties, parts[i]);
                if (!propertyFound) {
                    break;
                }

                var propertyType = propertyFound.type;

                // We could in theory still be missing types, but that would
                // be caused by a malformed path.
                if (!propertyType || isPrimitiveEdmType(propertyType)) {
                    return propertyType || null;
                }

                traversedType = lookupComplexType(propertyType, metadata);
                if (!traversedType) {
                    return null;
                }
            }

            // Traverse up the inheritance chain.
            owningType = lookupEntityType(owningType.baseType, metadata);
        }

        return null;
    };

    var atomReadEntry = function (domElement, baseURI, model) {
        /// <summary>Reads a DOM element for an ATOM entry, producing an object model in return.</summary>
        /// <param name="domElement">ATOM entry DOM element.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the ATOM entry.</param>
        /// <param name="model">Metadata that describes the conceptual schema.</param>
        /// <returns type="Object">A new object representing the entry.</returns>

        var entryMetadata = {};
        var entry = { __metadata: entryMetadata };

        var etag = xmlAttributeValue(domElement, "etag", odataMetaXmlNs);
        if (etag) {
            entryMetadata.etag = etag;
        }

        baseURI = xmlBaseURI(domElement, baseURI);

        xmlChildElements(domElement, function (child) {
            var nsURI = xmlNamespaceURI(child);
            var localName = xmlLocalName(child);

            if (nsURI === atomXmlNs) {
                if (localName === "id") {
                    atomReadEntryId(child, entryMetadata, baseURI);
                    return;
                }
                if (localName === "category") {
                    atomReadEntryType(child, entryMetadata);
                    return;
                }
                if (localName === "content") {
                    atomReadEntryContent(child, entry, entryMetadata, baseURI);
                    return;
                }
                if (localName === "link") {
                    atomReadEntryLink(child, entry, entryMetadata, baseURI, model);
                    return;
                }
                return;
            }

            if (nsURI === odataMetaXmlNs) {
                if (localName === "properties") {
                    atomReadEntryStructuralObject(child, entry, entryMetadata);
                    return;
                }
                if (localName === "action") {
                    atomReadAdvertisedAction(child, baseURI, entryMetadata);
                    return;
                }
                if (localName === "function") {
                    atomReadAdvertisedFunction(child, baseURI, entryMetadata);
                    return;
                }
            }
        });

        // Apply feed customizations if applicable
        var entityType = lookupEntityType(entryMetadata.type, model);
        atomApplyAllFeedCustomizations(entityType, model, function (customization) {
            atomApplyCustomizationToEntryObject(customization, domElement, entry);
        });

        return entry;
    };

    var atomReadEntryId = function (domElement, entryMetadata, baseURI) {
        /// <summary>Reads an ATOM entry id DOM element.</summary>
        /// <param name="domElement">ATOM id DOM element.</param>
        /// <param name="entryMetadata">Entry metadata object to update with the id information.</param>

        entryMetadata.uri = normalizeURI(xmlInnerText(domElement), xmlBaseURI(domElement, baseURI));
        entryMetadata.uri_extensions = atomReadExtensionAttributes(domElement);
    };

    var atomReadEntryType = function (domElement, entryMetadata) {
        /// <summary>Reads type information from an ATOM category DOM element.</summary>
        /// <param name="domElement">ATOM category DOM element.</param>
        /// <param name="entryMetadata">Entry metadata object to update with the type information.</param>

        if (xmlAttributeValue(domElement, "scheme") === odataScheme) {
            if (entryMetadata.type) {
                throw { message: "Invalid AtomPub document: multiple category elements defining the entry type were encounterd withing an entry", element: domElement };
            }

            var typeExtensions = [];
            xmlAttributes(domElement, function (attribute) {
                var nsURI = xmlNamespaceURI(attribute);
                var localName = xmlLocalName(attribute);

                if (!nsURI) {
                    if (localName !== "scheme" && localName !== "term") {
                        typeExtensions.push(createAttributeExtension(attribute, true));
                    }
                    return;
                }

                if (isExtensionNs(nsURI)) {
                    typeExtensions.push(createAttributeExtension(attribute, true));
                }
            });

            entryMetadata.type = xmlAttributeValue(domElement, "term");
            entryMetadata.type_extensions = typeExtensions;
        }
    };

    var atomReadEntryContent = function (domElement, entry, entryMetadata, baseURI) {
        /// <summary>Reads an ATOM content DOM element.</summary>
        /// <param name="domElement">ATOM content DOM element.</param>
        /// <param name="entry">Entry object to update with information.</param>
        /// <param name="entryMetadata">Entry metadata object to update with the content information.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the Atom entry content.</param>

        var src = xmlAttributeValue(domElement, "src");
        var type = xmlAttributeValue(domElement, "type");

        if (src) {
            if (!type) {
                throw {
                    message: "Invalid AtomPub document: content element must specify the type attribute if the src attribute is also specified",
                    element: domElement
                };
            }

            entryMetadata.media_src = normalizeURI(src, xmlBaseURI(domElement, baseURI));
            entryMetadata.content_type = type;
        }

        xmlChildElements(domElement, function (child) {
            if (src) {
                throw { message: "Invalid AtomPub document: content element must not have child elements if the src attribute is specified", element: domElement };
            }

            if (xmlNamespaceURI(child) === odataMetaXmlNs && xmlLocalName(child) === "properties") {
                atomReadEntryStructuralObject(child, entry, entryMetadata);
            }
        });
    };

    var atomReadEntryLink = function (domElement, entry, entryMetadata, baseURI, model) {
        /// <summary>Reads a link element on an entry.</summary>
        /// <param name="atomEntryLink">'link' element on the entry.</param>
        /// <param name="entry" type="Object">Entry object to update with the link data.</param>
        /// <param name="entryMetadata">Entry metadata object to update with the link metadata.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing the link href.</param>
        /// <param name="model" type="Object">Metadata that describes the conceptual schema.</param>

        var link = atomReadLink(domElement, baseURI);

        var rel = link.rel;
        var href = link.href;
        var extensions = link.extensions;

        if (rel === "self") {
            entryMetadata.self = href;
            entryMetadata.self_link_extensions = extensions;
            return;
        }

        if (rel === "edit") {
            entryMetadata.edit = href;
            entryMetadata.edit_link_extensions = extensions;
            return;
        }

        if (rel === "edit-media") {
            entryMetadata.edit_media = link.href;
            entryMetadata.edit_media_extensions = extensions;
            atomReadLinkMediaEtag(link, entryMetadata);
            return;
        }

        // This might be a named stream edit link
        if (rel.indexOf(odataEditMediaPrefix) === 0) {
            atomReadNamedStreamEditLink(link, entry, entryMetadata);
            return;
        }

        // This might be a named stram media resource (read) link
        if (rel.indexOf(odataMediaResourcePrefix) === 0) {
            atomReadNamedStreamSelfLink(link, entry, entryMetadata);
            return;
        }

        // This might be a navigation property
        if (rel.indexOf(odataRelatedPrefix) === 0) {
            atomReadNavPropLink(domElement, link, entry, entryMetadata, model);
            return;
        }

        if (rel.indexOf(odataRelatedLinksPrefix) === 0) {
            atomReadNavPropRelatedLink(link, entryMetadata);
            return;
        }
    };

    var atomReadNavPropRelatedLink = function (link, entryMetadata) {
        /// <summary>Reads a link represnting the links related to a navigation property in an OData Atom document.</summary>
        /// <param name="link" type="Object">Object representing the parsed link DOM element.</param>
        /// <param name="entryMetadata" type="Object">Entry metadata object to update with the related links information.</param>

        var propertyName = link.rel.substring(odataRelatedLinksPrefix.length);

        // Set the extra property information on the entry object metadata.
        entryMetadata.properties = entryMetadata.properties || {};
        var propertyMetadata = entryMetadata.properties[propertyName] = entryMetadata.properties[propertyName] || {};

        propertyMetadata.associationuri = link.href;
        propertyMetadata.associationuri_extensions = link.extensions;
    };

    var atomReadNavPropLink = function (domElement, link, entry, entryMetadata, model) {
        /// <summary>Reads a link representing a navigation property in an OData Atom document.</summary>
        /// <param name="domElement">DOM element for a navigation property in an OData Atom document.</summary>
        /// <param name="link" type="Object">Object representing the parsed link DOM element.</param>
        /// <param name="entry" type="Object">Entry object to update with the navigation property.</param>
        /// <param name="entryMetadata">Entry metadata object to update with the navigation property metadata.</param>
        /// <param name="model" type="Object">Metadata that describes the conceptual schema.</param>

        // Get any inline data.
        var inlineData;
        var inlineElement = xmlFirstChildElement(domElement, odataMetaXmlNs, "inline");
        if (inlineElement) {
            var inlineDocRoot = xmlFirstChildElement(inlineElement);
            var inlineBaseURI = xmlBaseURI(inlineElement, link.baseURI);
            inlineData = inlineDocRoot ? atomReadDocument(inlineDocRoot, inlineBaseURI, model) : null;
        } else {
            // If the link has no inline content, we consider it deferred.
            inlineData = { __deferred: { uri: link.href} };
        }

        var propertyName = link.rel.substring(odataRelatedPrefix.length);

        // Set the property value on the entry object.
        entry[propertyName] = inlineData;

        // Set the extra property information on the entry object metadata.
        entryMetadata.properties = entryMetadata.properties || {};
        var propertyMetadata = entryMetadata.properties[propertyName] = entryMetadata.properties[propertyName] || {};

        propertyMetadata.extensions = link.extensions;
    };

    var atomReadNamedStreamEditLink = function (link, entry, entryMetadata) {
        /// <summary>Reads a link representing the edit-media url of a named stream in an OData Atom document.</summary>
        /// <param name="link" type="Object">Object representing the parsed link DOM element.</param>
        /// <param name="entry" type="Object">Entry object to update with the named stream data.</param>
        /// <param name="entryMetadata">Entry metadata object to update with the named stream metadata.</param>

        var propertyName = link.rel.substring(odataEditMediaPrefix.length);

        var namedStreamMediaResource = atomGetEntryNamedStreamMediaResource(propertyName, entry, entryMetadata);
        var mediaResource = namedStreamMediaResource.value;
        var mediaResourceMetadata = namedStreamMediaResource.metadata;

        var editMedia = link.href;

        mediaResource.edit_media = editMedia;
        mediaResource.content_type = link.type;
        mediaResourceMetadata.edit_media_extensions = link.extensions;

        // If there is only the edit link, make it the media self link as well.
        mediaResource.media_src = mediaResource.media_src || editMedia;
        mediaResourceMetadata.media_src_extensions = mediaResourceMetadata.media_src_extensions || [];

        atomReadLinkMediaEtag(link, mediaResource);
    };

    var atomReadNamedStreamSelfLink = function (link, entry, entryMetadata) {
        /// <summary>Reads a link representing the self url of a named stream in an OData Atom document.</summary>
        /// <param name="link" type="Object">Object representing the parsed link DOM element.</param>
        /// <param name="entry" type="Object">Entry object to update with the named stream data.</param>
        /// <param name="entryMetadata">Entry metadata object to update with the named stream metadata.</param>

        var propertyName = link.rel.substring(odataMediaResourcePrefix.length);

        var namedStreamMediaResource = atomGetEntryNamedStreamMediaResource(propertyName, entry, entryMetadata);
        var mediaResource = namedStreamMediaResource.value;
        var mediaResourceMetadata = namedStreamMediaResource.metadata;

        mediaResource.media_src = link.href;
        mediaResourceMetadata.media_src_extensions = link.extensions;
        mediaResource.content_type = link.type;
    };

    var atomGetEntryNamedStreamMediaResource = function (name, entry, entryMetadata) {
        /// <summary>Gets the media resource object and metadata object for a named stream in an entry object.</summary>
        /// <param name="link" type="Object">Object representing the parsed link DOM element.</param>
        /// <param name="entry" type="Object">Entry object from which the media resource object will be obtained.</param>
        /// <param name="entryMetadata" type="Object">Entry metadata object from which the media resource metadata object will be obtained.</param>
        /// <remarks>
        ///    If the entry doest' have a media resource for the named stream indicated by the name argument, then this function will create a new
        ///    one along with its metadata object.
        /// <remarks>
        /// <returns type="Object"> Object containing the value and metadata of the named stream's media resource. <returns>

        entryMetadata.properties = entryMetadata.properties || {};

        var mediaResourceMetadata = entryMetadata.properties[name];
        var mediaResource = entry[name] && entry[name].__mediaresource;

        if (!mediaResource) {
            mediaResource = {};
            entry[name] = { __mediaresource: mediaResource };
            entryMetadata.properties[name] = mediaResourceMetadata = {};
        }
        return { value: mediaResource, metadata: mediaResourceMetadata };
    };

    var atomReadLinkMediaEtag = function (link, mediaResource) {
        /// <summary>Gets the media etag from the link extensions and updates the media resource object with it.</summary>
        /// <param name="link" type="Object">Object representing the parsed link DOM element.</param>
        /// <param name="mediaResource" type="Object">Object containing media information for an OData Atom entry.</param>
        /// <remarks>
        ///    The function will remove the extension object for the etag if it finds it in the link extensions and will set
        ///    its value under the media_etag property of the mediaResource object.
        /// <remarks>
        /// <returns type="Object"> Object containing the value and metadata of the named stream's media resource. <returns>

        var extensions = link.extensions;
        var i, len;
        for (i = 0, len = extensions.length; i < len; i++) {
            if (extensions[i].namespaceURI === odataMetaXmlNs && extensions[i].name === "etag") {
                mediaResource.media_etag = extensions[i].value;
                extensions.splice(i, 1);
                return;
            }
        }
    };

    var atomReadEntryStructuralObject = function (domElement, parent, parentMetadata) {
        /// <summary>Reads an atom entry's property as a structural object and sets its value in the parent and the metadata in the parentMetadata objects.</summary>
        /// <param name="propertiesElement">XML element for the 'properties' node.</param>
        /// <param name="parent">
        ///     Object that will contain the property value. It can be either an antom entry or
        ///     an atom complex property object.
        /// </param>
        /// <param name="parentMetadata">Object that will contain the property metadata. It can be either an atom entry metadata or a complex property metadata object</param>

        xmlChildElements(domElement, function (child) {
            var property = xmlReadODataProperty(child);
            if (property) {
                var propertyName = property.name;
                var propertiesMetadata = parentMetadata.properties = parentMetadata.properties || {};
                propertiesMetadata[propertyName] = property.metadata;
                parent[propertyName] = property.value;
            }
        });
    };

    var atomReadServiceDocument = function (domElement, baseURI) {
        /// <summary>Reads an AtomPub service document</summary>
        /// <param name="atomServiceDoc">DOM element for the root of an AtomPub service document</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the AtomPub service document.</param>
        /// <returns type="Object">An object that contains the properties of the service document</returns>

        var workspaces = [];
        var extensions = [];

        baseURI = xmlBaseURI(domElement, baseURI);
        // Find all the workspace elements.
        xmlChildElements(domElement, function (child) {
            if (xmlNamespaceURI(child) === appXmlNs && xmlLocalName(child) === "workspace") {
                workspaces.push(atomReadServiceDocumentWorkspace(child, baseURI));
                return;
            }
            extensions.push(createElementExtension(child));
        });

        // AtomPub (RFC 5023 Section 8.3.1) says a service document MUST contain one or
        // more workspaces. Throw if we don't find any.
        if (workspaces.length === 0) {
            throw { message: "Invalid AtomPub service document: No workspace element found.", element: domElement };
        }

        return { workspaces: workspaces, extensions: extensions };
    };

    var atomReadServiceDocumentWorkspace = function (domElement, baseURI) {
        /// <summary>Reads a single workspace element from an AtomPub service document</summary>
        /// <param name="domElement">DOM element that represents a workspace of an AtomPub service document</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the AtomPub service document workspace.</param>
        /// <returns type="Object">An object that contains the properties of the workspace</returns>

        var collections = [];
        var extensions = [];
        var title; // = undefined;

        baseURI = xmlBaseURI(domElement, baseURI);

        xmlChildElements(domElement, function (child) {
            var nsURI = xmlNamespaceURI(child);
            var localName = xmlLocalName(child);

            if (nsURI === atomXmlNs) {
                if (localName === "title") {
                    if (title !== undefined) {
                        throw { message: "Invalid AtomPub service document: workspace has more than one child title element", element: child };
                    }

                    title = xmlInnerText(child);
                    return;
                }
            }

            if (nsURI === appXmlNs) {
                if (localName === "collection") {
                    collections.push(atomReadServiceDocumentCollection(child, baseURI));
                }
                return;
            }
            extensions.push(atomReadExtensionElement(child));
        });

        return { title: title || "", collections: collections, extensions: extensions };
    };

    var atomReadServiceDocumentCollection = function (domElement, baseURI) {
        /// <summary>Reads a service document collection element into an object.</summary>
        /// <param name="domElement">DOM element that represents a collection of an AtomPub service document.</param>
        /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the AtomPub service document collection.</param>
        /// <returns type="Object">An object that contains the properties of the collection.</returns>


        var href = xmlAttributeValue(domElement, "href");

        if (!href) {
            throw { message: "Invalid AtomPub service document: collection has no href attribute", element: domElement };
        }

        baseURI = xmlBaseURI(domElement, baseURI);
        href = normalizeURI(href, xmlBaseURI(domElement, baseURI));
        var extensions = [];
        var title; // = undefined;

        xmlChildElements(domElement, function (child) {
            var nsURI = xmlNamespaceURI(child);
            var localName = xmlLocalName(child);

            if (nsURI === atomXmlNs) {
                if (localName === "title") {
                    if (title !== undefined) {
                        throw { message: "Invalid AtomPub service document: collection has more than one child title element", element: child };
                    }
                    title = xmlInnerText(child);
                }
                return;
            }

            if (nsURI !== appXmlNs) {
                extensions.push(atomReadExtensionElement(domElement));
            }
        });

        // AtomPub (RFC 5023 Section 8.3.3) says the collection element MUST contain
        // a title element. It's likely to be problematic if the service doc doesn't
        // have one so here we throw.
        if (!title) {
            throw { message: "Invalid AtomPub service document: collection has no title element", element: domElement };
        }

        return { title: title, href: href, extensions: extensions };
    };

    var atomNewElement = function (dom, name, children) {
        /// <summary>Creates a new DOM element in the Atom namespace.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Local name of the Atom element to create.</param>
        /// <param name="children" type="Array">Array containing DOM nodes or string values that will be added as children of the new DOM element.</param>
        /// <returns>New DOM element in the Atom namespace.</returns>
        /// <remarks>
        ///    If a value in the children collection is a string, then a new DOM text node is going to be created
        ///    for it and then appended as a child of the new DOM Element.
        /// </remarks>

        return xmlNewElement(dom, atomXmlNs, xmlQualifiedName(atomPrefix, name), children);
    };

    var atomNewAttribute = function (dom, name, value) {
        /// <summary>Creates a new DOM attribute for an Atom element in the default namespace.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Local name of the OData attribute to create.</param>
        /// <param name="value">Attribute value.</param>
        /// <returns>New DOM attribute in the default namespace.</returns>

        return xmlNewAttribute(dom, null, name, value);
    };

    var atomCanRemoveProperty = function (propertyElement) {
        /// <summary>Checks whether the property represented by domElement can be removed from the atom document DOM tree.</summary>
        /// <param name="propertyElement">DOM element for the property to test.</param>
        /// <remarks>
        ///     The property can only be removed if it doens't have any children and only has namespace or type declaration attributes.
        /// </remarks>
        /// <returns type="Boolean">True is the property can be removed; false otherwise.</returns>

        if (propertyElement.childNodes.length > 0) {
            return false;
        }

        var isEmpty = true;
        var attributes = propertyElement.attributes;
        var i, len;
        for (i = 0, len = attributes.length; i < len && isEmpty; i++) {
            var attribute = attributes[i];

            isEmpty = isEmpty && isXmlNSDeclaration(attribute) ||
                 (xmlNamespaceURI(attribute) == odataMetaXmlNs && xmlLocalName(attribute) === "type");
        }
        return isEmpty;
    };

    var atomNewODataNavigationProperty = function (dom, name, kind, value, model) {
        /// <summary>Creates a new Atom link DOM element for a navigation property in an OData Atom document.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Property name.</param>
        /// <param name="kind" type="String">Navigation property kind. Expected values are "deferred", "entry", or "feed".</param>
        /// <param name="value" optional="true" mayBeNull="true">Value of the navigation property, if any.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <returns type="Object">
        ///     Object containing the new Atom link DOM element for the navigation property and the
        ///     required data service version for this property.
        /// </returns>

        var linkType = null;
        var linkContent = null;
        var linkContentBodyData = null;
        var href = "";

        if (kind !== "deferred") {
            linkType = atomNewAttribute(dom, "type", "application/atom+xml;type=" + kind);
            linkContent = xmlNewODataMetaElement(dom, "inline");

            if (value) {
                href = value.__metadata && value.__metadata.uri || "";
                linkContentBodyData =
                    atomNewODataFeed(dom, value, model) ||
                    atomNewODataEntry(dom, value, model);
                xmlAppendChild(linkContent, linkContentBodyData.element);
            }
        } else {
            href = value.__deferred.uri;
        }

        var navProp = atomNewElement(dom, "link", [
            atomNewAttribute(dom, "href", href),
            atomNewAttribute(dom, "rel", normalizeURI(name, odataRelatedPrefix)),
            linkType,
            linkContent
        ]);

        return xmlNewODataElementInfo(navProp, linkContentBodyData ? linkContentBodyData.dsv : "1.0");
    };

    var atomNewODataEntryDataItem = function (dom, name, value, dataItemMetadata, dataItemModel, model) {
        /// <summary>Creates a new DOM element for a data item in an entry, complex property, or collection property.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="name" type="String">Data item name.</param>
        /// <param name="value" optional="true" mayBeNull="true">Value of the data item, if any.</param>
        /// <param name="dataItemMetadata" type="Object" optional="true">Object containing metadata about 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>
        /// <returns type="Object">
        ///     Object containing the new DOM element in the appropriate namespace for the data item and the
        ///     required data service version for it.
        /// </returns>

        if (isNamedStream(value)) {
            return null;
        }

        var dataElement = xmlNewODataDataElement(dom, name, value, dataItemMetadata, dataItemModel, model);
        if (!dataElement) {
            // This may be a navigation property.
            var navPropKind = navigationPropertyKind(value, dataItemModel);

            dataElement = atomNewODataNavigationProperty(dom, name, navPropKind, value, model);
        }
        return dataElement;
    };

    var atomEntryCustomization = function (dom, entry, entryProperties, customization) {
        /// <summary>Applies a feed customization by transforming an Atom entry DOM element as needed.</summary>
        /// <param name="dom">DOM document used for creating any new DOM nodes required by the customization.</param>
        /// <param name="entry">DOM element for the Atom entry to which the customization is going to be applied.</param>
        /// <param name="entryProperties">DOM element containing the properties of the Atom entry.</param>
        /// <param name="customization" type="Object">Object describing an applicable feed customization.</param>
        /// <remarks>
        ///     Look into the atomfeedCustomization function for a description of the customization object.
        /// </remarks>
        /// <returns type="String">Data service version required by the applied customization</returns>

        var atomProperty = xmlFindElementByPath(entryProperties, odataXmlNs, customization.propertyPath);
        var atomPropertyNullAttribute = atomProperty && xmlAttributeNode(atomProperty, "null", odataMetaXmlNs);
        var atomPropertyValue;
        var dataServiceVersion = "1.0";

        if (atomPropertyNullAttribute && atomPropertyNullAttribute.value === "true") {
            return dataServiceVersion;
        }

        if (atomProperty) {
            atomPropertyValue = xmlInnerText(atomProperty) || "";
            if (!customization.keepInContent) {
                dataServiceVersion = "2.0";
                var parent = atomProperty.parentNode;
                var candidate = parent;

                parent.removeChild(atomProperty);
                while (candidate !== entryProperties && atomCanRemoveProperty(candidate)) {
                    parent = candidate.parentNode;
                    parent.removeChild(candidate);
                    candidate = parent;
                }
            }
        }

        var targetNode = xmlNewNodeByPath(dom, entry,
            customization.nsURI, customization.nsPrefix, customization.entryPath);

        if (targetNode.nodeType === 2) {
            targetNode.value = atomPropertyValue;
            return dataServiceVersion;
        }

        var contentKind = customization.contentKind;
        xmlAppendChildren(targetNode, [
                contentKind && xmlNewAttribute(dom, null, "type", contentKind),
                contentKind === "xhtml" ? xmlNewFragment(dom, atomPropertyValue) : atomPropertyValue
        ]);

        return dataServiceVersion;
    };

    var atomNewODataEntry = function (dom, data, model) {
        /// <summary>Creates a new DOM element for an Atom entry.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="data" type="Object">Entry object in the library's internal representation.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <returns type="Object">
        ///     Object containing the new DOM element for the Atom entry and the required data service version for it.
        /// </returns>

        var payloadMetadata = data.__metadata || {};
        var propertiesMetadata = payloadMetadata.properties || {};

        var etag = payloadMetadata.etag;
        var uri = payloadMetadata.uri;
        var typeName = payloadMetadata.type;
        var entityType = lookupEntityType(typeName, model);

        var properties = xmlNewODataMetaElement(dom, "properties");
        var entry = atomNewElement(dom, "entry", [
            atomNewElement(dom, "author",
                atomNewElement(dom, "name")
            ),
            etag && xmlNewODataMetaAttribute(dom, "etag", etag),
            uri && atomNewElement(dom, "id", uri),
            typeName && atomNewElement(dom, "category", [
                atomNewAttribute(dom, "term", typeName),
                atomNewAttribute(dom, "scheme", odataScheme)
            ]),
        // TODO: MLE support goes here.
            atomNewElement(dom, "content", [
                atomNewAttribute(dom, "type", "application/xml"),
                properties
            ])
        ]);

        var dataServiceVersion = "1.0";
        for (var name in data) {
            if (name !== "__metadata") {
                var entryDataItemMetadata = propertiesMetadata[name] || {};
                var entryDataItemModel = entityType && (
                    lookupProperty(entityType.property, name) ||
                    lookupProperty(entityType.navigationProperty, name));

                var entryDataItem = atomNewODataEntryDataItem(dom, name, data[name], entryDataItemMetadata, entryDataItemModel, model);
                if (entryDataItem) {
                    var entryElement = entryDataItem.element;
                    var entryElementParent = (xmlNamespaceURI(entryElement) === atomXmlNs) ? entry : properties;

                    xmlAppendChild(entryElementParent, entryElement);
                    dataServiceVersion = maxVersion(dataServiceVersion, entryDataItem.dsv);
                }
            }
        }

        atomApplyAllFeedCustomizations(entityType, model, function (customization) {
            var customizationDsv = atomEntryCustomization(dom, entry, properties, customization);
            dataServiceVersion = maxVersion(dataServiceVersion, customizationDsv);
        });

        return xmlNewODataElementInfo(entry, dataServiceVersion);
    };

    var atomNewODataFeed = function (dom, data, model) {
        /// <summary>Creates a new DOM element for an Atom feed.</summary>
        /// <param name="dom">DOM document used for creating the new DOM Element.</param>
        /// <param name="data" type="Object">Feed object in the library's internal representation.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <returns type="Object">
        ///     Object containing the new DOM element for the Atom feed and the required data service version for it.
        /// </returns>

        var entries = isArray(data) ? data : data.results;

        if (!entries) {
            return null;
        }

        var dataServiceVersion = "1.0";
        var atomFeed = atomNewElement(dom, "feed");

        var i, len;
        for (i = 0, len = entries.length; i < len; i++) {
            var atomEntryData = atomNewODataEntry(dom, entries[i], model);
            xmlAppendChild(atomFeed, atomEntryData.element);
            dataServiceVersion = maxVersion(dataServiceVersion, atomEntryData.dsv);
        }
        return xmlNewODataElementInfo(atomFeed, dataServiceVersion);
    };

    var atomNewODataDocument = function (data, model) {
        /// <summary>Creates a new OData Atom document.</summary>
        /// <param name="data" type="Object">Feed or entry object in the libary's internal representaion.</param>
        /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
        /// <returns type="Object">
        ///     Object containing the new DOM document for the Atom document and the required data service version for it.
        /// </returns>

        if (data) {
            var atomRootWriter = isFeed(data) && atomNewODataFeed ||
                isObject(data) && atomNewODataEntry;

            if (atomRootWriter) {
                var dom = xmlDom();
                var atomRootData = atomRootWriter(dom, data, model);

                if (atomRootData) {
                    var atomRootElement = atomRootData.element;
                    xmlAppendChildren(atomRootElement, [
                        xmlNewNSDeclaration(dom, odataMetaXmlNs, odataMetaPrefix),
                        xmlNewNSDeclaration(dom, odataXmlNs, odataPrefix)
                    ]);
                    return xmlNewODataElementInfo(xmlAppendChild(dom, atomRootElement), atomRootData.dsv);
                }
            }
        }
        return null;
    };

    var atomParser = function (handler, text, context) {
        /// <summary>Parses an ATOM document (feed, entry or service document).</summary>
        /// <param name="handler">This handler.</param>
        /// <param name="text" type="String">Document text.</param>
        /// <param name="context" type="Object">Object with parsing context.</param>
        /// <returns>An object representation of the document; undefined if not applicable.</returns>

        if (text) {
            var atomDoc = xmlParse(text);
            var atomRoot = xmlFirstChildElement(atomDoc);
            if (atomRoot) {
                return atomReadDocument(atomRoot, null, context.metadata);
            }
        }
    };

    var atomSerializer = function (handler, data, context) {
        /// <summary>Serializes an ATOM object into a document (feed or entry).</summary>
        /// <param name="handler">This handler.</param>
        /// <param name="data" type="Object">Representation of feed or entry.</param>
        /// <param name="context" type="Object">Object with parsing context.</param>
        /// <returns>An text representation of the data object; undefined if not applicable.</returns>

        var cType = context.contentType = context.contentType || contentType(atomMediaType);
        if (cType && cType.mediaType === atomMediaType) {
            var atomDoc = atomNewODataDocument(data, context.metadata);
            if (atomDoc) {
                context.dataServiceVersion = maxVersion(context.dataServiceVersion || "1.0", atomDoc.dsv);
                return xmlSerialize(atomDoc.element);
            }
        }
        // Allow undefined to be returned.
    };

    odata.atomHandler = handler(atomParser, atomSerializer, atomAcceptTypes.join(","), MAX_DATA_SERVICE_VERSION);



    var schemaElement = function (attributes, elements, text, ns) {
        /// <summary>Creates an object that describes an element in an schema.</summary>
        /// <param name="attributes" type="Array">List containing the names of the attributes allowed for this element.</param>
        /// <param name="elements" type="Array">List containing the names of the child elements allowed for this element.</param>
        /// <param name="text" type="Boolean">Flag indicating if the element's text value is of interest or not.</param>
        /// <param name="ns" type="String">Namespace to which the element belongs to.</param>
        /// <remarks>
        ///    If a child element name ends with * then it is understood by the schema that that child element can appear 0 or more times.
        /// </remarks>
        /// <returns type="Object">Object with attributes, elements, text, and ns fields.</returns>

        return {
            attributes: attributes,
            elements: elements,
            text: text || false,
            ns: ns
        };
    };

    // It's assumed that all elements may have Documentation children and Annotation elements.
    // See http://docs.oasis-open.org/odata/odata/v4.0/cs01/part3-csdl/odata-v4.0-cs01-part3-csdl.html for a CSDL reference.
    var schema = {
        elements: {
            Action: schemaElement(
            /*attributes*/["Name", "IsBound", "EntitySetPath"],
            /*elements*/["ReturnType", "Parameter*", "Annotation*"]
            ),
            ActionImport: schemaElement(
            /*attributes*/["Name", "Action", "EntitySet", "Annotation*"]
            ),
            Annotation: schemaElement(
            /*attributes*/["Term", "Qualifier", "Binary", "Bool", "Date", "DateTimeOffset", "Decimal", "Duration", "EnumMember", "Float", "Guid", "Int", "String", "TimeOfDay", "AnnotationPath", "NavigationPropertyPath", "Path", "PropertyPath", "UrlRef"],
            /*elements*/["Binary*", "Bool*", "Date*", "DateTimeOffset*", "Decimal*", "Duration*", "EnumMember*", "Float*", "Guid*", "Int*", "String*", "TimeOfDay*", "And*", "Or*", "Not*", "Eq*", "Ne*", "Gt*", "Ge*", "Lt*", "Le*", "AnnotationPath*", "Apply*", "Cast*", "Collection*", "If*", "IsOf*", "LabeledElement*", "LabeledElementReference*", "Null*", "NavigationPropertyPath*", "Path*", "PropertyPath*", "Record*", "UrlRef*", "Annotation*"]
            ),
            AnnotationPath: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Annotations: schemaElement(
            /*attributes*/["Target", "Qualifier"],
            /*elements*/["Annotation*"]
            ),
            Apply: schemaElement(
            /*attributes*/["Function"],
            /*elements*/["String*", "Path*", "LabeledElement*", "Annotation*"]
            ),
            And: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Or: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Not: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Eq: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Ne: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Gt: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Ge: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Lt: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Le: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Binary: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Bool: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Cast: schemaElement(
            /*attributes*/["Type"],
            /*elements*/["Path*", "Annotation*"]
            ),
            Collection: schemaElement(
            /*attributes*/null,
            /*elements*/["Binary*", "Bool*", "Date*", "DateTimeOffset*", "Decimal*", "Duration*", "EnumMember*", "Float*", "Guid*", "Int*", "String*", "TimeOfDay*", "And*", "Or*", "Not*", "Eq*", "Ne*", "Gt*", "Ge*", "Lt*", "Le*", "AnnotationPath*", "Apply*", "Cast*", "Collection*", "If*", "IsOf*", "LabeledElement*", "LabeledElementReference*", "Null*", "NavigationPropertyPath*", "Path*", "PropertyPath*", "Record*", "UrlRef*"]
            ),
            ComplexType: schemaElement(
            /*attributes*/["Name", "BaseType", "Abstract", "OpenType"],
            /*elements*/["Property*", "NavigationProperty*", "Annotation*"]
            ),
            Date: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            DateTimeOffset: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Decimal: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Duration: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            EntityContainer: schemaElement(
            /*attributes*/["Name", "Extends"],
            /*elements*/["EntitySet*", "Singleton*", "ActionImport*", "FunctionImport*", "Annotation*"]
            ),
            EntitySet: schemaElement(
            /*attributes*/["Name", "EntityType", "IncludeInServiceDocument"],
            /*elements*/["NavigationPropertyBinding*", "Annotation*"]
            ),
            EntityType: schemaElement(
            /*attributes*/["Name", "BaseType", "Abstract", "OpenType", "HasStream"],
            /*elements*/["Key*", "Property*", "NavigationProperty*", "Annotation*"]
            ),
            EnumMember: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            EnumType: schemaElement(
            /*attributes*/["Name", "UnderlyingType", "IsFlags"],
            /*elements*/["Member*"]
            ),
            Float: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Function: schemaElement(
            /*attributes*/["Name", "IsBound", "IsComposable", "EntitySetPath"],
            /*elements*/["ReturnType", "Parameter*", "Annotation*"]
            ),
            FunctionImport: schemaElement(
            /*attributes*/["Name", "Function", "EntitySet", "IncludeInServiceDocument", "Annotation*"]
            ),
            Guid: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            If: schemaElement(
            /*attributes*/null,
            /*elements*/["Path*", "String*", "Annotation*"]
            ),
            Int: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            IsOf: schemaElement(
            /*attributes*/["Type", "MaxLength", "Precision", "Scale", "Unicode", "SRID", "DefaultValue", "Annotation*"],
            /*elements*/["Path*"]
            ),
            Key: schemaElement(
            /*attributes*/null,
            /*elements*/["PropertyRef*"]
            ),
            LabeledElement: schemaElement(
            /*attributes*/["Name"],
            /*elements*/["Binary*", "Bool*", "Date*", "DateTimeOffset*", "Decimal*", "Duration*", "EnumMember*", "Float*", "Guid*", "Int*", "String*", "TimeOfDay*", "And*", "Or*", "Not*", "Eq*", "Ne*", "Gt*", "Ge*", "Lt*", "Le*", "AnnotationPath*", "Apply*", "Cast*", "Collection*", "If*", "IsOf*", "LabeledElement*", "LabeledElementReference*", "Null*", "NavigationPropertyPath*", "Path*", "PropertyPath*", "Record*", "UrlRef*", "Annotation*"]
            ),
            LabeledElementReference: schemaElement(
            /*attributes*/["Term"],
            /*elements*/["Binary*", "Bool*", "Date*", "DateTimeOffset*", "Decimal*", "Duration*", "EnumMember*", "Float*", "Guid*", "Int*", "String*", "TimeOfDay*", "And*", "Or*", "Not*", "Eq*", "Ne*", "Gt*", "Ge*", "Lt*", "Le*", "AnnotationPath*", "Apply*", "Cast*", "Collection*", "If*", "IsOf*", "LabeledElement*", "LabeledElementReference*", "Null*", "NavigationPropertyPath*", "Path*", "PropertyPath*", "Record*", "UrlRef*"]
            ),
            Member: schemaElement(
            /*attributes*/["Name", "Value"],
            /*element*/["Annotation*"]
            ),
            NavigationProperty: schemaElement(
            /*attributes*/["Name", "Type", "Nullable", "Partner", "ContainsTarget"],
            /*elements*/["ReferentialConstraint*", "OnDelete*", "Annotation*"]
            ),
            NavigationPropertyBinding: schemaElement(
            /*attributes*/["Path", "Target"]
            ),
            NavigationPropertyPath: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Null: schemaElement(
            /*attributes*/null,
            /*elements*/["Annotation*"]
            ),
            OnDelete: schemaElement(
            /*attributes*/["Action"],
            /*elements*/["Annotation*"]
            ),
            Path: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Parameter: schemaElement(
            /*attributes*/["Name", "Type", "Nullable", "MaxLength", "Precision", "Scale", "SRID"],
            /*elements*/["Annotation*"]
            ),
            Property: schemaElement(
            /*attributes*/["Name", "Type", "Nullable", "MaxLength", "Precision", "Scale", "Unicode", "SRID", "DefaultValue"],
            /*elements*/["Annotation*"]
            ),
            PropertyPath: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            PropertyRef: schemaElement(
            /*attributes*/["Name", "Alias"]
            ),
            PropertyValue: schemaElement(
            /*attributes*/["Property", "Path"],
            /*elements*/["Binary*", "Bool*", "Date*", "DateTimeOffset*", "Decimal*", "Duration*", "EnumMember*", "Float*", "Guid*", "Int*", "String*", "TimeOfDay*", "And*", "Or*", "Not*", "Eq*", "Ne*", "Gt*", "Ge*", "Lt*", "Le*", "AnnotationPath*", "Apply*", "Cast*", "Collection*", "If*", "IsOf*", "LabeledElement*", "LabeledElementReference*", "Null*", "NavigationPropertyPath*", "Path*", "PropertyPath*", "Record*", "UrlRef*", "Annotation*"]
            ),
            Record: schemaElement(
            /*attributes*/null,
            /*Elements*/["PropertyValue*", "Property*", "Annotation*"]
            ),
            ReferentialConstraint: schemaElement(
            /*attributes*/["Property", "ReferencedProperty", "Annotation*"]
            ),
            ReturnType: schemaElement(
            /*attributes*/["Type", "Nullable", "MaxLength", "Precision", "Scale", "SRID"]
            ),
            String: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            Schema: schemaElement(
            /*attributes*/["Namespace", "Alias"],
            /*elements*/["Action*", "Annotations*", "Annotation*", "ComplexType*", "EntityContainer", "EntityType*", "EnumType*", "Function*", "Term*", "TypeDefinition*", "Annotation*"]
            ),
            Singleton: schemaElement(
            /*attributes*/["Name", "Type"],
            /*elements*/["NavigationPropertyBinding*", "Annotation*"]
            ),
            Term: schemaElement(
            /*attributes*/["Name", "Type", "BaseTerm", "DefaultValue ", "AppliesTo", "Nullable", "MaxLength", "Precision", "Scale", "SRID"],
            /*elements*/["Annotation*"]
            ),
            TimeOfDay: schemaElement(
            /*attributes*/null,
            /*elements*/null,
            /*text*/true
            ),
            TypeDefinition: schemaElement(
            /*attributes*/["Name", "UnderlyingType", "MaxLength", "Unicode", "Precision", "Scale", "SRID"],
            /*elements*/["Annotation*"]
            ),
            UrlRef: schemaElement(
            /*attributes*/null,
            /*elements*/["Binary*", "Bool*", "Date*", "DateTimeOffset*", "Decimal*", "Duration*", "EnumMember*", "Float*", "Guid*", "Int*", "String*", "TimeOfDay*", "And*", "Or*", "Not*", "Eq*", "Ne*", "Gt*", "Ge*", "Lt*", "Le*", "AnnotationPath*", "Apply*", "Cast*", "Collection*", "If*", "IsOf*", "LabeledElement*", "LabeledElementReference*", "Null*", "NavigationPropertyPath*", "Path*", "PropertyPath*", "Record*", "UrlRef*", "Annotation*"]
            ),

            // See http://msdn.microsoft.com/en-us/library/dd541238(v=prot.10) for an EDMX reference.
            Edmx: schemaElement(
            /*attributes*/["Version"],
            /*elements*/["DataServices", "Reference*"],
            /*text*/false,
            /*ns*/edmxNs
            ),
            DataServices: schemaElement(
            /*attributes*/["m:MaxDataServiceVersion", "m:DataServiceVersion"],
            /*elements*/["Schema*"],
            /*text*/false,
            /*ns*/edmxNs
            ),
            Reference: schemaElement(
            /*attributes*/["Uri"],
            /*elements*/["Include*", "IncludeAnnotations*", "Annotation*"]
            ),
            Include: schemaElement(
            /*attributes*/["Namespace", "Alias"]
            ),
            IncludeAnnotations: schemaElement(
            /*attributes*/["TermNamespace", "Qualifier", "TargetNamespace"]
            )
        }
    };

    var scriptCase = function (text) {
        /// <summary>Converts a Pascal-case identifier into a camel-case identifier.</summary>
        /// <param name="text" type="String">Text to convert.</param>
        /// <returns type="String">Converted text.</returns>
        /// <remarks>If the text starts with multiple uppercase characters, it is left as-is.</remarks>

        if (!text) {
            return text;
        }

        if (text.length > 1) {
            var firstTwo = text.substr(0, 2);
            if (firstTwo === firstTwo.toUpperCase()) {
                return text;
            }

            return text.charAt(0).toLowerCase() + text.substr(1);
        }

        return text.charAt(0).toLowerCase();
    };

    var getChildSchema = function (parentSchema, candidateName) {
        /// <summary>Gets the schema node for the specified element.</summary>
        /// <param name="parentSchema" type="Object">Schema of the parent XML node of 'element'.</param>
        /// <param name="candidateName">XML element name to consider.</param>
        /// <returns type="Object">The schema that describes the specified element; null if not found.</returns>

        var elements = parentSchema.elements;
        if (!elements) {
            return null;
        }

        var i, len;
        for (i = 0, len = elements.length; i < len; i++) {
            var elementName = elements[i];
            var multipleElements = false;
            if (elementName.charAt(elementName.length - 1) === "*") {
                multipleElements = true;
                elementName = elementName.substr(0, elementName.length - 1);
            }

            if (candidateName === elementName) {
                var propertyName = scriptCase(elementName);
                return { isArray: multipleElements, propertyName: propertyName };
            }
        }

        return null;
    };

    var isEdmNamespace = function (nsUri) {
        /// <summary>Checks whether the specifies namespace URI is one of the known CSDL namespace URIs.</summary>
        /// <param name="nsUri" type="String">Namespace URI to check.</param>
        /// <returns type="Boolean">true if nsURI is a known CSDL namespace; false otherwise.</returns>

        return nsUri === edmNs1;
    };

    var parseConceptualModelElement = function (element) {
        /// <summary>Parses a CSDL document.</summary>
        /// <param name="element">DOM element to parse.</param>
        /// <returns type="Object">An object describing the parsed element.</returns>

        var localName = xmlLocalName(element);
        var nsURI = xmlNamespaceURI(element);
        var elementSchema = schema.elements[localName];
        if (!elementSchema) {
            return null;
        }

        if (elementSchema.ns) {
            if (nsURI !== elementSchema.ns) {
                return null;
            }
        } else if (!isEdmNamespace(nsURI)) {
            return null;
        }

        var item = {};
        var attributes = elementSchema.attributes || [];
        xmlAttributes(element, function (attribute) {

            var localName = xmlLocalName(attribute);
            var nsURI = xmlNamespaceURI(attribute);
            var value = attribute.value;

            // Don't do anything with xmlns attributes.
            if (nsURI === xmlnsNS) {
                return;
            }

            // Currently, only m: for metadata is supported as a prefix in the internal schema table,
            // un-prefixed element names imply one a CSDL element.
            var schemaName = null;
            var handled = false;
            if (isEdmNamespace(nsURI) || nsURI === null) {
                schemaName = "";
            } else if (nsURI === odataMetaXmlNs) {
                schemaName = "m:";
            }

            if (schemaName !== null) {
                schemaName += localName;

                if (contains(attributes, schemaName)) {
                    item[scriptCase(localName)] = value;
                }
            }
        });

        xmlChildElements(element, function (child) {
            var localName = xmlLocalName(child);
            var childSchema = getChildSchema(elementSchema, localName);
            if (childSchema) {
                if (childSchema.isArray) {
                    var arr = item[childSchema.propertyName];
                    if (!arr) {
                        arr = [];
                        item[childSchema.propertyName] = arr;
                    }
                    arr.push(parseConceptualModelElement(child));
                } else {
                    item[childSchema.propertyName] = parseConceptualModelElement(child);
                }
            }
        });

        if (elementSchema.text) {
            item.text = xmlInnerText(element);
        }

        return item;
    };

    var metadataParser = function (handler, text) {
        /// <summary>Parses a metadata document.</summary>
        /// <param name="handler">This handler.</param>
        /// <param name="text" type="String">Metadata text.</param>
        /// <returns>An object representation of the conceptual model.</returns>

        var doc = xmlParse(text);
        var root = xmlFirstChildElement(doc);
        return parseConceptualModelElement(root) || undefined;
    };

    var metadataParser2 = function (xmldocument) {
        /// <summary>Parses a metadata document.</summary>
        /// <param name="handler">This handler.</param>
        /// <param name="text" type="String">Metadata text.</param>
        /// <returns>An object representation of the conceptual model.</returns>

        var root = xmlFirstChildElement(xmldocument);
        return parseConceptualModelElement(root) || undefined;
    };

    odata.metadataHandler = handler(metadataParser, null, xmlMediaType, MAX_DATA_SERVICE_VERSION);
    odata.metadataParser2 = metadataParser2;


    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 contextUrlAnnotation = "@" + odataAnnotationPrefix + "context";

    var bindAnnotation = "@" + odataAnnotationPrefix + "bind";
    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>

        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[contextUrlAnnotation];
        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 || "minimal";
        var baseURI = data[contextUrlAnnotation];
        var payloadInfo = jsonLightPayloadInfo(data, model, inferFeedAsComplexType);
        if (assigned(payloadInfo)) {
            payloadInfo.contentTypeOdata = contentTypeOdata;
        }
        var typeName = null;
        if (payloadInfo) {
            delete data[contextUrlAnnotation];

            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 = ["@odata.type", "@odata.etag", "@odata.mediaEditLink", "@odata.mediaReadLink", "@odata.mediaContentType", "@odata.mediaEtag"];

    var formatJsonLightRequestPayload = function (data) {
        if (!data) {
            return data;
        }

        if (isPrimitive(data)) {
            return data;
        }

        if (isArray(data)) {
            var newArrayData = [];
            var i, len;
            for (i = 0, len = data.length; i < len; i++) {
                newArrayData[i] = formatJsonLightRequestPayload(data[i]);
            }

            return newArrayData;
        }

        var newdata = {};
        for (var property in data) {
            if (isJsonLightSerializableProperty(property)) {
                newdata[property] = formatJsonLightRequestPayload(data[property]);
            }
        }

        return newdata;
    };

    var isJsonLightSerializableProperty = function (property) {
        if (!property) {
            return false;
        }

        if (property.indexOf("@odata.") == -1) {
            return true;
        }

        var i, len;
        for (i = 0, len = jsonLightSerializableMetadata.length; i < len; i++) {
            var name = jsonLightSerializableMetadata[i];
            if (property.indexOf(name) != -1) {
                return true;
            }
        }

        return false;
    };

    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;
        }


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



    var jsonMediaType = "application/json";
    var jsonContentType = contentType(jsonMediaType);

    var jsonReadAdvertisedActionsOrFunctions = function (value) {
        /// <summary>Reads and object containing action or function metadata and maps them into a single array of objects.</summary>
        /// <param name="value" type="Object">Object containing action or function metadata.</param>
        /// <returns type="Array">Array of objects containing metadata for the actions or functions specified in value.</returns>

        var result = [];
        for (var name in value) {
            var i, len;
            for (i = 0, len = value[name].length; i < len; i++) {
                result.push(extend({ metadata: name }, value[name][i]));
            }
        }
        return result;
    };

    var jsonApplyMetadata = function (value, metadata, dateParser, recognizeDates) {
        /// <summary>Applies metadata coming from both the payload and the metadata object to the value.</summary>
        /// <param name="value" type="Object">Data on which the metada is going to be applied.</param>
        /// <param name="metadata">Metadata store; one of edmx, schema, or an array of any of them.</param>
        /// <param name="dateParser" type="function">Function used for parsing datetime values.</param>
        /// <param name="recognizeDates" type="Boolean">
        ///     True if strings formatted as datetime values should be treated as datetime values. False otherwise.
        /// </param>
        /// <returns type="Object">Transformed data.</returns>

        if (value && typeof value === "object") {
            var dataTypeName;
            var valueMetadata = value.__metadata;

            if (valueMetadata) {
                if (valueMetadata.actions) {
                    valueMetadata.actions = jsonReadAdvertisedActionsOrFunctions(valueMetadata.actions);
                }
                if (valueMetadata.functions) {
                    valueMetadata.functions = jsonReadAdvertisedActionsOrFunctions(valueMetadata.functions);
                }
                dataTypeName = valueMetadata && valueMetadata.type;
            }

            var dataType = lookupEntityType(dataTypeName, metadata) || lookupComplexType(dataTypeName, metadata);
            var propertyValue;
            if (dataType) {
                var properties = dataType.property;
                if (properties) {
                    var i, len;
                    for (i = 0, len = properties.length; i < len; i++) {
                        var property = properties[i];
                        var propertyName = property.name;
                        propertyValue = value[propertyName];

                        if (property.type === "Edm.DateTime" || property.type === "Edm.DateTimeOffset") {
                            if (propertyValue) {
                                propertyValue = dateParser(propertyValue);
                                if (!propertyValue) {
                                    throw { message: "Invalid date/time value" };
                                }
                                value[propertyName] = propertyValue;
                            }
                        } else if (property.type === "Edm.Time") {
                            value[propertyName] = parseDuration(propertyValue);
                        }
                    }
                }
            } else if (recognizeDates) {
                for (var name in value) {
                    propertyValue = value[name];
                    if (typeof propertyValue === "string") {
                        value[name] = dateParser(propertyValue) || propertyValue;
                    }
                }
            }
        }
        return value;
    };

    var isJsonLight = function (contentType) {
        /// <summary>Tests where the content type indicates a json light payload.</summary>
        /// <param name="contentType">Object with media type and properties dictionary.</param>
        /// <returns type="Boolean">True is the content type indicates a json light payload. False otherwise.</returns>

        if (contentType) {
            var odata = contentType.properties["odata.metadata"];
            return odata === "none" || odata === "minimal" || odata === "full";
        }

        return false;
    };

    var normalizeServiceDocument = function (data, baseURI) {
        /// <summary>Normalizes a JSON service document to look like an ATOM service document.</summary>
        /// <param name="data" type="Object">Object representation of service documents as deserialized.</param>
        /// <param name="baseURI" type="String">Base URI to resolve relative URIs.</param>
        /// <returns type="Object">An object representation of the service document.</returns>
        var workspace = { collections: [] };

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

            workspace.collections.push(collection);
        }

        return { workspaces: [workspace] };
    };

    // The regular expression corresponds to something like this:
    // /Date(123+60)/
    //
    // This first number is date ticks, the + may be a - and is optional,
    // with the second number indicating a timezone offset in minutes.
    //
    // On the wire, the leading and trailing forward slashes are
    // escaped without being required to so the chance of collisions is reduced;
    // however, by the time we see the objects, the characters already
    // look like regular forward slashes.
    var jsonDateRE = /^\/Date\((-?\d+)(\+|-)?(\d+)?\)\/$/;

    var minutesToOffset = function (minutes) {
        /// <summary>Formats the given minutes into (+/-)hh:mm format.</summary>
        /// <param name="minutes" type="Number">Number of minutes to format.</param>
        /// <returns type="String">The minutes in (+/-)hh:mm format.</returns>

        var sign;
        if (minutes < 0) {
            sign = "-";
            minutes = -minutes;
        } else {
            sign = "+";
        }

        var hours = Math.floor(minutes / 60);
        minutes = minutes - (60 * hours);

        return sign + formatNumberWidth(hours, 2) + ":" + formatNumberWidth(minutes, 2);
    };

    var parseJsonDateString = function (value) {
        /// <summary>Parses the JSON Date representation into a Date object.</summary>
        /// <param name="value" type="String">String value.</param>
        /// <returns type="Date">A Date object if the value matches one; falsy otherwise.</returns>

        var arr = value && jsonDateRE.exec(value);
        if (arr) {
            // 0 - complete results; 1 - ticks; 2 - sign; 3 - minutes
            var result = new Date(parseInt10(arr[1]));
            if (arr[2]) {
                var mins = parseInt10(arr[3]);
                if (arr[2] === "-") {
                    mins = -mins;
                }

                // The offset is reversed to get back the UTC date, which is
                // what the API will eventually have.
                var current = result.getUTCMinutes();
                result.setUTCMinutes(current - mins);
                result.__edmType = "Edm.DateTimeOffset";
                result.__offset = minutesToOffset(mins);
            }
            if (!isNaN(result.valueOf())) {
                return result;
            }
        }

        // Allow undefined to be returned.
    };

    // Some JSON implementations cannot produce the character sequence \/
    // which is needed to format DateTime and DateTimeOffset into the
    // JSON string representation defined by the OData protocol.
    // See the history of this file for a candidate implementation of
    // a 'formatJsonDateString' function.

    var jsonParser = function (handler, text, context) {
        /// <summary>Parses a JSON OData payload.</summary>
        /// <param name="handler">This handler.</param>
        /// <param name="text">Payload text (this parser also handles pre-parsed objects).</param>
        /// <param name="context" type="Object">Object with parsing context.</param>
        /// <returns>An object representation of the OData payload.</returns>

        var dataServiceVersion = context.dataServiceVersion;
        var json = (typeof text === "string") ? window.JSON.parse(text) : text;

        if ((maxVersion("4.0", dataServiceVersion) === dataServiceVersion)) {
            return json;
        }

        return undefined;
    };

    var jsonToString = function (data) {
        /// <summary>Converts the data into a JSON string.</summary>
        /// <param name="data">Data to serialize.</param>
        /// <returns type="String">The JSON string representation of data.</returns>

        var result; // = undefined;
        // Save the current date.toJSON function
        var dateToJSON = Date.prototype.toJSON;
        try {
            // Set our own date.toJSON function
            Date.prototype.toJSON = function () {
                return formatDateTimeOffset(this);
            };
            result = window.JSON.stringify(data, jsonReplacer);
        } finally {
            // Restore the original toJSON function
            Date.prototype.toJSON = dateToJSON;
        }
        return result;
    };

    var jsonSerializer = function (handler, data, context) {
        /// <summary>Serializes the data by returning its string representation.</summary>
        /// <param name="handler">This handler.</param>
        /// <param name="data">Data to serialize.</param>
        /// <param name="context" type="Object">Object with serialization context.</param>
        /// <returns type="String">The string representation of data.</returns>

        var dataServiceVersion = context.dataServiceVersion || "4.0";
        var cType = context.contentType = context.contentType || jsonContentType;

        if (cType && cType.mediaType === jsonContentType.mediaType) {
            context.dataServiceVersion = maxVersion(dataServiceVersion, "4.0");
            var newdata = formatJsonLightRequestPayload(data);
            if (newdata) {
                return window.JSON.stringify(newdata);
            }
        }

        return undefined;
    };

    var jsonReplacer = function (_, value) {
        /// <summary>JSON replacer function for converting a value to its JSON representation.</summary>
        /// <param value type="Object">Value to convert.</param>
        /// <returns type="String">JSON representation of the input value.</returns>
        /// <remarks>
        ///   This method is used during JSON serialization and invoked only by the JSON.stringify function.
        ///   It should never be called directly.
        /// </remarks>

        if (value && value.__edmType === "Edm.Time") {
            return formatDuration(value);
        } else {
            return value;
        }
    };

    var jsonNormalizeData = function (data, baseURI) {
        /// <summary>
        /// Normalizes the specified data into an intermediate representation.
        /// like the latest supported version.
        /// </summary>
        /// <param name="data" optional="false">Data to update.</param>
        /// <param name="baseURI" optional="false">URI to use as the base for normalizing references.</param>

        var isSvcDoc = isComplex(data) && !data.__metadata && isArray(data.EntitySets);
        return isSvcDoc ? normalizeServiceDocument(data, baseURI) : data;
    };

    var jsonHandler = handler(jsonParser, jsonSerializer, jsonMediaType, MAX_DATA_SERVICE_VERSION);
    jsonHandler.recognizeDates = false;
    jsonHandler.useJsonLight = false;
    jsonHandler.inferJsonLightFeedAsObject = false;

    odata.jsonHandler = jsonHandler;




    var batchMediaType = "multipart/mixed";
    var responseStatusRegex = /^HTTP\/1\.\d (\d{3}) (.*)$/i;
    var responseHeaderRegex = /^([^()<>@,;:\\"\/[\]?={} \t]+)\s?:\s?(.*)/;

    var hex16 = function () {
        /// <summary>
        /// Calculates a random 16 bit number and returns it in hexadecimal format.
        /// </summary>
        /// <returns type="String">A 16-bit number in hex format.</returns>

        return Math.floor((1 + Math.random()) * 0x10000).toString(16).substr(1);
    };

    var createBoundary = function (prefix) {
        /// <summary>
        /// Creates a string that can be used as a multipart request boundary.
        /// </summary>
        /// <param name="prefix" type="String" optional="true">String to use as the start of the boundary string</param>
        /// <returns type="String">Boundary string of the format: <prefix><hex16>-<hex16>-<hex16></returns>

        return prefix + hex16() + "-" + hex16() + "-" + hex16();
    };

    var partHandler = function (context) {
        /// <summary>
        /// Gets the handler for data serialization of individual requests / responses in a batch.
        /// </summary>
        /// <param name="context">Context used for data serialization.</param>
        /// <returns>Handler object.</returns>

        return context.handler.partHandler;
    };

    var currentBoundary = function (context) {
        /// <summary>
        /// Gets the current boundary used for parsing the body of a multipart response.
        /// </summary>
        /// <param name="context">Context used for parsing a multipart response.</param>
        /// <returns type="String">Boundary string.</returns>

        var boundaries = context.boundaries;
        return boundaries[boundaries.length - 1];
    };

    var batchParser = function (handler, text, context) {
        /// <summary>Parses a batch response.</summary>
        /// <param name="handler">This handler.</param>
        /// <param name="text" type="String">Batch text.</param>
        /// <param name="context" type="Object">Object with parsing context.</param>
        /// <returns>An object representation of the batch.</returns>

        var boundary = context.contentType.properties["boundary"];
        return { __batchResponses: readBatch(text, { boundaries: [boundary], handlerContext: context }) };
    };

    var batchSerializer = function (handler, data, context) {
        /// <summary>Serializes a batch object representation into text.</summary>
        /// <param name="handler">This handler.</param>
        /// <param name="data" type="Object">Representation of a batch.</param>
        /// <param name="context" type="Object">Object with parsing context.</param>
        /// <returns>An text representation of the batch object; undefined if not applicable.</returns>

        var cType = context.contentType = context.contentType || contentType(batchMediaType);
        if (cType.mediaType === batchMediaType) {
            return writeBatch(data, context);
        }
    };

    var readBatch = function (text, context) {
        /// <summary>
        /// Parses a multipart/mixed response body from from the position defined by the context.
        /// </summary>
        /// <param name="text" type="String" optional="false">Body of the multipart/mixed response.</param>
        /// <param name="context">Context used for parsing.</param>
        /// <returns>Array of objects representing the individual responses.</returns>

        var delimiter = "--" + currentBoundary(context);

        // Move beyond the delimiter and read the complete batch
        readTo(text, context, delimiter);

        // Ignore the incoming line
        readLine(text, context);

        // Read the batch parts
        var responses = [];
        var partEnd;

        while (partEnd !== "--" && context.position < text.length) {
            var partHeaders = readHeaders(text, context);
            var partContentType = contentType(partHeaders["Content-Type"]);

            var changeResponses;
            if (partContentType && partContentType.mediaType === batchMediaType) {
                context.boundaries.push(partContentType.properties["boundary"]);
                try {
                    changeResponses = readBatch(text, context);
                } catch (e) {
                    e.response = readResponse(text, context, delimiter);
                    changeResponses = [e];
                }
                responses.push({ __changeResponses: changeResponses });
                context.boundaries.pop();
                readTo(text, context, "--" + currentBoundary(context));
            } else {
                if (!partContentType || partContentType.mediaType !== "application/http") {
                    throw { message: "invalid MIME part type " };
                }
                // Skip empty line
                readLine(text, context);
                // Read the response
                var response = readResponse(text, context, delimiter);
                try {
                    if (response.statusCode >= 200 && response.statusCode <= 299) {
                        partHandler(context.handlerContext).read(response, context.handlerContext);
                    } else {
                        // Keep track of failed responses and continue processing the batch.
                        response = { message: "HTTP request failed", response: response };
                    }
                } catch (e) {
                    response = e;
                }

                responses.push(response);
            }

            partEnd = text.substr(context.position, 2);

            // Ignore the incoming line.
            readLine(text, context);
        }
        return responses;
    };

    var readHeaders = function (text, context) {
        /// <summary>
        /// Parses the http headers in the text from the position defined by the context.
        /// </summary>
        /// <param name="text" type="String" optional="false">Text containing an http response's headers</param>
        /// <param name="context">Context used for parsing.</param>
        /// <returns>Object containing the headers as key value pairs.</returns>
        /// <remarks>
        /// This function doesn't support split headers and it will stop reading when it hits two consecutive line breaks.
        /// </remarks>

        var headers = {};
        var parts;
        var line;
        var pos;

        do {
            pos = context.position;
            line = readLine(text, context);
            parts = responseHeaderRegex.exec(line);
            if (parts !== null) {
                headers[parts[1]] = parts[2];
            } else {
                // Whatever was found is not a header, so reset the context position.
                context.position = pos;
            }
        } while (line && parts);

        normalizeHeaders(headers);

        return headers;
    };

    var readResponse = function (text, context, delimiter) {
        /// <summary>
        /// Parses an HTTP response.
        /// </summary>
        /// <param name="text" type="String" optional="false">Text representing the http response.</param>
        /// <param name="context" optional="false">Context used for parsing.</param>
        /// <param name="delimiter" type="String" optional="false">String used as delimiter of the multipart response parts.</param>
        /// <returns>Object representing the http response.</returns>

        // Read the status line.
        var pos = context.position;
        var match = responseStatusRegex.exec(readLine(text, context));

        var statusCode;
        var statusText;
        var headers;

        if (match) {
            statusCode = match[1];
            statusText = match[2];
            headers = readHeaders(text, context);
            readLine(text, context);
        } else {
            context.position = pos;
        }

        return {
            statusCode: statusCode,
            statusText: statusText,
            headers: headers,
            body: readTo(text, context, "\r\n" + delimiter)
        };
    };

    var readLine = function (text, context) {
        /// <summary>
        /// Returns a substring from the position defined by the context up to the next line break (CRLF).
        /// </summary>
        /// <param name="text" type="String" optional="false">Input string.</param>
        /// <param name="context" optional="false">Context used for reading the input string.</param>
        /// <returns type="String">Substring to the first ocurrence of a line break or null if none can be found. </returns>

        return readTo(text, context, "\r\n");
    };

    var readTo = function (text, context, str) {
        /// <summary>
        /// Returns a substring from the position given by the context up to value defined by the str parameter and increments the position in the context.
        /// </summary>
        /// <param name="text" type="String" optional="false">Input string.</param>
        /// <param name="context" type="Object" optional="false">Context used for reading the input string.</param>
        /// <param name="str" type="String" optional="true">Substring to read up to.</param>
        /// <returns type="String">Substring to the first ocurrence of str or the end of the input string if str is not specified. Null if the marker is not found.</returns>

        var start = context.position || 0;
        var end = text.length;
        if (str) {
            end = text.indexOf(str, start);
            if (end === -1) {
                return null;
            }
            context.position = end + str.length;
        } else {
            context.position = end;
        }

        return text.substring(start, end);
    };

    var writeBatch = function (data, context) {
        /// <summary>
        /// Serializes a batch request object to a string.
        /// </summary>
        /// <param name="data" optional="false">Batch request object in payload representation format</param>
        /// <param name="context" optional="false">Context used for the serialization</param>
        /// <returns type="String">String representing the batch request</returns>

        if (!isBatch(data)) {
            throw { message: "Data is not a batch object." };
        }

        var batchBoundary = createBoundary("batch_");
        var batchParts = data.__batchRequests;
        var batch = "";
        var i, len;
        for (i = 0, len = batchParts.length; i < len; i++) {
            batch += writeBatchPartDelimiter(batchBoundary, false) +
                     writeBatchPart(batchParts[i], context);
        }
        batch += writeBatchPartDelimiter(batchBoundary, true);

        // Register the boundary with the request content type.
        var contentTypeProperties = context.contentType.properties;
        contentTypeProperties.boundary = batchBoundary;

        return batch;
    };

    var writeBatchPartDelimiter = function (boundary, close) {
        /// <summary>
        /// Creates the delimiter that indicates that start or end of an individual request.
        /// </summary>
        /// <param name="boundary" type="String" optional="false">Boundary string used to indicate the start of the request</param>
        /// <param name="close" type="Boolean">Flag indicating that a close delimiter string should be generated</param>
        /// <returns type="String">Delimiter string</returns>

        var result = "\r\n--" + boundary;
        if (close) {
            result += "--";
        }

        return result + "\r\n";
    };

    var writeBatchPart = function (part, context, nested) {
        /// <summary>
        /// Serializes a part of a batch request to a string. A part can be either a GET request or
        /// a change set grouping several CUD (create, update, delete) requests.
        /// </summary>
        /// <param name="part" optional="false">Request or change set object in payload representation format</param>
        /// <param name="context" optional="false">Object containing context information used for the serialization</param>
        /// <param name="nested" type="boolean" optional="true">Flag indicating that the part is nested inside a change set</param>
        /// <returns type="String">String representing the serialized part</returns>
        /// <remarks>
        /// A change set is an array of request objects and they cannot be nested inside other change sets.
        /// </remarks>

        var changeSet = part.__changeRequests;
        var result;
        if (isArray(changeSet)) {
            if (nested) {
                throw { message: "Not Supported: change set nested in other change set" };
            }

            var changeSetBoundary = createBoundary("changeset_");
            result = "Content-Type: " + batchMediaType + "; boundary=" + changeSetBoundary + "\r\n";
            var i, len;
            for (i = 0, len = changeSet.length; i < len; i++) {
                result += writeBatchPartDelimiter(changeSetBoundary, false) +
                     writeBatchPart(changeSet[i], context, true);
            }

            result += writeBatchPartDelimiter(changeSetBoundary, true);
        } else {
            result = "Content-Type: application/http\r\nContent-Transfer-Encoding: binary\r\n\r\n";
            var partContext = extend({}, context);
            partContext.handler = handler;
            partContext.request = part;
            partContext.contentType = null;

            prepareRequest(part, partHandler(context), partContext);
            result += writeRequest(part);
        }

        return result;
    };

    var writeRequest = function (request) {
        /// <summary>
        /// Serializes a request object to a string.
        /// </summary>
        /// <param name="request" optional="false">Request object to serialize</param>
        /// <returns type="String">String representing the serialized request</returns>

        var result = (request.method ? request.method : "GET") + " " + request.requestUri + " HTTP/1.1\r\n";
        for (var name in request.headers) {
            if (request.headers[name]) {
                result = result + name + ": " + request.headers[name] + "\r\n";
            }
        }

        result += "\r\n";

        if (request.body) {
            result += request.body;
        }

        return result;
    };

    odata.batchHandler = handler(batchParser, batchSerializer, batchMediaType, MAX_DATA_SERVICE_VERSION);


    
    // to do: disable atom scenario
    var handlers = [odata.jsonHandler/*, odata.atomHandler*/, odata.xmlHandler, odata.textHandler];

    var dispatchHandler = function (handlerMethod, requestOrResponse, context) {
        /// <summary>Dispatches an operation to handlers.</summary>
        /// <param name="handlerMethod" type="String">Name of handler method to invoke.</param>
        /// <param name="requestOrResponse" type="Object">request/response argument for delegated call.</param>
        /// <param name="context" type="Object">context argument for delegated call.</param>

        var i, len;
        for (i = 0, len = handlers.length; i < len && !handlers[i][handlerMethod](requestOrResponse, context); i++) {
        }

        if (i === len) {
            throw { message: "no handler for data" };
        }
    };

    odata.defaultSuccess = function (data) {
        /// <summary>Default success handler for OData.</summary>
        /// <param name="data">Data to process.</param>

        window.alert(window.JSON.stringify(data));
    };

    odata.defaultError = throwErrorCallback;

    odata.defaultHandler = {
        read: function (response, context) {
            /// <summary>Reads the body of the specified response by delegating to JSON and ATOM handlers.</summary>
            /// <param name="response">Response object.</param>
            /// <param name="context">Operation context.</param>

            if (response && assigned(response.body) && response.headers["Content-Type"]) {
                dispatchHandler("read", response, context);
            }
        },

        write: function (request, context) {
            /// <summary>Write the body of the specified request by delegating to JSON and ATOM handlers.</summary>
            /// <param name="request">Reques tobject.</param>
            /// <param name="context">Operation context.</param>

            dispatchHandler("write", request, context);
        },

        maxDataServiceVersion: MAX_DATA_SERVICE_VERSION,
        accept: "application/json;q=0.9, application/atomsvc+xml;q=0.8, */*;q=0.1"
    };

    odata.defaultMetadata = [];

    odata.read = function (urlOrRequest, success, error, handler, httpClient, metadata) {
        /// <summary>Reads data from the specified URL.</summary>
        /// <param name="urlOrRequest">URL to read data from.</param>
        /// <param name="success" type="Function" optional="true">Callback for a successful read operation.</param>
        /// <param name="error" type="Function" optional="true">Callback for handling errors.</param>
        /// <param name="handler" type="Object" optional="true">Handler for data serialization.</param>
        /// <param name="httpClient" type="Object" optional="true">HTTP client layer.</param>
        /// <param name="metadata" type="Object" optional="true">Conceptual metadata for this request.</param>

        var request;
        if (urlOrRequest instanceof String || typeof urlOrRequest === "string") {
            request = { requestUri: urlOrRequest };
        } else {
            request = urlOrRequest;
        }

        return odata.request(request, success, error, handler, httpClient, metadata);
    };

    odata.request = function (request, success, error, handler, httpClient, metadata) {
        /// <summary>Sends a request containing OData payload to a server.</summary>
        /// <param name="request" type="Object">Object that represents the request to be sent.</param>
        /// <param name="success" type="Function" optional="true">Callback for a successful read operation.</param>
        /// <param name="error" type="Function" optional="true">Callback for handling errors.</param>
        /// <param name="handler" type="Object" optional="true">Handler for data serialization.</param>
        /// <param name="httpClient" type="Object" optional="true">HTTP client layer.</param>
        /// <param name="metadata" type="Object" optional="true">Conceptual metadata for this request.</param>

        success = success || odata.defaultSuccess;
        error = error || odata.defaultError;
        handler = handler || odata.defaultHandler;
        httpClient = httpClient || odata.defaultHttpClient;
        metadata = metadata || odata.defaultMetadata;

        // Augment the request with additional defaults.
        request.recognizeDates = defined(request.recognizeDates, odata.jsonHandler.recognizeDates);
        request.callbackParameterName = defined(request.callbackParameterName, odata.defaultHttpClient.callbackParameterName);
        request.formatQueryString = defined(request.formatQueryString, odata.defaultHttpClient.formatQueryString);
        request.enableJsonpCallback = defined(request.enableJsonpCallback, odata.defaultHttpClient.enableJsonpCallback);
        request.useJsonLight = defined(request.useJsonLight, odata.jsonHandler.enableJsonpCallback);
        request.inferJsonLightFeedAsObject = defined(request.inferJsonLightFeedAsObject, odata.jsonHandler.inferJsonLightFeedAsObject);

        // Create the base context for read/write operations, also specifying complete settings.
        var context = {
            metadata: metadata,
            recognizeDates: request.recognizeDates,
            callbackParameterName: request.callbackParameterName,
            formatQueryString: request.formatQueryString,
            enableJsonpCallback: request.enableJsonpCallback,
            useJsonLight: request.useJsonLight,
            inferJsonLightFeedAsObject: request.inferJsonLightFeedAsObject
        };

        try {
            prepareRequest(request, handler, context);
            return invokeRequest(request, success, error, handler, httpClient, context);
        } catch (err) {
            error(err);
        }
    };

    odata.parseMetadata = function (csdlMetadataDocument) {
        /// <summary>Parses the csdl metadata to DataJS metatdata format. This method can be used when the metadata is retrieved using something other than DataJS</summary>
        /// <param name="atomMetadata" type="string">A string that represents the entire csdl metadata.</param>
        /// <returns type="Object">An object that has the representation of the metadata in Datajs format.</returns>

        return metadataParser(null, csdlMetadataDocument);
    };

    // Configure the batch handler to use the default handler for the batch parts.
    odata.batchHandler.partHandler = odata.defaultHandler;



    var localStorage = null;

    var domStoreDateToJSON = function () {
        /// <summary>Converts a Date object into an object representation friendly to JSON serialization.</summary>
        /// <returns type="Object">Object that represents the Date.</returns>
        /// <remarks>
        ///   This method is used to override the Date.toJSON method and is called only by
        ///   JSON.stringify.  It should never be called directly.
        /// </remarks>

        var newValue = { v: this.valueOf(), t: "[object Date]" };
        // Date objects might have extra properties on them so we save them.
        for (var name in this) {
            newValue[name] = this[name];
        }
        return newValue;
    };

    var domStoreJSONToDate = function (_, value) {
        /// <summary>JSON reviver function for converting an object representing a Date in a JSON stream to a Date object</summary>
        /// <param value="Object">Object to convert.</param>
        /// <returns type="Date">Date object.</returns>
        /// <remarks>
        ///   This method is used during JSON parsing and invoked only by the reviver function.
        ///   It should never be called directly.
        /// </remarks>

        if (value && value.t === "[object Date]") {
            var newValue = new Date(value.v);
            for (var name in value) {
                if (name !== "t" && name !== "v") {
                    newValue[name] = value[name];
                }
            }
            value = newValue;
        }
        return value;
    };

    var qualifyDomStoreKey = function (store, key) {
        /// <summary>Qualifies the key with the name of the store.</summary>
        /// <param name="store" type="Object">Store object whose name will be used for qualifying the key.</param>
        /// <param name="key" type="String">Key string.</param>
        /// <returns type="String">Fully qualified key string.</returns>

        return store.name + "#!#" + key;
    };

    var unqualifyDomStoreKey = function (store, key) {
        /// <summary>Gets the key part of a fully qualified key string.</summary>
        /// <param name="store" type="Object">Store object whose name will be used for qualifying the key.</param>
        /// <param name="key" type="String">Fully qualified key string.</param>
        /// <returns type="String">Key part string</returns>

        return key.replace(store.name + "#!#", "");
    };

    var DomStore = function (name) {
        /// <summary>Constructor for store objects that use DOM storage as the underlying mechanism.</summary>
        /// <param name="name" type="String">Store name.</param>
        this.name = name;
    };

    DomStore.create = function (name) {
        /// <summary>Creates a store object that uses DOM Storage as its underlying mechanism.</summary>
        /// <param name="name" type="String">Store name.</param>
        /// <returns type="Object">Store object.</returns>

        if (DomStore.isSupported()) {
            localStorage = localStorage || window.localStorage;
            return new DomStore(name);
        }

        throw { message: "Web Storage not supported by the browser" };
    };

    DomStore.isSupported = function () {
        /// <summary>Checks whether the underlying mechanism for this kind of store objects is supported by the browser.</summary>
        /// <returns type="Boolean">True if the mechanism is supported by the browser; otherwise false.</summary>
        return !!window.localStorage;
    };

    DomStore.prototype.add = function (key, value, success, error) {
        /// <summary>Adds a new value identified by a key to the store.</summary>
        /// <param name="key" type="String">Key string.</param>
        /// <param name="value">Value that is going to be added to the store.</param>
        /// <param name="success" type="Function" optional="no">Callback for a successful add operation.</param>
        /// <param name="error" type="Function" optional="yes">Callback for handling errors. If not specified then store.defaultError is invoked.</param>
        /// <remarks>
        ///    This method errors out if the store already contains the specified key.
        /// </remarks>

        error = error || this.defaultError;
        var store = this;
        this.contains(key, function (contained) {
            if (!contained) {
                store.addOrUpdate(key, value, success, error);
            } else {
                delay(error, { message: "key already exists", key: key });
            }
        }, error);
    };

    DomStore.prototype.addOrUpdate = function (key, value, success, error) {
        /// <summary>Adds or updates a value identified by a key to the store.</summary>
        /// <param name="key" type="String">Key string.</param>
        /// <param name="value">Value that is going to be added or updated to the store.</param>
        /// <param name="success" type="Function" optional="no">Callback for a successful add or update operation.</param>
        /// <param name="error" type="Function" optional="yes">Callback for handling errors. If not specified then store.defaultError is invoked.</param>
        /// <remarks>
        ///   This method will overwrite the key's current value if it already exists in the store; otherwise it simply adds the new key and value.
        /// </remarks>

        error = error || this.defaultError;

        if (key instanceof Array) {
            error({ message: "Array of keys not supported" });
        } else {
            var fullKey = qualifyDomStoreKey(this, key);
            var oldDateToJSON = Date.prototype.toJSON;
            try {
                var storedValue = value;
                if (storedValue !== undefined) {
                    // Dehydrate using json
                    Date.prototype.toJSON = domStoreDateToJSON;
                    storedValue = window.JSON.stringify(value);
                }
                // Save the json string.
                localStorage.setItem(fullKey, storedValue);
                delay(success, key, value);
            }
            catch (e) {
                if (e.code === 22 || e.number === 0x8007000E) {
                    delay(error, { name: "QUOTA_EXCEEDED_ERR", error: e });
                } else {
                    delay(error, e);
                }
            }
            finally {
                Date.prototype.toJSON = oldDateToJSON;
            }
        }
    };

    DomStore.prototype.clear = function (success, error) {
        /// <summary>Removes all the data associated with this store object.</summary>
        /// <param name="success" type="Function" optional="no">Callback for a successful clear operation.</param>
        /// <param name="error" type="Function" optional="yes">Callback for handling errors. If not specified then store.defaultError is invoked.</param>
        /// <remarks>
        ///    In case of an error, this method will not restore any keys that might have been deleted at that point.
        /// </remarks>

        error = error || this.defaultError;
        try {
            var i = 0, len = localStorage.length;
            while (len > 0 && i < len) {
                var fullKey = localStorage.key(i);
                var key = unqualifyDomStoreKey(this, fullKey);
                if (fullKey !== key) {
                    localStorage.removeItem(fullKey);
                    len = localStorage.length;
                } else {
                    i++;
                }
            }
            delay(success);
        }
        catch (e) {
            delay(error, e);
        }
    };

    DomStore.prototype.close = function () {
        /// <summary>This function does nothing in DomStore as it does not have a connection model</summary>
    };

    DomStore.prototype.contains = function (key, success, error) {
        /// <summary>Checks whether a key exists in the store.</summary>
        /// <param name="key" type="String">Key string.</param>
        /// <param name="success" type="Function" optional="no">Callback indicating whether the store contains the key or not.</param>
        /// <param name="error" type="Function" optional="yes">Callback for handling errors. If not specified then store.defaultError is invoked.</param>
        error = error || this.defaultError;
        try {
            var fullKey = qualifyDomStoreKey(this, key);
            var value = localStorage.getItem(fullKey);
            delay(success, value !== null);
        } catch (e) {
            delay(error, e);
        }
    };

    DomStore.prototype.defaultError = throwErrorCallback;

    DomStore.prototype.getAllKeys = function (success, error) {
        /// <summary>Gets all the keys that exist in the store.</summary>
        /// <param name="success" type="Function" optional="no">Callback for a successful get operation.</param>
        /// <param name="error" type="Function" optional="yes">Callback for handling errors. If not specified then store.defaultError is invoked.</param>

        error = error || this.defaultError;

        var results = [];
        var i, len;

        try {
            for (i = 0, len = localStorage.length; i < len; i++) {
                var fullKey = localStorage.key(i);
                var key = unqualifyDomStoreKey(this, fullKey);
                if (fullKey !== key) {
                    results.push(key);
                }
            }
            delay(success, results);
        }
        catch (e) {
            delay(error, e);
        }
    };

    /// <summary>Identifies the underlying mechanism used by the store.</summary>
    DomStore.prototype.mechanism = "dom";

    DomStore.prototype.read = function (key, success, error) {
        /// <summary>Reads the value associated to a key in the store.</summary>
        /// <param name="key" type="String">Key string.</param>
        /// <param name="success" type="Function" optional="no">Callback for a successful reads operation.</param>
        /// <param name="error" type="Function" optional="yes">Callback for handling errors. If not specified then store.defaultError is invoked.</param>
        error = error || this.defaultError;

        if (key instanceof Array) {
            error({ message: "Array of keys not supported" });
        } else {
            try {
                var fullKey = qualifyDomStoreKey(this, key);
                var value = localStorage.getItem(fullKey);
                if (value !== null && value !== "undefined") {
                    // Hydrate using json
                    value = window.JSON.parse(value, domStoreJSONToDate);
                }
                else {
                    value = undefined;
                }
                delay(success, key, value);
            } catch (e) {
                delay(error, e);
            }
        }
    };

    DomStore.prototype.remove = function (key, success, error) {
        /// <summary>Removes a key and its value from the store.</summary>
        /// <param name="key" type="String">Key string.</param>
        /// <param name="success" type="Function" optional="no">Callback for a successful remove operation.</param>
        /// <param name="error" type="Function" optional="yes">Callback for handling errors. If not specified then store.defaultError is invoked.</param>
        error = error || this.defaultError;

        if (key instanceof Array) {
            error({ message: "Batches not supported" });
        } else {
            try {
                var fullKey = qualifyDomStoreKey(this, key);
                localStorage.removeItem(fullKey);
                delay(success);
            } catch (e) {
                delay(error, e);
            }
        }
    };

    DomStore.prototype.update = function (key, value, success, error) {
        /// <summary>Updates the value associated to a key in the store.</summary>
        /// <param name="key" type="String">Key string.</param>
        /// <param name="value">New value.</param>
        /// <param name="success" type="Function" optional="no">Callback for a successful update operation.</param>
        /// <param name="error" type="Function" optional="yes">Callback for handling errors. If not specified then store.defaultError is invoked.</param>
        /// <remarks>
        ///    This method errors out if the specified key is not found in the store.
        /// </remarks>

        error = error || this.defaultError;
        var store = this;
        this.contains(key, function (contained) {
            if (contained) {
                store.addOrUpdate(key, value, success, error);
            } else {
                delay(error, { message: "key not found", key: key });
            }
        }, error);
    };



    var indexedDB = window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.indexedDB;
    var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
    var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || {};

    var IDBT_READ_ONLY = IDBTransaction.READ_ONLY || "readonly";
    var IDBT_READ_WRITE = IDBTransaction.READ_WRITE || "readwrite";

    var getError = function (error, defaultError) {
        /// <summary>Returns either a specific error handler or the default error handler</summary>
        /// <param name="error" type="Function">The specific error handler</param>
        /// <param name="defaultError" type="Function">The default error handler</param>
        /// <returns type="Function">The error callback</returns>

        return function (e) {
            var errorFunc = error || defaultError;
            if (!errorFunc) {
                return;
            }

            // Old api quota exceeded error support.
            if (Object.prototype.toString.call(e) === "[object IDBDatabaseException]") {
                if (e.code === 11 /* IndexedDb disk quota exceeded */) {
                    errorFunc({ name: "QuotaExceededError", error: e });
                    return;
                }
                errorFunc(e);
                return;
            }

            var errName;
            try {
                var errObj = e.target.error || e;
                errName = errObj.name;
            } catch (ex) {
                errName = (e.type === "blocked") ? "IndexedDBBlocked" : "UnknownError";
            }
            errorFunc({ name: errName, error: e });
        };
    };

    var openStoreDb = function (store, success, error) {
        /// <summary>Opens the store object's indexed db database.</summary>
        /// <param name="store" type="IndexedDBStore">The store object</param>
        /// <param name="success" type="Function">The success callback</param>
        /// <param name="error" type="Function">The error callback</param>

        var storeName = store.name;
        var dbName = "_datajs_" + storeName;

        var request = indexedDB.open(dbName);
        request.onblocked = error;
        request.onerror = error;

        request.onupgradeneeded = function () {
            var db = request.result;
            if (!db.objectStoreNames.contains(storeName)) {
                db.createObjectStore(storeName);
            }
        };

        request.onsuccess = function (event) {
            var db = request.result;
            if (!db.objectStoreNames.contains(storeName)) {
                // Should we use the old style api to define the database schema?
                if ("setVersion" in db) {
                    var versionRequest = db.setVersion("1.0");
                    versionRequest.onsuccess = function () {
                        var transaction = versionRequest.transaction;
                        transaction.oncomplete = function () {
                            success(db);
                        };
                        db.createObjectStore(storeName, null, false);
                    };
                    versionRequest.onerror = error;
                    versionRequest.onblocked = error;
                    return;
                }

                // The database doesn't have the expected store.
                // Fabricate an error object for the event for the schema mismatch
                // and error out.
                event.target.error = { name: "DBSchemaMismatch" };
                error(event);
                return;
            }

            db.onversionchange = function(event) {
                event.target.close();
            };
            success(db);
        };
    };

    var openTransaction = function (store, mode, success, error) {
        /// <summary>Opens a new transaction to the store</summary>
        /// <param name="store" type="IndexedDBStore">The store object</param>
        /// <param name="mode" type="Short">The read/write mode of the transaction (constants from IDBTransaction)</param>
        /// <param name="success" type="Function">The success callback</param>
        /// <param name="error" type="Function">The error callback</param>

        var storeName = store.name;
        var storeDb = store.db;
        var errorCallback = getError(error, store.defaultError);

        if (storeDb) {
            success(storeDb.transaction(storeName, mode));
            return;
        }

        openStoreDb(store, function (db) {
            store.db = db;
            success(db.transaction(storeName, mode));
        }, errorCallback);
    };

    var IndexedDBStore = function (name) {
        /// <summary>Creates a new IndexedDBStore.</summary>
        /// <param name="name" type="String">The name of the store.</param>
        /// <returns type="Object">The new IndexedDBStore.</returns>
        this.name = name;
    };

    IndexedDBStore.create = function (name) {
        /// <summary>Creates a new IndexedDBStore.</summary>
        /// <param name="name" type="String">The name of the store.</param>
        /// <returns type="Object">The new IndexedDBStore.</returns>
        if (IndexedDBStore.isSupported()) {
            return new IndexedDBStore(name);
        }

        throw { message: "IndexedDB is not supported on this browser" };
    };

    IndexedDBStore.isSupported = function () {
        /// <summary>Returns whether IndexedDB is supported.</summary>
        /// <returns type="Boolean">True if IndexedDB is supported, false otherwise.</returns>
        return !!indexedDB;
    };

    IndexedDBStore.prototype.add = function (key, value, success, error) {
        /// <summary>Adds a key/value pair to the store</summary>
        /// <param name="key" type="String">The key</param>
        /// <param name="value" type="Object">The value</param>
        /// <param name="success" type="Function">The success callback</param>
        /// <param name="error" type="Function">The error callback</param>
        var name = this.name;
        var defaultError = this.defaultError;
        var keys = [];
        var values = [];

        if (key instanceof Array) {
            keys = key;
            values = value;
        } else {
            keys = [key];
            values = [value];
        }

        openTransaction(this, IDBT_READ_WRITE, function (transaction) {
            transaction.onabort = getError(error, defaultError, key, "add");
            transaction.oncomplete = function () {
                if (key instanceof Array) {
                    success(keys, values);
                } else {
                    success(key, value);
                }
            };

            for (var i = 0; i < keys.length && i < values.length; i++) {
                transaction.objectStore(name).add({ v: values[i] }, keys[i]);
            }
        }, error);
    };

    IndexedDBStore.prototype.addOrUpdate = function (key, value, success, error) {
        /// <summary>Adds or updates a key/value pair in the store</summary>
        /// <param name="key" type="String">The key</param>
        /// <param name="value" type="Object">The value</param>
        /// <param name="success" type="Function">The success callback</param>
        /// <param name="error" type="Function">The error callback</param>
        var name = this.name;
        var defaultError = this.defaultError;
        var keys = [];
        var values = [];

        if (key instanceof Array) {
            keys = key;
            values = value;
        } else {
            keys = [key];
            values = [value];
        }

        openTransaction(this, IDBT_READ_WRITE, function (transaction) {
            transaction.onabort = getError(error, defaultError);
            transaction.oncomplete = function () {
                if (key instanceof Array) {
                    success(keys, values);
                } else {
                    success(key, value);
                }
            };

            for (var i = 0; i < keys.length && i < values.length; i++) {
                var record = { v: values[i] };
                transaction.objectStore(name).put(record, keys[i]);
            }
        }, error);
    };

    IndexedDBStore.prototype.clear = function (success, error) {
        /// <summary>Clears the store</summary>
        /// <param name="success" type="Function">The success callback</param>
        /// <param name="error" type="Function">The error callback</param>
        var name = this.name;
        var defaultError = this.defaultError;
        openTransaction(this, IDBT_READ_WRITE, function (transaction) {
            transaction.onerror = getError(error, defaultError);
            transaction.oncomplete = function () {
                success();
            };

            transaction.objectStore(name).clear();
        }, error);
    };

    IndexedDBStore.prototype.close = function () {
        /// <summary>Closes the connection to the database</summary>
        if (this.db) {
            this.db.close();
            this.db = null;
        }
    };

    IndexedDBStore.prototype.contains = function (key, success, error) {
        /// <summary>Returns whether the store contains a key</summary>
        /// <param name="key" type="String">The key</param>
        /// <param name="success" type="Function">The success callback</param>
        /// <param name="error" type="Function">The error callback</param>
        var name = this.name;
        var defaultError = this.defaultError;
        openTransaction(this, IDBT_READ_ONLY, function (transaction) {
            var objectStore = transaction.objectStore(name);
            var request = objectStore["get"](key);

            transaction.oncomplete = function () {
                success(!!request.result);
            };
            transaction.onerror = getError(error, defaultError);
        }, error);
    };

    IndexedDBStore.prototype.defaultError = throwErrorCallback;

    IndexedDBStore.prototype.getAllKeys = function (success, error) {
        /// <summary>Gets all the keys from the store</summary>
        /// <param name="success" type="Function">The success callback</param>
        /// <param name="error" type="Function">The error callback</param>
        var name = this.name;
        var defaultError = this.defaultError;
        openTransaction(this, IDBT_READ_WRITE, function (transaction) {
            var results = [];

            transaction.oncomplete = function () {
                success(results);
            };

            var request = transaction.objectStore(name).openCursor();

            request.onerror = getError(error, defaultError);
            request.onsuccess = function (event) {
                var cursor = event.target.result;
                if (cursor) {
                    results.push(cursor.key);
                    // Some tools have issues because continue is a javascript reserved word.
                    cursor["continue"].call(cursor);
                }
            };
        }, error);
    };

    /// <summary>Identifies the underlying mechanism used by the store.</summary>
    IndexedDBStore.prototype.mechanism = "indexeddb";

    IndexedDBStore.prototype.read = function (key, success, error) {
        /// <summary>Reads the value for the specified key</summary>
        /// <param name="key" type="String">The key</param>
        /// <param name="success" type="Function">The success callback</param>
        /// <param name="error" type="Function">The error callback</param>
        /// <remarks>If the key does not exist, the success handler will be called with value = undefined</remarks>
        var name = this.name;
        var defaultError = this.defaultError;
        var keys = (key instanceof Array) ? key : [key];

        openTransaction(this, IDBT_READ_ONLY, function (transaction) {
            var values = [];

            transaction.onerror = getError(error, defaultError, key, "read");
            transaction.oncomplete = function () {
                if (key instanceof Array) {
                    success(keys, values);
                } else {
                    success(keys[0], values[0]);
                }
            };

            for (var i = 0; i < keys.length; i++) {
                // Some tools have issues because get is a javascript reserved word. 
                var objectStore = transaction.objectStore(name);
                var request = objectStore["get"].call(objectStore, keys[i]);
                request.onsuccess = function (event) {
                    var record = event.target.result;
                    values.push(record ? record.v : undefined);
                };
            }
        }, error);
    };

    IndexedDBStore.prototype.remove = function (key, success, error) {
        /// <summary>Removes the specified key from the store</summary>
        /// <param name="key" type="String">The key</param>
        /// <param name="success" type="Function">The success callback</param>
        /// <param name="error" type="Function">The error callback</param>
        var name = this.name;
        var defaultError = this.defaultError;
        var keys = (key instanceof Array) ? key : [key];

        openTransaction(this, IDBT_READ_WRITE, function (transaction) {
            transaction.onerror = getError(error, defaultError);
            transaction.oncomplete = function () {
                success();
            };

            for (var i = 0; i < keys.length; i++) {
                // Some tools have issues because continue is a javascript reserved word.
                var objectStore = transaction.objectStore(name);
                objectStore["delete"].call(objectStore, keys[i]);
            }
        }, error);
    };

    IndexedDBStore.prototype.update = function (key, value, success, error) {
        /// <summary>Updates a key/value pair in the store</summary>
        /// <param name="key" type="String">The key</param>
        /// <param name="value" type="Object">The value</param>
        /// <param name="success" type="Function">The success callback</param>
        /// <param name="error" type="Function">The error callback</param>
        var name = this.name;
        var defaultError = this.defaultError;
        var keys = [];
        var values = [];

        if (key instanceof Array) {
            keys = key;
            values = value;
        } else {
            keys = [key];
            values = [value];
        }

        openTransaction(this, IDBT_READ_WRITE, function (transaction) {
            transaction.onabort = getError(error, defaultError);
            transaction.oncomplete = function () {
                if (key instanceof Array) {
                    success(keys, values);
                } else {
                    success(key, value);
                }
            };

            for (var i = 0; i < keys.length && i < values.length; i++) {
                var request = transaction.objectStore(name).openCursor(IDBKeyRange.only(keys[i]));
                var record = { v: values[i] };
                request.pair = { key: keys[i], value: record };
                request.onsuccess = function (event) {
                    var cursor = event.target.result;
                    if (cursor) {
                        cursor.update(event.target.pair.value);
                    } else {
                        transaction.abort();
                    }
                };
            }
        }, error);
    };



    var MemoryStore = function (name) {
        /// <summary>Constructor for store objects that use a sorted array as the underlying mechanism.</summary>
        /// <param name="name" type="String">Store name.</param>

        var holes = [];
        var items = [];
        var keys = {};

        this.name = name;

        var getErrorCallback = function (error) {
            return error || this.defaultError;
        };

        var validateKeyInput = function (key, error) {
            /// <summary>Validates that the specified key is not undefined, not null, and not an array</summary>
            /// <param name="key">Key value.</param>
            /// <param name="error" type="Function">Error callback.</param>
            /// <returns type="Boolean">True if the key is valid. False if the key is invalid and the error callback has been queued for execution.</returns>

            var messageString;

            if (key instanceof Array) {
                messageString = "Array of keys not supported";
            }

            if (key === undefined || key === null) {
                messageString = "Invalid key";
            }

            if (messageString) {
                delay(error, { message: messageString });
                return false;
            }
            return true;
        };

        this.add = function (key, value, success, error) {
            /// <summary>Adds a new value identified by a key to the store.</summary>
            /// <param name="key" type="String">Key string.</param>
            /// <param name="value">Value that is going to be added to the store.</param>
            /// <param name="success" type="Function" optional="no">Callback for a successful add operation.</param>
            /// <param name="error" type="Function" optional="yes">Callback for handling errors. If not specified then store.defaultError is invoked.</param>
            /// <remarks>
            ///    This method errors out if the store already contains the specified key.
            /// </remarks>

            error = getErrorCallback(error);

            if (validateKeyInput(key, error)) {
                if (!keys.hasOwnProperty(key)) {
                    this.addOrUpdate(key, value, success, error);
                } else {
                    error({ message: "key already exists", key: key });
                }
            }
        };

        this.addOrUpdate = function (key, value, success, error) {
            /// <summary>Adds or updates a value identified by a key to the store.</summary>
            /// <param name="key" type="String">Key string.</param>
            /// <param name="value">Value that is going to be added or updated to the store.</param>
            /// <param name="success" type="Function" optional="no">Callback for a successful add or update operation.</param>
            /// <param name="error" type="Function" optional="yes">Callback for handling errors. If not specified then store.defaultError is invoked.</param>
            /// <remarks>
            ///   This method will overwrite the key's current value if it already exists in the store; otherwise it simply adds the new key and value.
            /// </remarks>

            error = getErrorCallback(error);

            if (validateKeyInput(key, error)) {
                var index = keys[key];
                if (index === undefined) {
                    if (holes.length > 0) {
                        index = holes.splice(0, 1);
                    } else {
                        index = items.length;
                    }
                }
                items[index] = value;
                keys[key] = index;
                delay(success, key, value);
            }
        };

        this.clear = function (success) {
            /// <summary>Removes all the data associated with this store object.</summary>
            /// <param name="success" type="Function" optional="no">Callback for a successful clear operation.</param>

            items = [];
            keys = {};
            holes = [];

            delay(success);
        };

        this.contains = function (key, success) {
            /// <summary>Checks whether a key exists in the store.</summary>
            /// <param name="key" type="String">Key string.</param>
            /// <param name="success" type="Function" optional="no">Callback indicating whether the store contains the key or not.</param>

            var contained = keys.hasOwnProperty(key);
            delay(success, contained);
        };

        this.getAllKeys = function (success) {
            /// <summary>Gets all the keys that exist in the store.</summary>
            /// <param name="success" type="Function" optional="no">Callback for a successful get operation.</param>

            var results = [];
            for (var name in keys) {
                results.push(name);
            }
            delay(success, results);
        };

        this.read = function (key, success, error) {
            /// <summary>Reads the value associated to a key in the store.</summary>
            /// <param name="key" type="String">Key string.</param>
            /// <param name="success" type="Function" optional="no">Callback for a successful reads operation.</param>
            /// <param name="error" type="Function" optional="yes">Callback for handling errors. If not specified then store.defaultError is invoked.</param>
            error = getErrorCallback(error);

            if (validateKeyInput(key, error)) {
                var index = keys[key];
                delay(success, key, items[index]);
            }
        };

        this.remove = function (key, success, error) {
            /// <summary>Removes a key and its value from the store.</summary>
            /// <param name="key" type="String">Key string.</param>
            /// <param name="success" type="Function" optional="no">Callback for a successful remove operation.</param>
            /// <param name="error" type="Function" optional="yes">Callback for handling errors. If not specified then store.defaultError is invoked.</param>
            error = getErrorCallback(error);

            if (validateKeyInput(key, error)) {
                var index = keys[key];
                if (index !== undefined) {
                    if (index === items.length - 1) {
                        items.pop();
                    } else {
                        items[index] = undefined;
                        holes.push(index);
                    }
                    delete keys[key];

                    // The last item was removed, no need to keep track of any holes in the array.
                    if (items.length === 0) {
                        holes = [];
                    }
                }

                delay(success);
            }
        };

        this.update = function (key, value, success, error) {
            /// <summary>Updates the value associated to a key in the store.</summary>
            /// <param name="key" type="String">Key string.</param>
            /// <param name="value">New value.</param>
            /// <param name="success" type="Function" optional="no">Callback for a successful update operation.</param>
            /// <param name="error" type="Function" optional="yes">Callback for handling errors. If not specified then store.defaultError is invoked.</param>
            /// <remarks>
            ///    This method errors out if the specified key is not found in the store.
            /// </remarks>

            error = getErrorCallback(error);
            if (validateKeyInput(key, error)) {
                if (keys.hasOwnProperty(key)) {
                    this.addOrUpdate(key, value, success, error);
                } else {
                    error({ message: "key not found", key: key });
                }
            }
        };
    };

    MemoryStore.create = function (name) {
        /// <summary>Creates a store object that uses memory storage as its underlying mechanism.</summary>
        /// <param name="name" type="String">Store name.</param>
        /// <returns type="Object">Store object.</returns>
        return new MemoryStore(name);
    };

    MemoryStore.isSupported = function () {
        /// <summary>Checks whether the underlying mechanism for this kind of store objects is supported by the browser.</summary>
        /// <returns type="Boolean">True if the mechanism is supported by the browser; otherwise false.</returns>
        return true;
    };

    MemoryStore.prototype.close = function () {
        /// <summary>This function does nothing in MemoryStore as it does not have a connection model.</summary>
    };

    MemoryStore.prototype.defaultError = throwErrorCallback;

    /// <summary>Identifies the underlying mechanism used by the store.</summary>
    MemoryStore.prototype.mechanism = "memory";



    var mechanisms = {
        indexeddb: IndexedDBStore,
        dom: DomStore,
        memory: MemoryStore
    };

    datajs.defaultStoreMechanism = "best";

    datajs.createStore = function (name, mechanism) {
        /// <summary>Creates a new store object.</summary>
        /// <param name="name" type="String">Store name.</param>
        /// <param name="mechanism" type="String" optional="true">A specific mechanism to use (defaults to best, can be "best", "dom", "indexeddb", "webdb").</param>
        /// <returns type="Object">Store object.</returns>

        if (!mechanism) {
            mechanism = datajs.defaultStoreMechanism;
        }

        if (mechanism === "best") {
            mechanism = (DomStore.isSupported()) ? "dom" : "memory";
        }

        var factory = mechanisms[mechanism];
        if (factory) {
            return factory.create(name);
        }

        throw { message: "Failed to create store", name: name, mechanism: mechanism };
    };




    var appendQueryOption = function (uri, queryOption) {
        /// <summary>Appends the specified escaped query option to the specified URI.</summary>
        /// <param name="uri" type="String">URI to append option to.</param>
        /// <param name="queryOption" type="String">Escaped query option to append.</param>
        var separator = (uri.indexOf("?") >= 0) ? "&" : "?";
        return uri + separator + queryOption;
    };

    var appendSegment = function (uri, segment) {
        /// <summary>Appends the specified segment to the given URI.</summary>
        /// <param name="uri" type="String">URI to append a segment to.</param>
        /// <param name="segment" type="String">Segment to append.</param>
        /// <returns type="String">The original URI with a new segment appended.</returns>

        var index = uri.indexOf("?");
        var queryPortion = "";
        if (index >= 0) {
            queryPortion = uri.substr(index);
            uri = uri.substr(0, index);
        }

        if (uri[uri.length - 1] !== "/") {
            uri += "/";
        }
        return uri + segment + queryPortion;
    };

    var buildODataRequest = function (uri, options) {
        /// <summary>Builds a request object to GET the specified URI.</summary>
        /// <param name="uri" type="String">URI for request.</param>
        /// <param name="options" type="Object">Additional options.</param>

        return {
            method: "GET",
            requestUri: uri,
            user: options.user,
            password: options.password,
            enableJsonpCallback: options.enableJsonpCallback,
            callbackParameterName: options.callbackParameterName,
            formatQueryString: options.formatQueryString
        };
    };

    var findQueryOptionStart = function (uri, name) {
        /// <summary>Finds the index where the value of a query option starts.</summary>
        /// <param name="uri" type="String">URI to search in.</param>
        /// <param name="name" type="String">Name to look for.</param>
        /// <returns type="Number">The index where the query option starts.</returns>

        var result = -1;
        var queryIndex = uri.indexOf("?");
        if (queryIndex !== -1) {
            var start = uri.indexOf("?" + name + "=", queryIndex);
            if (start === -1) {
                start = uri.indexOf("&" + name + "=", queryIndex);
            }
            if (start !== -1) {
                result = start + name.length + 2;
            }
        }
        return result;
    };

    var queryForData = function (uri, options, success, error) {
        /// <summary>Gets data from an OData service.</summary>
        /// <param name="uri" type="String">URI to the OData service.</param>
        /// <param name="options" type="Object">Object with additional well-known request options.</param>
        /// <param name="success" type="Function">Success callback.</param>
        /// <param name="error" type="Function">Error callback.</param>
        /// <returns type="Object">Object with an abort method.</returns>

        var request = queryForDataInternal(uri, options, {}, success, error);
        return request;
    };

    var queryForDataInternal = function (uri, options, data, success, error) {
        /// <summary>Gets data from an OData service taking into consideration server side paging.</summary>
        /// <param name="uri" type="String">URI to the OData service.</param>
        /// <param name="options" type="Object">Object with additional well-known request options.</param>
        /// <param name="data" type="Array">Array that stores the data provided by the OData service.</param>
        /// <param name="success" type="Function">Success callback.</param>
        /// <param name="error" type="Function">Error callback.</param>
        /// <returns type="Object">Object with an abort method.</returns>

        var request = buildODataRequest(uri, options);
        var currentRequest = odata.request(request, function (newData) {
            var nextLink = newData["@odata.nextLink"];
            if (nextLink) {
                var index = uri.indexOf(".svc/", 0);
                if (index != -1) {
                    nextLink = uri.substring(0, index + 5) + nextLink;
                }
            }

            if (data.value && newData.value) {
                data.value = data.value.concat(newData.value);
            }
            else {
                for (var property in newData) {
                    if (property != "@odata.nextLink") {
                        data[property] = newData[property];
                    }
                }
            }

            if (nextLink) {
                currentRequest = queryForDataInternal(nextLink, options, data, success, error);
            }
            else {
                success(data);
            }
        }, error, undefined, options.httpClient, options.metadata);

        return {
            abort: function () {
                currentRequest.abort();
            }
        };
    };

    var ODataCacheSource = function (options) {
        /// <summary>Creates a data cache source object for requesting data from an OData service.</summary>
        /// <param name="options">Options for the cache data source.</param>
        /// <returns type="ODataCacheSource">A new data cache source instance.</returns>

        var that = this;
        var uri = options.source;

        that.identifier = normalizeURICase(encodeURI(decodeURI(uri)));
        that.options = options;

        that.count = function (success, error) {
            /// <summary>Gets the number of items in the collection.</summary>
            /// <param name="success" type="Function">Success callback with the item count.</param>
            /// <param name="error" type="Function">Error callback.</param>
            /// <returns type="Object">Request object with an abort method./<param>

            var options = that.options;
            return odata.request(
                buildODataRequest(appendSegment(uri, "$count"), options),
                function (data) {
                    var count = parseInt10(data.toString());
                    if (isNaN(count)) {
                        error({ message: "Count is NaN", count: count });
                    } else {
                        success(count);
                    }
                }, error, undefined, options.httpClient, options.metadata);
        };

        that.read = function (index, count, success, error) {
            /// <summary>Gets a number of consecutive items from the collection.</summary>
            /// <param name="index" type="Number">Zero-based index of the items to retrieve.</param>
            /// <param name="count" type="Number">Number of items to retrieve.</param>
            /// <param name="success" type="Function">Success callback with the requested items.</param>
            /// <param name="error" type="Function">Error callback.</param>
            /// <returns type="Object">Request object with an abort method./<param>

            var queryOptions = "$skip=" + index + "&$top=" + count;
            return queryForData(appendQueryOption(uri, queryOptions), that.options, success, error);
        };

        return that;
    };



    var appendPage = function (operation, page) {
        /// <summary>Appends a page's data to the operation data.</summary>
        /// <param name="operation" type="Object">Operation with (i)ndex, (c)ount and (d)ata.</param>
        /// <param name="page" type="Object">Page with (i)ndex, (c)ount and (d)ata.</param>

        var intersection = intersectRanges(operation, page);
        var start = 0;
        var end = 0;
        if (intersection) {
            start = intersection.i - page.i;
            end = start + (operation.c - getJsonValueArraryLength(operation.d));
        }

        operation.d = concatJsonValueArray(operation.d, sliceJsonValueArray(page.d, start, end));
    };

    var intersectRanges = function (x, y) {
        /// <summary>Returns the {(i)ndex, (c)ount} range for the intersection of x and y.</summary>
        /// <param name="x" type="Object">Range with (i)ndex and (c)ount members.</param>
        /// <param name="y" type="Object">Range with (i)ndex and (c)ount members.</param>
        /// <returns type="Object">The intersection (i)ndex and (c)ount; undefined if there is no intersection.</returns>

        var xLast = x.i + x.c;
        var yLast = y.i + y.c;
        var resultIndex = (x.i > y.i) ? x.i : y.i;
        var resultLast = (xLast < yLast) ? xLast : yLast;
        var result;
        if (resultLast >= resultIndex) {
            result = { i: resultIndex, c: resultLast - resultIndex };
        }

        return result;
    };

    var checkZeroGreater = function (val, name) {
        /// <summary>Checks whether val is a defined number with value zero or greater.</summary>
        /// <param name="val" type="Number">Value to check.</param>
        /// <param name="name" type="String">Parameter name to use in exception.</param>

        if (val === undefined || typeof val !== "number") {
            throw { message: "'" + name + "' must be a number." };
        }

        if (isNaN(val) || val < 0 || !isFinite(val)) {
            throw { message: "'" + name + "' must be greater than or equal to zero." };
        }
    };

    var checkUndefinedGreaterThanZero = function (val, name) {
        /// <summary>Checks whether val is undefined or a number with value greater than zero.</summary>
        /// <param name="val" type="Number">Value to check.</param>
        /// <param name="name" type="String">Parameter name to use in exception.</param>

        if (val !== undefined) {
            if (typeof val !== "number") {
                throw { message: "'" + name + "' must be a number." };
            }

            if (isNaN(val) || val <= 0 || !isFinite(val)) {
                throw { message: "'" + name + "' must be greater than zero." };
            }
        }
    };

    var checkUndefinedOrNumber = function (val, name) {
        /// <summary>Checks whether val is undefined or a number</summary>
        /// <param name="val" type="Number">Value to check.</param>
        /// <param name="name" type="String">Parameter name to use in exception.</param>
        if (val !== undefined && (typeof val !== "number" || isNaN(val) || !isFinite(val))) {
            throw { message: "'" + name + "' must be a number." };
        }
    };

    var removeFromArray = function (arr, item) {
        /// <summary>Performs a linear search on the specified array and removes the first instance of 'item'.</summary>
        /// <param name="arr" type="Array">Array to search.</param>
        /// <param name="item">Item being sought.</param>
        /// <returns type="Boolean">Whether the item was removed.</returns>

        var i, len;
        for (i = 0, len = arr.length; i < len; i++) {
            if (arr[i] === item) {
                arr.splice(i, 1);
                return true;
            }
        }

        return false;
    };

    var estimateSize = function (obj) {
        /// <summary>Estimates the size of an object in bytes.</summary>
        /// <param name="obj" type="Object">Object to determine the size of.</param>
        /// <returns type="Integer">Estimated size of the object in bytes.</returns>
        var size = 0;
        var type = typeof obj;

        if (type === "object" && obj) {
            for (var name in obj) {
                size += name.length * 2 + estimateSize(obj[name]);
            }
        } else if (type === "string") {
            size = obj.length * 2;
        } else {
            size = 8;
        }
        return size;
    };

    var snapToPageBoundaries = function (lowIndex, highIndex, pageSize) {
        /// <summary>Snaps low and high indices into page sizes and returns a range.</summary>
        /// <param name="lowIndex" type="Number">Low index to snap to a lower value.</param>
        /// <param name="highIndex" type="Number">High index to snap to a higher value.</param>
        /// <param name="pageSize" type="Number">Page size to snap to.</param>
        /// <returns type="Object">A range with (i)ndex and (c)ount of elements.</returns>

        lowIndex = Math.floor(lowIndex / pageSize) * pageSize;
        highIndex = Math.ceil((highIndex + 1) / pageSize) * pageSize;
        return { i: lowIndex, c: highIndex - lowIndex };
    };

    // The DataCache is implemented using state machines.  The following constants are used to properly
    // identify and label the states that these machines transition to.

    // DataCache state constants

    var CACHE_STATE_DESTROY = "destroy";
    var CACHE_STATE_IDLE = "idle";
    var CACHE_STATE_INIT = "init";
    var CACHE_STATE_READ = "read";
    var CACHE_STATE_PREFETCH = "prefetch";
    var CACHE_STATE_WRITE = "write";

    // DataCacheOperation state machine states.
    // Transitions on operations also depend on the cache current of the cache.

    var OPERATION_STATE_CANCEL = "cancel";
    var OPERATION_STATE_END = "end";
    var OPERATION_STATE_ERROR = "error";
    var OPERATION_STATE_START = "start";
    var OPERATION_STATE_WAIT = "wait";

    // Destroy state machine states

    var DESTROY_STATE_CLEAR = "clear";

    // Read / Prefetch state machine states

    var READ_STATE_DONE = "done";
    var READ_STATE_LOCAL = "local";
    var READ_STATE_SAVE = "save";
    var READ_STATE_SOURCE = "source";

    var DataCacheOperation = function (stateMachine, promise, isCancelable, index, count, data, pending) {
        /// <summary>Creates a new operation object.</summary>
        /// <param name="stateMachine" type="Function">State machine that describes the specific behavior of the operation.</param>
        /// <param name="promise" type ="DjsDeferred">Promise for requested values.</param>
        /// <param name="isCancelable" type ="Boolean">Whether this operation can be canceled or not.</param>
        /// <param name="index" type="Number">Index of first item requested.</param>
        /// <param name="count" type="Number">Count of items requested.</param>
        /// <param name="data" type="Array">Array with the items requested by the operation.</param>
        /// <param name="pending" type="Number">Total number of pending prefetch records.</param>
        /// <returns type="DataCacheOperation">A new data cache operation instance.</returns>

        /// <field name="p" type="DjsDeferred">Promise for requested values.</field>
        /// <field name="i" type="Number">Index of first item requested.</field>
        /// <field name="c" type="Number">Count of items requested.</field>
        /// <field name="d" type="Array">Array with the items requested by the operation.</field>
        /// <field name="s" type="Array">Current state of the operation.</field>
        /// <field name="canceled" type="Boolean">Whether the operation has been canceled.</field>
        /// <field name="pending" type="Number">Total number of pending prefetch records.</field>
        /// <field name="oncomplete" type="Function">Callback executed when the operation reaches the end state.</field>

        var stateData;
        var cacheState;
        var that = this;

        that.p = promise;
        that.i = index;
        that.c = count;
        that.d = data;
        that.s = OPERATION_STATE_START;

        that.canceled = false;
        that.pending = pending;
        that.oncomplete = null;

        that.cancel = function () {
            /// <summary>Transitions this operation to the cancel state and sets the canceled flag to true.</summary>
            /// <remarks>The function is a no-op if the operation is non-cancelable.</summary>

            if (!isCancelable) {
                return;
            }

            var state = that.s;
            if (state !== OPERATION_STATE_ERROR && state !== OPERATION_STATE_END && state !== OPERATION_STATE_CANCEL) {
                that.canceled = true;
                transition(OPERATION_STATE_CANCEL, stateData);
            }
        };

        that.complete = function () {
            /// <summary>Transitions this operation to the end state.</summary>

            transition(OPERATION_STATE_END, stateData);
        };

        that.error = function (err) {
            /// <summary>Transitions this operation to the error state.</summary>
            if (!that.canceled) {
                transition(OPERATION_STATE_ERROR, err);
            }
        };

        that.run = function (state) {
            /// <summary>Executes the operation's current state in the context of a new cache state.</summary>
            /// <param name="state" type="Object">New cache state.</param>

            cacheState = state;
            that.transition(that.s, stateData);
        };

        that.wait = function (data) {
            /// <summary>Transitions this operation to the wait state.</summary>

            transition(OPERATION_STATE_WAIT, data);
        };

        var operationStateMachine = function (opTargetState, cacheState, data) {
            /// <summary>State machine that describes all operations common behavior.</summary>
            /// <param name="opTargetState" type="Object">Operation state to transition to.</param>
            /// <param name="cacheState" type="Object">Current cache state.</param>
            /// <param name="data" type="Object" optional="true">Additional data passed to the state.</param>

            switch (opTargetState) {
                case OPERATION_STATE_START:
                    // Initial state of the operation. The operation will remain in this state until the cache has been fully initialized.
                    if (cacheState !== CACHE_STATE_INIT) {
                        stateMachine(that, opTargetState, cacheState, data);
                    }
                    break;

                case OPERATION_STATE_WAIT:
                    // Wait state indicating that the operation is active but waiting for an asynchronous operation to complete.
                    stateMachine(that, opTargetState, cacheState, data);
                    break;

                case OPERATION_STATE_CANCEL:
                    // Cancel state.
                    stateMachine(that, opTargetState, cacheState, data);
                    that.fireCanceled();
                    transition(OPERATION_STATE_END);
                    break;

                case OPERATION_STATE_ERROR:
                    // Error state. Data is expected to be an object detailing the error condition.
                    stateMachine(that, opTargetState, cacheState, data);
                    that.canceled = true;
                    that.fireRejected(data);
                    transition(OPERATION_STATE_END);
                    break;

                case OPERATION_STATE_END:
                    // Final state of the operation.
                    if (that.oncomplete) {
                        that.oncomplete(that);
                    }
                    if (!that.canceled) {
                        that.fireResolved();
                    }
                    stateMachine(that, opTargetState, cacheState, data);
                    break;

                default:
                    // Any other state is passed down to the state machine describing the operation's specific behavior.
                        stateMachine(that, opTargetState, cacheState, data);
                    break;
            }
        };

        var transition = function (state, data) {
            /// <summary>Transitions this operation to a new state.</summary>
            /// <param name="state" type="Object">State to transition the operation to.</param>
            /// <param name="data" type="Object" optional="true">Additional data passed to the state.</param>

            that.s = state;
            stateData = data;
            operationStateMachine(state, cacheState, data);
        };

        that.transition = transition;

        return that;
    };

    DataCacheOperation.prototype.fireResolved = function () {
        /// <summary>Fires a resolved notification as necessary.</summary>

        // Fire the resolve just once.
        var p = this.p;
        if (p) {
            this.p = null;
            p.resolve(this.d);
        }
    };

    DataCacheOperation.prototype.fireRejected = function (reason) {
        /// <summary>Fires a rejected notification as necessary.</summary>

        // Fire the rejection just once.
        var p = this.p;
        if (p) {
            this.p = null;
            p.reject(reason);
        }
    };

    DataCacheOperation.prototype.fireCanceled = function () {
        /// <summary>Fires a canceled notification as necessary.</summary>

        this.fireRejected({ canceled: true, message: "Operation canceled" });
    };


    var DataCache = function (options) {
        /// <summary>Creates a data cache for a collection that is efficiently loaded on-demand.</summary>
        /// <param name="options">
        /// Options for the data cache, including name, source, pageSize,
        /// prefetchSize, cacheSize, storage mechanism, and initial prefetch and local-data handler.
        /// </param>
        /// <returns type="DataCache">A new data cache instance.</returns>

        var state = CACHE_STATE_INIT;
        var stats = { counts: 0, netReads: 0, prefetches: 0, cacheReads: 0 };

        var clearOperations = [];
        var readOperations = [];
        var prefetchOperations = [];

        var actualCacheSize = 0;                                             // Actual cache size in bytes.
        var allDataLocal = false;                                            // Whether all data is local.
        var cacheSize = undefinedDefault(options.cacheSize, 1048576);        // Requested cache size in bytes, default 1 MB.
        var collectionCount = 0;                                             // Number of elements in the server collection.
        var highestSavedPage = 0;                                            // Highest index of all the saved pages.
        var highestSavedPageSize = 0;                                        // Item count of the saved page with the highest index.
        var overflowed = cacheSize === 0;                                    // If the cache has overflowed (actualCacheSize > cacheSize or cacheSize == 0);
        var pageSize = undefinedDefault(options.pageSize, 50);               // Number of elements to store per page.
        var prefetchSize = undefinedDefault(options.prefetchSize, pageSize); // Number of elements to prefetch from the source when the cache is idling.
        var version = "1.0";
        var cacheFailure;

        var pendingOperations = 0;

        var source = options.source;
        if (typeof source === "string") {
            // Create a new cache source.
            source = new ODataCacheSource(options);
        }
        source.options = options;

        // Create a cache local store.
        var store = datajs.createStore(options.name, options.mechanism);

        var that = this;

        that.onidle = options.idle;
        that.stats = stats;

        that.count = function () {
            /// <summary>Counts the number of items in the collection.</summary>
            /// <returns type="Object">A promise with the number of items.</returns>

            if (cacheFailure) {
                throw cacheFailure;
            }

            var deferred = createDeferred();
            var canceled = false;

            if (allDataLocal) {
                delay(function () {
                    deferred.resolve(collectionCount);
                });

                return deferred.promise();
            }

            // TODO: Consider returning the local data count instead once allDataLocal flag is set to true.
            var request = source.count(function (count) {
                request = null;
                stats.counts++;
                deferred.resolve(count);
            }, function (err) {
                request = null;
                deferred.reject(extend(err, { canceled: canceled }));
            });

            return extend(deferred.promise(), {
                cancel: function () {
                    /// <summary>Aborts the count operation.</summary>
                    if (request) {
                        canceled = true;
                        request.abort();
                        request = null;
                    }
                }
            });
        };

        that.clear = function () {
            /// <summary>Cancels all running operations and clears all local data associated with this cache.</summary>
            /// <remarks>
            /// New read requests made while a clear operation is in progress will not be canceled.
            /// Instead they will be queued for execution once the operation is completed.
            /// </remarks>
            /// <returns type="Object">A promise that has no value and can't be canceled.</returns>

            if (cacheFailure) {
                throw cacheFailure;
            }

            if (clearOperations.length === 0) {
                var deferred = createDeferred();
                var op = new DataCacheOperation(destroyStateMachine, deferred, false);
                queueAndStart(op, clearOperations);
                return deferred.promise();
            }
            return clearOperations[0].p;
        };

        that.filterForward = function (index, count, predicate) {
            /// <summary>Filters the cache data based a predicate.</summary>
            /// <param name="index" type="Number">The index of the item to start filtering forward from.</param>
            /// <param name="count" type="Number">Maximum number of items to include in the result.</param>
            /// <param name="predicate" type="Function">Callback function returning a boolean that determines whether an item should be included in the result or not.</param>
            /// <remarks>
            /// Specifying a negative count value will yield all the items in the cache that satisfy the predicate.
            /// </remarks>
            /// <returns type="DjsDeferred">A promise for an array of results.</returns>
            return filter(index, count, predicate, false);
        };

        that.filterBack = function (index, count, predicate) {
            /// <summary>Filters the cache data based a predicate.</summary>
            /// <param name="index" type="Number">The index of the item to start filtering backward from.</param>
            /// <param name="count" type="Number">Maximum number of items to include in the result.</param>
            /// <param name="predicate" type="Function">Callback function returning a boolean that determines whether an item should be included in the result or not.</param>
            /// <remarks>
            /// Specifying a negative count value will yield all the items in the cache that satisfy the predicate.
            /// </remarks>
            /// <returns type="DjsDeferred">A promise for an array of results.</returns>
            return filter(index, count, predicate, true);
        };

        that.readRange = function (index, count) {
            /// <summary>Reads a range of adjacent records.</summary>
            /// <param name="index" type="Number">Zero-based index of record range to read.</param>
            /// <param name="count" type="Number">Number of records in the range.</param>
            /// <remarks>
            /// New read requests made while a clear operation is in progress will not be canceled.
            /// Instead they will be queued for execution once the operation is completed.
            /// </remarks>
            /// <returns type="DjsDeferred">
            /// A promise for an array of records; less records may be returned if the
            /// end of the collection is found.
            /// </returns>

            checkZeroGreater(index, "index");
            checkZeroGreater(count, "count");

            if (cacheFailure) {
                throw cacheFailure;
            }

            var deferred = createDeferred();

            // Merging read operations would be a nice optimization here.
            var op = new DataCacheOperation(readStateMachine, deferred, true, index, count, {}, 0);
            queueAndStart(op, readOperations);

            return extend(deferred.promise(), {
                cancel: function () {
                    /// <summary>Aborts the readRange operation.</summary>
                    op.cancel();
                }
            });
        };

        that.ToObservable = that.toObservable = function () {
            /// <summary>Creates an Observable object that enumerates all the cache contents.</summary>
            /// <returns>A new Observable object that enumerates all the cache contents.</returns>
            if (!window.Rx || !window.Rx.Observable) {
                throw { message: "Rx library not available - include rx.js" };
            }

            if (cacheFailure) {
                throw cacheFailure;
            }

            return window.Rx.Observable.CreateWithDisposable(function (obs) {
                var disposed = false;
                var index = 0;

                var errorCallback = function (error) {
                    if (!disposed) {
                        obs.OnError(error);
                    }
                };

                var successCallback = function (data) {
                    if (!disposed) {
                        var i, len;
                        for (i = 0, len = data.value.length; i < len; i++) {
                            // The wrapper automatically checks for Dispose
                            // on the observer, so we don't need to check it here.
                            obs.OnNext(data.value[i]);
                        }

                        if (data.value.length < pageSize) {
                            obs.OnCompleted();
                        } else {
                            index += pageSize;
                            that.readRange(index, pageSize).then(successCallback, errorCallback);
                        }
                    }
                };

                that.readRange(index, pageSize).then(successCallback, errorCallback);

                return { Dispose: function () { disposed = true; } };
            });
        };

        var cacheFailureCallback = function (message) {
            /// <summary>Creates a function that handles a callback by setting the cache into failure mode.</summary>
            /// <param name="message" type="String">Message text.</param>
            /// <returns type="Function">Function to use as error callback.</returns>
            /// <remarks>
            /// This function will specifically handle problems with critical store resources
            /// during cache initialization.
            /// </remarks>

            return function (error) {
                cacheFailure = { message: message, error: error };

                // Destroy any pending clear or read operations.
                // At this point there should be no prefetch operations.
                // Count operations will go through but are benign because they
                // won't interact with the store.
                var i, len;
                for (i = 0, len = readOperations.length; i < len; i++) {
                    readOperations[i].fireRejected(cacheFailure);
                }
                for (i = 0, len = clearOperations.length; i < len; i++) {
                    clearOperations[i].fireRejected(cacheFailure);
                }

                // Null out the operation arrays.
                readOperations = clearOperations = null;
            };
        };

        var changeState = function (newState) {
            /// <summary>Updates the cache's state and signals all pending operations of the change.</summary>
            /// <param name="newState" type="Object">New cache state.</param>
            /// <remarks>This method is a no-op if the cache's current state and the new state are the same.</remarks>

            if (newState !== state) {
                state = newState;
                var operations = clearOperations.concat(readOperations, prefetchOperations);
                var i, len;
                for (i = 0, len = operations.length; i < len; i++) {
                    operations[i].run(state);
                }
            }
        };

        var clearStore = function () {
            /// <summary>Removes all the data stored in the cache.</summary>
            /// <returns type="DjsDeferred">A promise with no value.</returns>

            var deferred = new DjsDeferred();
            store.clear(function () {

                // Reset the cache settings.
                actualCacheSize = 0;
                allDataLocal = false;
                collectionCount = 0;
                highestSavedPage = 0;
                highestSavedPageSize = 0;
                overflowed = cacheSize === 0;

                // version is not reset, in case there is other state in eg V1.1 that is still around.

                // Reset the cache stats.
                stats = { counts: 0, netReads: 0, prefetches: 0, cacheReads: 0 };
                that.stats = stats;

                store.close();
                deferred.resolve();
            }, function (err) {
                deferred.reject(err);
            });
            return deferred;
        };

        var dequeueOperation = function (operation) {
            /// <summary>Removes an operation from the caches queues and changes the cache state to idle.</summary>
            /// <param name="operation" type="DataCacheOperation">Operation to dequeue.</param>
            /// <remarks>This method is used as a handler for the operation's oncomplete event.</remarks>

            var removed = removeFromArray(clearOperations, operation);
            if (!removed) {
                removed = removeFromArray(readOperations, operation);
                if (!removed) {
                    removeFromArray(prefetchOperations, operation);
                }
            }

            pendingOperations--;
            changeState(CACHE_STATE_IDLE);
        };

        var fetchPage = function (start) {
            /// <summary>Requests data from the cache source.</summary>
            /// <param name="start" type="Number">Zero-based index of items to request.</param>
            /// <returns type="DjsDeferred">A promise for a page object with (i)ndex, (c)ount, (d)ata.</returns>


            var deferred = new DjsDeferred();
            var canceled = false;

            var request = source.read(start, pageSize, function (data) {
                var length = getJsonValueArraryLength(data);
                var page = { i: start, c: length, d: data };
                deferred.resolve(page);
            }, function (err) {
                deferred.reject(err);
            });

            return extend(deferred, {
                cancel: function () {
                    if (request) {
                        request.abort();
                        canceled = true;
                        request = null;
                    }
                }
            });
        };

        var filter = function (index, count, predicate, backwards) {
            /// <summary>Filters the cache data based a predicate.</summary>
            /// <param name="index" type="Number">The index of the item to start filtering from.</param>
            /// <param name="count" type="Number">Maximum number of items to include in the result.</param>
            /// <param name="predicate" type="Function">Callback function returning a boolean that determines whether an item should be included in the result or not.</param>
            /// <param name="backwards" type="Boolean">True if the filtering should move backward from the specified index, falsey otherwise.</param>
            /// <remarks>
            /// Specifying a negative count value will yield all the items in the cache that satisfy the predicate.
            /// </remarks>
            /// <returns type="DjsDeferred">A promise for an array of results.</returns>
            index = parseInt10(index);
            count = parseInt10(count);

            if (isNaN(index)) {
                throw { message: "'index' must be a valid number.", index: index };
            }
            if (isNaN(count)) {
                throw { message: "'count' must be a valid number.", count: count };
            }

            if (cacheFailure) {
                throw cacheFailure;
            }

            index = Math.max(index, 0);

            var deferred = createDeferred();
            var returnData = {};
            returnData.value = [];
            var canceled = false;
            var pendingReadRange = null;

            var readMore = function (readIndex, readCount) {
                if (!canceled) {
                    if (count > 0 && returnData.value.length >= count) {
                        deferred.resolve(returnData);
                    } else {
                        pendingReadRange = that.readRange(readIndex, readCount).then(function (data) {
                            if (data["@odata.context"] && !returnData["@odata.context"]) {
                                returnData["@odata.context"] = data["@odata.context"];
                            }
                            
                            for (var i = 0, length = data.value.length; i < length && (count < 0 || returnData.value.length < count); i++) {
                                var dataIndex = backwards ? length - i - 1 : i;
                                var item = data.value[dataIndex];
                                if (predicate(item)) {
                                    var element = {
                                        index: readIndex + dataIndex,
                                        item: item
                                    };

                                    backwards ? returnData.value.unshift(element) : returnData.value.push(element);
                                }
                            }

                            // Have we reached the end of the collection?
                            if ((!backwards && data.value.length < readCount) || (backwards && readIndex <= 0)) {
                                deferred.resolve(returnData);
                            } else {
                                var nextIndex = backwards ? Math.max(readIndex - pageSize, 0) : readIndex + readCount;
                                readMore(nextIndex, pageSize);
                            }
                        }, function (err) {
                            deferred.reject(err);
                        });
                    }
                }
            };

            // Initially, we read from the given starting index to the next/previous page boundary
            var initialPage = snapToPageBoundaries(index, index, pageSize);
            var initialIndex = backwards ? initialPage.i : index;
            var initialCount = backwards ? index - initialPage.i + 1 : initialPage.i + initialPage.c - index;
            readMore(initialIndex, initialCount);

            return extend(deferred.promise(), {
                cancel: function () {
                    /// <summary>Aborts the filter operation</summary>
                    if (pendingReadRange) {
                        pendingReadRange.cancel();
                    }
                    canceled = true;
                }
            });
        };

        var fireOnIdle = function () {
            /// <summary>Fires an onidle event if any functions are assigned.</summary>

            if (that.onidle && pendingOperations === 0) {
                that.onidle();
            }
        };

        var prefetch = function (start) {
            /// <summary>Creates and starts a new prefetch operation.</summary>
            /// <param name="start" type="Number">Zero-based index of the items to prefetch.</param>
            /// <remarks>
            /// This method is a no-op if any of the following conditions is true:
            ///     1.- prefetchSize is 0
            ///     2.- All data has been read and stored locally in the cache.
            ///     3.- There is already an all data prefetch operation queued.
            ///     4.- The cache has run out of available space (overflowed).
            /// <remarks>

            if (allDataLocal || prefetchSize === 0 || overflowed) {
                return;
            }


            if (prefetchOperations.length === 0 || (prefetchOperations[0] && prefetchOperations[0].c !== -1)) {
                // Merging prefetch operations would be a nice optimization here.
                var op = new DataCacheOperation(prefetchStateMachine, null, true, start, prefetchSize, null, prefetchSize);
                queueAndStart(op, prefetchOperations);
            }
        };

        var queueAndStart = function (op, queue) {
            /// <summary>Queues an operation and runs it.</summary>
            /// <param name="op" type="DataCacheOperation">Operation to queue.</param>
            /// <param name="queue" type="Array">Array that will store the operation.</param>

            op.oncomplete = dequeueOperation;
            queue.push(op);
            pendingOperations++;
            op.run(state);
        };

        var readPage = function (key) {
            /// <summary>Requests a page from the cache local store.</summary>
            /// <param name="key" type="Number">Zero-based index of the reuqested page.</param>
            /// <returns type="DjsDeferred">A promise for a found flag and page object with (i)ndex, (c)ount, (d)ata, and (t)icks.</returns>


            var canceled = false;
            var deferred = extend(new DjsDeferred(), {
                cancel: function () {
                    /// <summary>Aborts the readPage operation.</summary>
                    canceled = true;
                }
            });

            var error = storeFailureCallback(deferred, "Read page from store failure");

            store.contains(key, function (contained) {
                if (canceled) {
                    return;
                }
                if (contained) {
                    store.read(key, function (_, data) {
                        if (!canceled) {
                            deferred.resolve(data !== undefined, data);
                        }
                    }, error);
                    return;
                }
                deferred.resolve(false);
            }, error);
            return deferred;
        };

        var savePage = function (key, page) {
            /// <summary>Saves a page to the cache local store.</summary>
            /// <param name="key" type="Number">Zero-based index of the requested page.</param>
            /// <param name="page" type="Object">Object with (i)ndex, (c)ount, (d)ata, and (t)icks.</param>
            /// <returns type="DjsDeferred">A promise with no value.</returns>


            var canceled = false;

            var deferred = extend(new DjsDeferred(), {
                cancel: function () {
                    /// <summary>Aborts the readPage operation.</summary>
                    canceled = true;
                }
            });

            var error = storeFailureCallback(deferred, "Save page to store failure");

            var resolve = function () {
                deferred.resolve(true);
            };

            if (page.c > 0) {
                var pageBytes = estimateSize(page);
                overflowed = cacheSize >= 0 && cacheSize < actualCacheSize + pageBytes;

                if (!overflowed) {
                    store.addOrUpdate(key, page, function () {
                        updateSettings(page, pageBytes);
                        saveSettings(resolve, error);
                    }, error);
                } else {
                    resolve();
                }
            } else {
                updateSettings(page, 0);
                saveSettings(resolve, error);
            }
            return deferred;
        };

        var saveSettings = function (success, error) {
            /// <summary>Saves the cache's current settings to the local store.</summary>
            /// <param name="success" type="Function">Success callback.</param>
            /// <param name="error" type="Function">Errror callback.</param>

            var settings = {
                actualCacheSize: actualCacheSize,
                allDataLocal: allDataLocal,
                cacheSize: cacheSize,
                collectionCount: collectionCount,
                highestSavedPage: highestSavedPage,
                highestSavedPageSize: highestSavedPageSize,
                pageSize: pageSize,
                sourceId: source.identifier,
                version: version
            };

            store.addOrUpdate("__settings", settings, success, error);
        };

        var storeFailureCallback = function (deferred/*, message*/) {
            /// <summary>Creates a function that handles a store error.</summary>
            /// <param name="deferred" type="DjsDeferred">Deferred object to resolve.</param>
            /// <param name="message" type="String">Message text.</param>
            /// <returns type="Function">Function to use as error callback.</returns>
            /// <remarks>
            /// This function will specifically handle problems when interacting with the store.
            /// </remarks>

            return function (/*error*/) {
                // var console = window.console;
                // if (console && console.log) {
                //    console.log(message);
                //    console.dir(error);
                // }
                deferred.resolve(false);
            };
        };

        var updateSettings = function (page, pageBytes) {
            /// <summary>Updates the cache's settings based on a page object.</summary>
            /// <param name="page" type="Object">Object with (i)ndex, (c)ount, (d)ata.</param>
            /// <param name="pageBytes" type="Number">Size of the page in bytes.</param>

            var pageCount = page.c;
            var pageIndex = page.i;

            // Detect the collection size.
            if (pageCount === 0) {
                if (highestSavedPage === pageIndex - pageSize) {
                    collectionCount = highestSavedPage + highestSavedPageSize;
                }
            } else {
                highestSavedPage = Math.max(highestSavedPage, pageIndex);
                if (highestSavedPage === pageIndex) {
                    highestSavedPageSize = pageCount;
                }
                actualCacheSize += pageBytes;
                if (pageCount < pageSize && !collectionCount) {
                    collectionCount = pageIndex + pageCount;
                }
            }

            // Detect the end of the collection.
            if (!allDataLocal && collectionCount === highestSavedPage + highestSavedPageSize) {
                allDataLocal = true;
            }
        };

        var cancelStateMachine = function (operation, opTargetState, cacheState, data) {
            /// <summary>State machine describing the behavior for cancelling a read or prefetch operation.</summary>
            /// <param name="operation" type="DataCacheOperation">Operation being run.</param>
            /// <param name="opTargetState" type="Object">Operation state to transition to.</param>
            /// <param name="cacheState" type="Object">Current cache state.</param>
            /// <param name="data" type="Object" optional="true">Additional data passed to the state.</param>
            /// <remarks>
            /// This state machine contains behavior common to read and prefetch operations.
            /// </remarks>

            var canceled = operation.canceled && opTargetState !== OPERATION_STATE_END;
            if (canceled) {
                if (opTargetState === OPERATION_STATE_CANCEL) {
                    // Cancel state.
                    // Data is expected to be any pending request made to the cache.
                    if (data && data.cancel) {
                        data.cancel();
                    }
                }
            }
            return canceled;
        };

        var destroyStateMachine = function (operation, opTargetState, cacheState) {
            /// <summary>State machine describing the behavior of a clear operation.</summary>
            /// <param name="operation" type="DataCacheOperation">Operation being run.</param>
            /// <param name="opTargetState" type="Object">Operation state to transition to.</param>
            /// <param name="cacheState" type="Object">Current cache state.</param>
            /// <remarks>
            /// Clear operations have the highest priority and can't be interrupted by other operations; however,
            /// they will preempt any other operation currently executing.
            /// </remarks>

            var transition = operation.transition;

            // Signal the cache that a clear operation is running.
            if (cacheState !== CACHE_STATE_DESTROY) {
                changeState(CACHE_STATE_DESTROY);
                return true;
            }

            switch (opTargetState) {
                case OPERATION_STATE_START:
                    // Initial state of the operation.
                    transition(DESTROY_STATE_CLEAR);
                    break;

                case OPERATION_STATE_END:
                    // State that signals the operation is done.
                    fireOnIdle();
                    break;

                case DESTROY_STATE_CLEAR:
                    // State that clears all the local data of the cache.
                    clearStore().then(function () {
                        // Terminate the operation once the local store has been cleared.
                        operation.complete();
                    });
                    // Wait until the clear request completes.
                    operation.wait();
                    break;

                default:
                    return false;
            }
            return true;
        };

        var prefetchStateMachine = function (operation, opTargetState, cacheState, data) {
            /// <summary>State machine describing the behavior of a prefetch operation.</summary>
            /// <param name="operation" type="DataCacheOperation">Operation being run.</param>
            /// <param name="opTargetState" type="Object">Operation state to transition to.</param>
            /// <param name="cacheState" type="Object">Current cache state.</param>
            /// <param name="data" type="Object" optional="true">Additional data passed to the state.</param>
            /// <remarks>
            /// Prefetch operations have the lowest priority and will be interrupted by operations of
            /// other kinds. A preempted prefetch operation will resume its execution only when the state
            /// of the cache returns to idle.
            ///
            /// If a clear operation starts executing then all the prefetch operations are canceled,
            /// even if they haven't started executing yet.
            /// </remarks>

            // Handle cancelation
            if (!cancelStateMachine(operation, opTargetState, cacheState, data)) {

                var transition = operation.transition;

                // Handle preemption
                if (cacheState !== CACHE_STATE_PREFETCH) {
                    if (cacheState === CACHE_STATE_DESTROY) {
                        if (opTargetState !== OPERATION_STATE_CANCEL) {
                            operation.cancel();
                        }
                    } else if (cacheState === CACHE_STATE_IDLE) {
                        // Signal the cache that a prefetch operation is running.
                        changeState(CACHE_STATE_PREFETCH);
                    }
                    return true;
                }

                switch (opTargetState) {
                    case OPERATION_STATE_START:
                        // Initial state of the operation.
                        if (prefetchOperations[0] === operation) {
                            transition(READ_STATE_LOCAL, operation.i);
                        }
                        break;

                    case READ_STATE_DONE:
                        // State that determines if the operation can be resolved or has to
                        // continue processing.
                        // Data is expected to be the read page.
                        var pending = operation.pending;

                        if (pending > 0) {
                            pending -= Math.min(pending, data.c);
                        }

                        // Are we done, or has all the data been stored?
                        if (allDataLocal || pending === 0 || data.c < pageSize || overflowed) {
                            operation.complete();
                        } else {
                            // Continue processing the operation.
                            operation.pending = pending;
                            transition(READ_STATE_LOCAL, data.i + pageSize);
                        }
                        break;

                    default:
                        return readSaveStateMachine(operation, opTargetState, cacheState, data, true);
                }
            }
            return true;
        };

        var readStateMachine = function (operation, opTargetState, cacheState, data) {
            /// <summary>State machine describing the behavior of a read operation.</summary>
            /// <param name="operation" type="DataCacheOperation">Operation being run.</param>
            /// <param name="opTargetState" type="Object">Operation state to transition to.</param>
            /// <param name="cacheState" type="Object">Current cache state.</param>
            /// <param name="data" type="Object" optional="true">Additional data passed to the state.</param>
            /// <remarks>
            /// Read operations have a higher priority than prefetch operations, but lower than
            /// clear operations. They will preempt any prefetch operation currently running
            /// but will be interrupted by a clear operation.
            ///
            /// If a clear operation starts executing then all the currently running
            /// read operations are canceled. Read operations that haven't started yet will
            /// wait in the start state until the destory operation finishes.
            /// </remarks>

            // Handle cancelation
            if (!cancelStateMachine(operation, opTargetState, cacheState, data)) {

                var transition = operation.transition;

                // Handle preemption
                if (cacheState !== CACHE_STATE_READ && opTargetState !== OPERATION_STATE_START) {
                    if (cacheState === CACHE_STATE_DESTROY) {
                        if (opTargetState !== OPERATION_STATE_START) {
                            operation.cancel();
                        }
                    } else if (cacheState !== CACHE_STATE_WRITE) {
                        // Signal the cache that a read operation is running.
                        changeState(CACHE_STATE_READ);
                    }

                    return true;
                }

                switch (opTargetState) {
                    case OPERATION_STATE_START:
                        // Initial state of the operation.
                        // Wait until the cache is idle or prefetching.
                        if (cacheState === CACHE_STATE_IDLE || cacheState === CACHE_STATE_PREFETCH) {
                            // Signal the cache that a read operation is running.
                            changeState(CACHE_STATE_READ);
                            if (operation.c >= 0) {
                                // Snap the requested range to a page boundary.
                                var range = snapToPageBoundaries(operation.i, operation.c, pageSize);
                                transition(READ_STATE_LOCAL, range.i);
                            } else {
                                transition(READ_STATE_DONE, operation);
                            }
                        }
                        break;

                    case READ_STATE_DONE:
                        // State that determines if the operation can be resolved or has to
                        // continue processing.
                        // Data is expected to be the read page.
                        appendPage(operation, data);
                        var len = getJsonValueArraryLength(operation.d);
                        // Are we done?
                        if (operation.c === len || data.c < pageSize) {
                            // Update the stats, request for a prefetch operation.
                            stats.cacheReads++;
                            prefetch(data.i + data.c);
                            // Terminate the operation.
                            operation.complete();
                        } else {
                            // Continue processing the operation.
                            transition(READ_STATE_LOCAL, data.i + pageSize);
                        }
                        break;

                    default:
                        return readSaveStateMachine(operation, opTargetState, cacheState, data, false);
                }
            }

            return true;
        };

        var readSaveStateMachine = function (operation, opTargetState, cacheState, data, isPrefetch) {
            /// <summary>State machine describing the behavior for reading and saving data into the cache.</summary>
            /// <param name="operation" type="DataCacheOperation">Operation being run.</param>
            /// <param name="opTargetState" type="Object">Operation state to transition to.</param>
            /// <param name="cacheState" type="Object">Current cache state.</param>
            /// <param name="data" type="Object" optional="true">Additional data passed to the state.</param>
            /// <param name="isPrefetch" type="Boolean">Flag indicating whether a read (false) or prefetch (true) operation is running.
            /// <remarks>
            /// This state machine contains behavior common to read and prefetch operations.
            /// </remarks>

            var error = operation.error;
            var transition = operation.transition;
            var wait = operation.wait;
            var request;

            switch (opTargetState) {
                case OPERATION_STATE_END:
                    // State that signals the operation is done.
                    fireOnIdle();
                    break;

                case READ_STATE_LOCAL:
                    // State that requests for a page from the local store.
                    // Data is expected to be the index of the page to request.
                    request = readPage(data).then(function (found, page) {
                        // Signal the cache that a read operation is running.
                        if (!operation.canceled) {
                            if (found) {
                                // The page is in the local store, check if the operation can be resolved.
                                transition(READ_STATE_DONE, page);
                            } else {
                                // The page is not in the local store, request it from the source.
                                transition(READ_STATE_SOURCE, data);
                            }
                        }
                    });
                    break;

                case READ_STATE_SOURCE:
                    // State that requests for a page from the cache source.
                    // Data is expected to be the index of the page to request.
                    request = fetchPage(data).then(function (page) {
                        // Signal the cache that a read operation is running.
                        if (!operation.canceled) {
                            // Update the stats and save the page to the local store.
                            if (isPrefetch) {
                                stats.prefetches++;
                            } else {
                                stats.netReads++;
                            }
                            transition(READ_STATE_SAVE, page);
                        }
                    }, error);
                    break;

                case READ_STATE_SAVE:
                    // State that saves a  page to the local store.
                    // Data is expected to be the page to save.
                    // Write access to the store is exclusive.
                    if (cacheState !== CACHE_STATE_WRITE) {
                        changeState(CACHE_STATE_WRITE);
                        request = savePage(data.i, data).then(function (saved) {
                            if (!operation.canceled) {
                                if (!saved && isPrefetch) {
                                    operation.pending = 0;
                                }
                                // Check if the operation can be resolved.
                                transition(READ_STATE_DONE, data);
                            }
                            changeState(CACHE_STATE_IDLE);
                        });
                    }
                    break;

                default:
                    // Unknown state that can't be handled by this state machine.
                    return false;
            }

            if (request) {
                // The operation might have been canceled between stack frames do to the async calls.
                if (operation.canceled) {
                    request.cancel();
                } else if (operation.s === opTargetState) {
                    // Wait for the request to complete.
                    wait(request);
                }
            }

            return true;
        };

        // Initialize the cache.
        store.read("__settings", function (_, settings) {
            if (assigned(settings)) {
                var settingsVersion = settings.version;
                if (!settingsVersion || settingsVersion.indexOf("1.") !== 0) {
                    cacheFailureCallback("Unsupported cache store version " + settingsVersion)();
                    return;
                }

                if (pageSize !== settings.pageSize || source.identifier !== settings.sourceId) {
                    // The shape or the source of the data was changed so invalidate the store.
                    clearStore().then(function () {
                        // Signal the cache is fully initialized.
                        changeState(CACHE_STATE_IDLE);
                    }, cacheFailureCallback("Unable to clear store during initialization"));
                } else {
                    // Restore the saved settings.
                    actualCacheSize = settings.actualCacheSize;
                    allDataLocal = settings.allDataLocal;
                    cacheSize = settings.cacheSize;
                    collectionCount = settings.collectionCount;
                    highestSavedPage = settings.highestSavedPage;
                    highestSavedPageSize = settings.highestSavedPageSize;
                    version = settingsVersion;

                    // Signal the cache is fully initialized.
                    changeState(CACHE_STATE_IDLE);
                }
            } else {
                // This is a brand new cache.
                saveSettings(function () {
                    // Signal the cache is fully initialized.
                    changeState(CACHE_STATE_IDLE);
                }, cacheFailureCallback("Unable to write settings during initialization."));
            }
        }, cacheFailureCallback("Unable to read settings from store."));

        return that;
    };

    datajs.createDataCache = function (options) {
        /// <summary>Creates a data cache for a collection that is efficiently loaded on-demand.</summary>
        /// <param name="options">
        /// Options for the data cache, including name, source, pageSize,
        /// prefetchSize, cacheSize, storage mechanism, and initial prefetch and local-data handler.
        /// </param>
        /// <returns type="DataCache">A new data cache instance.</returns>
        checkUndefinedGreaterThanZero(options.pageSize, "pageSize");
        checkUndefinedOrNumber(options.cacheSize, "cacheSize");
        checkUndefinedOrNumber(options.prefetchSize, "prefetchSize");

        if (!assigned(options.name)) {
            throw { message: "Undefined or null name", options: options };
        }

        if (!assigned(options.source)) {
            throw { message: "Undefined source", options: options };
        }

        return new DataCache(options);
    };



})(this);