You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by bi...@apache.org on 2014/05/09 09:22:20 UTC

[11/24] a) Convert all the DataJS supported functionality from V3 to V4. 1. Remove all the Json verbose logic, make the DataJS accepted and returned javascript object be in Json light format. (Since Json verbose has been completely removed on V4, making

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/e387fc92/JSLib/src/odata.js
----------------------------------------------------------------------
diff --git a/JSLib/src/odata.js b/JSLib/src/odata.js
index 98b80e2..a18ac80 100644
--- a/JSLib/src/odata.js
+++ b/JSLib/src/odata.js
@@ -1,158 +1,155 @@
-// Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
-// files (the "Software"), to deal  in the Software without restriction, including without limitation the rights  to use, copy,
-// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-// WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// odata.js
-
-(function (window, undefined) {
-
-    var datajs = window.datajs || {};
-    var odata = window.OData || {};
-
-    // Imports
-
-    var assigned = datajs.assigned;
-    var defined = datajs.defined;
-    var throwErrorCallback = datajs.throwErrorCallback;
-
-    var invokeRequest = odata.invokeRequest;
-    var MAX_DATA_SERVICE_VERSION = odata.MAX_DATA_SERVICE_VERSION;
-    var prepareRequest = odata.prepareRequest;
-    var metadataParser = odata.metadataParser;
-
-    // CONTENT START
-
-    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/atomsvc+xml;q=0.8, application/json;odata=fullmetadata;q=0.7, application/json;q=0.5, */*;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;
-
-    // CONTENT END
+// Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal  in the Software without restriction, including without limitation the rights  to use, copy,
+// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+// WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// odata.js
+
+(function (window, undefined) {
+
+    var datajs = window.datajs || {};
+    var odata = window.OData || {};
+
+    // Imports
+
+    var assigned = datajs.assigned;
+    var defined = datajs.defined;
+    var throwErrorCallback = datajs.throwErrorCallback;
+
+    var invokeRequest = odata.invokeRequest;
+    var MAX_DATA_SERVICE_VERSION = odata.MAX_DATA_SERVICE_VERSION;
+    var prepareRequest = odata.prepareRequest;
+    var metadataParser = odata.metadataParser;
+
+    // CONTENT START
+    
+    // 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);
+
+        // 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
+        };
+
+        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;
+
+    // CONTENT END
 })(this);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/e387fc92/JSLib/src/store-dom.js
----------------------------------------------------------------------
diff --git a/JSLib/src/store-dom.js b/JSLib/src/store-dom.js
index bf8a887..238d43e 100644
--- a/JSLib/src/store-dom.js
+++ b/JSLib/src/store-dom.js
@@ -1,320 +1,320 @@
-// Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation 
-// files (the "Software"), to deal  in the Software without restriction, including without limitation the rights  to use, copy,
-// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-// WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
-// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// store-dom.js
-
-(function (window, undefined) {
-
-    var datajs = window.datajs || {};
-
-    // Imports.
-    var throwErrorCallback = datajs.throwErrorCallback;
-    var delay = datajs.delay;
-
-    // CONTENT START
-
-    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);
-    };
-
-    // DATAJS INTERNAL START
-    datajs.DomStore = DomStore;
-    // DATAJS INTERNAL END
-
-    // CONTENT END
+// Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation 
+// files (the "Software"), to deal  in the Software without restriction, including without limitation the rights  to use, copy,
+// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+// WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// store-dom.js
+
+(function (window, undefined) {
+
+    var datajs = window.datajs || {};
+
+    // Imports.
+    var throwErrorCallback = datajs.throwErrorCallback;
+    var delay = datajs.delay;
+
+    // CONTENT START
+
+    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);
+    };
+
+    // DATAJS INTERNAL START
+    datajs.DomStore = DomStore;
+    // DATAJS INTERNAL END
+
+    // CONTENT END
 })(this);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/e387fc92/JSLib/src/store-indexeddb.js
----------------------------------------------------------------------
diff --git a/JSLib/src/store-indexeddb.js b/JSLib/src/store-indexeddb.js
index b56828f..1df180a 100644
--- a/JSLib/src/store-indexeddb.js
+++ b/JSLib/src/store-indexeddb.js
@@ -1,417 +1,417 @@
-// Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation 
-// files (the "Software"), to deal  in the Software without restriction, including without limitation the rights  to use, copy,
-// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-// WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
-// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// store-indexeddb.js
-
-(function (window, undefined) {
-
-    var datajs = window.datajs || {};
-
-    // Imports.
-    var throwErrorCallback = datajs.throwErrorCallback;
-    var delay = datajs.delay;
-
-    // CONTENT START
-
-    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);
-    };
-
-    // DATAJS INTERNAL START
-    datajs.IndexedDBStore = IndexedDBStore;
-    // DATAJS INTERNAL END
-
-    // CONTENT END
+// Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation 
+// files (the "Software"), to deal  in the Software without restriction, including without limitation the rights  to use, copy,
+// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+// WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// store-indexeddb.js
+
+(function (window, undefined) {
+
+    var datajs = window.datajs || {};
+
+    // Imports.
+    var throwErrorCallback = datajs.throwErrorCallback;
+    var delay = datajs.delay;
+
+    // CONTENT START
+
+    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);
+    };
+
+    // DATAJS INTERNAL START
+    datajs.IndexedDBStore = IndexedDBStore;
+    // DATAJS INTERNAL END
+
+    // CONTENT END
 })(this);
\ No newline at end of file