You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ko...@apache.org on 2015/03/23 14:53:58 UTC

[1/8] olingo-odata4-js git commit: [OLINGO-442] Cleanup bevore release II and beta-name removal

Repository: olingo-odata4-js
Updated Branches:
  refs/heads/master 4621d41c8 -> 27f830e61


http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/store/indexeddb.js
----------------------------------------------------------------------
diff --git a/src/lib/store/indexeddb.js b/src/lib/store/indexeddb.js
deleted file mode 100644
index d7527c1..0000000
--- a/src/lib/store/indexeddb.js
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-/** @module store/indexeddb */
-var utils = require('./../utils.js');
-
-// Imports.
-var throwErrorCallback = utils.throwErrorCallback;
-var delay = utils.delay;
-
-
-var indexedDB = utils.inBrowser() ? window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.indexedDB : undefined;
-var IDBKeyRange = utils.inBrowser() ? window.IDBKeyRange || window.webkitIDBKeyRange : undefined;
-var IDBTransaction = utils.inBrowser() ? window.IDBTransaction || window.webkitIDBTransaction || {} : {} ;
-
-var IDBT_READ_ONLY = IDBTransaction.READ_ONLY || "readonly";
-var IDBT_READ_WRITE = IDBTransaction.READ_WRITE || "readwrite";
-
-/** Returns either a specific error handler or the default error handler
- * @param {Function} error - The specific error handler
- * @param {Function} defaultError - The default error handler
- * @returns {Function} The error callback
- */
-function getError(error, defaultError) {
-
-    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 });
-    };
-}
-
-/** Opens the store object's indexed db database.
- * @param {IndexedDBStore} store - The store object
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-function openStoreDb(store, success, error) {
-
-    var storeName = store.name;
-    var dbName = "_odatajs_" + 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);
-    };
-}
-
-/** Opens a new transaction to the store
- * @param {IndexedDBStore} store - The store object
- * @param {Integer} mode - The read/write mode of the transaction (constants from IDBTransaction)
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-function openTransaction(store, mode, success, error) {
-
-    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);
-}
-
-/** Creates a new IndexedDBStore.
- * @class IndexedDBStore
- * @constructor
- * @param {String} name - The name of the store.
- * @returns {Object} The new IndexedDBStore.
- */
-function IndexedDBStore(name) {
-    this.name = name;
-}
-
-/** Creates a new IndexedDBStore.
- * @method module:store/indexeddb~IndexedDBStore.create
- * @param {String} name - The name of the store.
- * @returns {Object} The new IndexedDBStore.
- */
-IndexedDBStore.create = function (name) {
-    if (IndexedDBStore.isSupported()) {
-        return new IndexedDBStore(name);
-    }
-
-    throw { message: "IndexedDB is not supported on this browser" };
-};
-
-/** Returns whether IndexedDB is supported.
- * @method module:store/indexeddb~IndexedDBStore.isSupported
- * @returns {Boolean} True if IndexedDB is supported, false otherwise.
- */
-IndexedDBStore.isSupported = function () {
-    return !!indexedDB;
-};
-
-/** Adds a key/value pair to the store
- * @method module:store/indexeddb~IndexedDBStore#add
- * @param {String} key - The key
- * @param {Object} value - The value
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
-*/
-IndexedDBStore.prototype.add = function (key, value, success, error) {
-    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);
-};
-
-/** Adds or updates a key/value pair in the store
- * @method module:store/indexeddb~IndexedDBStore#addOrUpdate
- * @param {String} key - The key
- * @param {Object} value - The value
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-IndexedDBStore.prototype.addOrUpdate = function (key, value, success, error) {
-    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);
-};
-
-/** Clears the store
- * @method module:store/indexeddb~IndexedDBStore#clear
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-IndexedDBStore.prototype.clear = function (success, error) {
-    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);
-};
-
-/** Closes the connection to the database
- * @method module:store/indexeddb~IndexedDBStore#close
-*/
-IndexedDBStore.prototype.close = function () {
-    
-    if (this.db) {
-        this.db.close();
-        this.db = null;
-    }
-};
-
-/** Returns whether the store contains a key
- * @method module:store/indexeddb~IndexedDBStore#contains
- * @param {String} key - The key
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-IndexedDBStore.prototype.contains = function (key, success, error) {
-    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;
-
-/** Gets all the keys from the store
- * @method module:store/indexeddb~IndexedDBStore#getAllKeys
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-IndexedDBStore.prototype.getAllKeys = function (success, error) {
-    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);
-};
-
-/** Identifies the underlying mechanism used by the store.
-*/
-IndexedDBStore.prototype.mechanism = "indexeddb";
-
-/** Reads the value for the specified key
- * @method module:store/indexeddb~IndexedDBStore#read
- * @param {String} key - The key
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- * If the key does not exist, the success handler will be called with value = undefined
- */
-IndexedDBStore.prototype.read = function (key, success, error) {
-    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);
-};
-
-/** Removes the specified key from the store
- * @method module:store/indexeddb~IndexedDBStore#remove
- * @param {String} key - The key
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-IndexedDBStore.prototype.remove = function (key, success, error) {
-
-    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);
-};
-
-/** Updates a key/value pair in the store
- * @method module:store/indexeddb~IndexedDBStore#update
- * @param {String} key - The key
- * @param {Object} value - The value
- * @param {Function} success - The success callback
- * @param {Function} error - The error callback
- */
-IndexedDBStore.prototype.update = function (key, value, success, error) {
-    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);
-};
-
-
-module.exports = IndexedDBStore;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/store/memory.js
----------------------------------------------------------------------
diff --git a/src/lib/store/memory.js b/src/lib/store/memory.js
deleted file mode 100644
index a9c69d4..0000000
--- a/src/lib/store/memory.js
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-/** @module store/memory */
-
-
-var utils = require('./../utils.js');
-
-// Imports.
-var throwErrorCallback = utils.throwErrorCallback;
-var delay = utils.delay;
-
-/** Constructor for store objects that use a sorted array as the underlying mechanism.
- * @class MemoryStore
- * @constructor
- * @param {String} name - Store name.
- */
-function MemoryStore(name) {
-
-    var holes = [];
-    var items = [];
-    var keys = {};
-
-    this.name = name;
-
-    var getErrorCallback = function (error) {
-        return error || this.defaultError;
-    };
-
-    /** Validates that the specified key is not undefined, not null, and not an array
-     * @param key - Key value.
-     * @param {Function} error - Error callback.
-     * @returns {Boolean} True if the key is valid. False if the key is invalid and the error callback has been queued for execution.
-     */
-    function validateKeyInput(key, error) {
-
-        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 method errors out if the store already contains the specified key.
-     * @summary Adds a new value identified by a key to the store.
-     * @method module:store/memory~MemoryStore#add
-     * @param {String} key - Key string.
-     * @param value - Value that is going to be added to the store.
-     * @param {Function} success - Callback for a successful add operation.
-     * @param {Function} error - Callback for handling errors. If not specified then store.defaultError is invoked.
-     */
-    this.add = function (key, value, success, error) {
-        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 method will overwrite the key's current value if it already exists in the store; otherwise it simply adds the new key and value.
-     * @summary Adds or updates a value identified by a key to the store.
-     * @method module:store/memory~MemoryStore#addOrUpdate
-     * @param {String} key - Key string.
-     * @param value - Value that is going to be added or updated to the store.
-     * @param {Function} success - Callback for a successful add or update operation.
-     * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
-    */
-    this.addOrUpdate = function (key, value, success, error) {
-        
-        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);
-        }
-    };
-
-    /** Removes all the data associated with this store object.
-     * @method module:store/memory~MemoryStore#clear
-     * @param {Function} success - Callback for a successful clear operation.
-     */
-    this.clear = function (success) {
-        items = [];
-        keys = {};
-        holes = [];
-        delay(success);
-    };
-
-    /** Checks whether a key exists in the store.
-     * @method module:store/memory~MemoryStore#contains
-     * @param {String} key - Key string.
-     * @param {Function} success - Callback indicating whether the store contains the key or not.
-     */
-    this.contains = function (key, success) {
-        var contained = keys.hasOwnProperty(key);
-        delay(success, contained);
-    };
-
-    /** Gets all the keys that exist in the store.
-     * @method module:store/memory~MemoryStore#getAllKeys
-     * @param {Function} success - Callback for a successful get operation.
-     */
-    this.getAllKeys = function (success) {
-
-        var results = [];
-        for (var name in keys) {
-            results.push(name);
-        }
-        delay(success, results);
-    };
-
-    /** Reads the value associated to a key in the store.
-     * @method module:store/memory~MemoryStore#read
-     * @param {String} key - Key string.
-     * @param {Function} success - Callback for a successful reads operation.
-     * @param {Function} error - Callback for handling errors. If not specified then store.defaultError is invoked.
-     */
-    this.read = function (key, success, error) {
-        error = getErrorCallback(error);
-
-        if (validateKeyInput(key, error)) {
-            var index = keys[key];
-            delay(success, key, items[index]);
-        }
-    };
-
-    /** Removes a key and its value from the store.
-     * @method module:store/memory~MemoryStore#remove
-     * @param {String} key - Key string.
-     * @param {Function} success - Callback for a successful remove operation.
-     * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
-     */
-    this.remove = function (key, success, error) {
-        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);
-        }
-    };
-
-    /** Updates the value associated to a key in the store.
-     * @method module:store/memory~MemoryStore#update
-     * @param {String} key - Key string.
-     * @param value - New value.
-     * @param {Function} success - Callback for a successful update operation.
-     * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
-     * This method errors out if the specified key is not found in the store.
-     */
-    this.update = function (key, value, success, error) {
-        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 });
-            }
-        }
-    };
-}
-
-/** Creates a store object that uses memory storage as its underlying mechanism.
- * @method MemoryStore.create
- * @param {String} name - Store name.
- * @returns {Object} Store object.
- */
-MemoryStore.create = function (name) {
-    return new MemoryStore(name);
-};
-
-/** Checks whether the underlying mechanism for this kind of store objects is supported by the browser.
- * @method MemoryStore.isSupported
- * @returns {Boolean} True if the mechanism is supported by the browser; otherwise false.
- */
-MemoryStore.isSupported = function () {
-    return true;
-};
-
-/** This function does nothing in MemoryStore as it does not have a connection model.
-*/
-MemoryStore.prototype.close = function () {
-};
-
-MemoryStore.prototype.defaultError = throwErrorCallback;
-
-/** Identifies the underlying mechanism used by the store.
-*/
-MemoryStore.prototype.mechanism = "memory";
-
-
-/** MemoryStore (see {@link MemoryStore}) */
-module.exports = MemoryStore;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/utils.js
----------------------------------------------------------------------
diff --git a/src/lib/utils.js b/src/lib/utils.js
deleted file mode 100644
index 429a56a..0000000
--- a/src/lib/utils.js
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-/** @module odatajs/utils */
-
-
-function inBrowser() {
-    return typeof window !== 'undefined';
-}
-
-/** Creates a new ActiveXObject from the given progId.
- * @param {String} progId - ProgId string of the desired ActiveXObject.
- * @returns {Object} The ActiveXObject instance. Null if ActiveX is not supported by the browser.
- * This function throws whatever exception might occur during the creation
- * of the ActiveXObject.
-*/
-var activeXObject = function (progId) {
-    
-    if (window.ActiveXObject) {
-        return new window.ActiveXObject(progId);
-    }
-    return null;
-};
-
-/** Checks whether the specified value is different from null and undefined.
- * @param [value] Value to check ( may be null)
- * @returns {Boolean} true if the value is assigned; false otherwise.
-*/     
-function assigned(value) {
-    return value !== null && value !== undefined;
-}
-
-/** Checks whether the specified item is in the array.
- * @param {Array} [arr] Array to check in.
- * @param item - Item to look for.
- * @returns {Boolean} true if the item is contained, false otherwise.
-*/
-function contains(arr, item) {
-    var i, len;
-    for (i = 0, len = arr.length; i < len; i++) {
-        if (arr[i] === item) {
-            return true;
-        }
-    }
-    return false;
-}
-
-/** Given two values, picks the first one that is not undefined.
- * @param a - First value.
- * @param b - Second value.
- * @returns a if it's a defined value; else b.
- */
-function defined(a, b) {
-    return (a !== undefined) ? a : b;
-}
-
-/** Delays the invocation of the specified function until execution unwinds.
- * @param {Function} callback - Callback function.
- */
-function delay(callback) {
-
-    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);
-}
-
-/** Throws an exception in case that a condition evaluates to false.
- * @param {Boolean} condition - Condition to evaluate.
- * @param {String} message - Message explaining the assertion.
- * @param {Object} data - Additional data to be included in the exception.
- */
-function djsassert(condition, message, data) {
-
-
-    if (!condition) {
-        throw { message: "Assert fired: " + message, data: data };
-    }
-}
-
-/** Extends the target with the specified values.
- * @param {Object} target - Object to add properties to.
- * @param {Object} values - Object with properties to add into target.
- * @returns {Object} The target object.
-*/
-function extend(target, values) {
-    for (var name in values) {
-        target[name] = values[name];
-    }
-
-    return target;
-}
-
-function find(arr, callback) {
-    /** Returns the first item in the array that makes the callback function true.
-     * @param {Array} [arr] Array to check in. ( may be null)
-     * @param {Function} callback - Callback function to invoke once per item in the array.
-     * @returns The first item that makes the callback return true; null otherwise or if the array is null.
-    */
-
-    if (arr) {
-        var i, len;
-        for (i = 0, len = arr.length; i < len; i++) {
-            if (callback(arr[i])) {
-                return arr[i];
-            }
-        }
-    }
-    return null;
-}
-
-function isArray(value) {
-    /** Checks whether the specified value is an array object.
-     * @param value - Value to check.
-     * @returns {Boolean} true if the value is an array object; false otherwise.
-     */
-
-    return Object.prototype.toString.call(value) === "[object Array]";
-}
-
-/** Checks whether the specified value is a Date object.
- * @param value - Value to check.
- * @returns {Boolean} true if the value is a Date object; false otherwise.
- */
-function isDate(value) {
-    return Object.prototype.toString.call(value) === "[object Date]";
-}
-
-/** Tests whether a value is an object.
- * @param value - Value to test.
- * @returns {Boolean} True is the value is an object; false otherwise.
- * Per javascript rules, null and array values are objects and will cause this function to return true.
- */
-function isObject(value) {
-    return typeof value === "object";
-}
-
-/** Parses a value in base 10.
- * @param {String} value - String value to parse.
- * @returns {Number} The parsed value, NaN if not a valid value.
-*/   
-function parseInt10(value) {
-    return parseInt(value, 10);
-}
-
-/** Renames a property in an object.
- * @param {Object} obj - Object in which the property will be renamed.
- * @param {String} oldName - Name of the property that will be renamed.
- * @param {String} newName - New name of the property.
- * This function will not do anything if the object doesn't own a property with the specified old name.
- */
-function renameProperty(obj, oldName, newName) {
-    if (obj.hasOwnProperty(oldName)) {
-        obj[newName] = obj[oldName];
-        delete obj[oldName];
-    }
-}
-
-/** Default error handler.
- * @param {Object} error - Error to handle.
- */
-function throwErrorCallback(error) {
-    throw error;
-}
-
-/** Removes leading and trailing whitespaces from a string.
- * @param {String} str String to trim
- * @returns {String} The string with no leading or trailing whitespace.
- */
-function trimString(str) {
-    if (str.trim) {
-        return str.trim();
-    }
-
-    return str.replace(/^\s+|\s+$/g, '');
-}
-
-/** Returns a default value in place of undefined.
- * @param [value] Value to check (may be null)
- * @param defaultValue - Value to return if value is undefined.
- * @returns value if it's defined; defaultValue otherwise.
- * This should only be used for cases where falsy values are valid;
- * otherwise the pattern should be 'x = (value) ? value : defaultValue;'.
- */
-function undefinedDefault(value, defaultValue) {
-    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"];
-
-/** Gets information about the components of the specified URI.
- * @param {String} uri - URI to get information from.
- * @return  {Object} An object with an isAbsolute flag and part names (scheme, authority, etc.) if available.
- */
-function getURIInfo(uri) {
-    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;
-}
-
-/** Builds a URI string from its components.
- * @param {Object} uriInfo -  An object with uri parts (scheme, authority, etc.).
- * @returns {String} URI string.
- */
-function getURIFromInfo(uriInfo) {
-    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;
-
-/** Normalizes the casing of a URI.
- * @param {String} uri - URI to normalize, absolute or relative.
- * @returns {String} The URI normalized to lower case.
-*/
-function normalizeURICase(uri) {
-    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();
-    });
-}
-
-/** Normalizes a possibly relative URI with a base URI.
- * @param {String} uri - URI to normalize, absolute or relative
- * @param {String} base - Base URI to compose with (may be null)
- * @returns {String} The composed URI if relative; the original one if absolute.
- */
-function normalizeURI(uri, base) {
-    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);
-}
-
-/** Merges the path of a relative URI and a base URI.
- * @param {String} uriPath - Relative URI path.
- * @param {String} basePath - Base URI path.
- * @returns {String} A string with the merged path.
- */
-function mergeUriPathWithBase(uriPath, basePath) {
-    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;
-}
-
-/** Removes the special folders . and .. from a URI's path.
- * @param {string} path - URI path component.
- * @returns {String} Path without any . and .. folders.
- */
-function removeDotsFromPath(path) {
-    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;
-}
-
-function convertByteArrayToHexString(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;
-}
-
-function decodeBase64(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;
-}
-
-function getBase64IndexValue(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;
-    }
-}
-
-function addBase64Padding(binaryString) {
-    while (binaryString.length < 6) {
-        binaryString = "0" + binaryString;
-    }
-    return binaryString;
-
-}
-
-function getJsonValueArraryLength(data) {
-    if (data && data.value) {
-        return data.value.length;
-    }
-
-    return 0;
-}
-
-function sliceJsonValueArray(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;
-}
-
-function concatJsonValueArray(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;
-}
-
-function endsWith(input, search) {
-    return input.indexOf(search, input.length - search.length) !== -1;
-}
-
-function startsWith (input, search) {
-    return input.indexOf(search) === 0;
-}
-
-function getFormatKind(format, defaultFormatKind) {
-    var formatKind = defaultFormatKind;
-    if (!assigned(format)) {
-        return formatKind;
-    }
-
-    var normalizedFormat = format.toLowerCase();
-    switch (normalizedFormat) {
-        case "none":
-            formatKind = 0;
-            break;
-        case "minimal":
-            formatKind = 1;
-            break;
-        case "full":
-            formatKind = 2;
-            break;
-        default:
-            break;
-    }
-
-    return formatKind;
-}
-
-
-    
-    
-exports.inBrowser = inBrowser;
-exports.activeXObject = activeXObject;
-exports.assigned = assigned;
-exports.contains = contains;
-exports.defined = defined;
-exports.delay = delay;
-exports.djsassert = djsassert;
-exports.extend = extend;
-exports.find = find;
-exports.getURIInfo = getURIInfo;
-exports.isArray = isArray;
-exports.isDate = isDate;
-exports.isObject = isObject;
-exports.normalizeURI = normalizeURI;
-exports.normalizeURICase = normalizeURICase;
-exports.parseInt10 = parseInt10;
-exports.renameProperty = renameProperty;
-exports.throwErrorCallback = throwErrorCallback;
-exports.trimString = trimString;
-exports.undefinedDefault = undefinedDefault;
-exports.decodeBase64 = decodeBase64;
-exports.convertByteArrayToHexString = convertByteArrayToHexString;
-exports.getJsonValueArraryLength = getJsonValueArraryLength;
-exports.sliceJsonValueArray = sliceJsonValueArray;
-exports.concatJsonValueArray = concatJsonValueArray;
-exports.startsWith = startsWith;
-exports.endsWith = endsWith;
-exports.getFormatKind = getFormatKind;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/xml.js
----------------------------------------------------------------------
diff --git a/src/lib/xml.js b/src/lib/xml.js
deleted file mode 100644
index 194b4ba..0000000
--- a/src/lib/xml.js
+++ /dev/null
@@ -1,824 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
- 
-
-/** @module odatajs/xml */
-
-var utils    = require('./utils.js');
-
-var activeXObject = utils.activeXObject;
-var djsassert = utils.djsassert;
-var extend = utils.extend;
-var isArray = utils.isArray;
-var normalizeURI = utils.normalizeURI;
-
-// 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";
-
-/** Checks whether the specified string has leading or trailing spaces.
- * @param {String} text - String to check.
- * @returns {Boolean} true if text has any leading or trailing whitespace; false otherwise.
- */
-function hasLeadingOrTrailingWhitespace(text) {
-    var re = /(^\s)|(\s$)/;
-    return re.test(text);
-}
-
-/** Determines whether the specified text is empty or whitespace.
- * @param {String} text - Value to inspect.
- * @returns {Boolean} true if the text value is empty or all whitespace; false otherwise.
- */
-function isWhitespace(text) {
-
-
-    var ws = /^\s*$/;
-    return text === null || ws.test(text);
-}
-
-/** Determines whether the specified element has xml:space='preserve' applied.
- * @param domElement - Element to inspect.
- * @returns {Boolean} Whether xml:space='preserve' is in effect.
- */
-function isWhitespacePreserveContext(domElement) {
-
-
-    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;
-}
-
-/** Determines whether the attribute is a XML namespace declaration.
- * @param domAttribute - Element to inspect.
- * @return {Boolean} True if the attribute is a namespace declaration (its name is 'xmlns' or starts with 'xmlns:'; false otherwise.
- */
-function isXmlNSDeclaration(domAttribute) {
-    var nodeName = domAttribute.nodeName;
-    return nodeName == "xmlns" || nodeName.indexOf("xmlns:") === 0;
-}
-
-/** Safely set as property in an object by invoking obj.setProperty.
- * @param obj - Object that exposes a setProperty method.
- * @param {String} name - Property name
- * @param value - Property value.
- */
-function safeSetProperty(obj, name, value) {
-
-
-    try {
-        obj.setProperty(name, value);
-    } catch (_) { }
-}
-
-/** Creates an configures new MSXML 3.0 ActiveX object.
- * @returns {Object} New MSXML 3.0 ActiveX object.
- * This function throws any exception that occurs during the creation
- * of the MSXML 3.0 ActiveX object.
- */
-function msXmlDom3() {
-    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;
-}
-
-/** Creates an configures new MSXML 6.0 or MSXML 3.0 ActiveX object.
- * @returns {Object} New MSXML 3.0 ActiveX object.
- * 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.
- */
-function msXmlDom() {
-    try {
-        var msxml = activeXObject("Msxml2.DOMDocument.6.0");
-        if (msxml) {
-            msxml.async = true;
-        }
-        return msxml;
-    } catch (_) {
-        return msXmlDom3();
-    }
-}
-
-/** Parses an XML string using the MSXML DOM.
- * @returns {Object} New MSXML DOMDocument node representing the parsed XML string.
- * 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.
- */
-function msXmlParse(text) {
-    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;
-}
-
-/** Throws a new exception containing XML parsing error information.
- * @param exceptionOrReason - String indicating the reason of the parsing failure or Object detailing the parsing error.
- * @param {String} srcText -     String indicating the part of the XML string that caused the parsing error.
- * @param {String} errorXmlText - XML string for wich the parsing failed.
- */
-function xmlThrowParserError(exceptionOrReason, srcText, errorXmlText) {
-
-    if (typeof exceptionOrReason === "string") {
-        exceptionOrReason = { message: exceptionOrReason };
-    }
-    throw extend(exceptionOrReason, { srcText: srcText || "", errorXmlText: errorXmlText || "" });
-}
-
-/** Returns an XML DOM document from the specified text.
- * @param {String} text - Document text.
- * @returns XML DOM document.
- * This function will throw an exception in case of a parse error
- */
-function xmlParse(text) {
-    var domParser = undefined;
-    if (utils.inBrowser()) {
-        domParser = window.DOMParser && new window.DOMParser();
-    } else {
-        domParser = new (require('xmldom').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;
-}
-
-/** Builds a XML qualified name string in the form of "prefix:name".
- * @param {String} prefix - Prefix string (may be null)
- * @param {String} name - Name string to qualify with the prefix.
- * @returns {String} Qualified name.
- */
-function xmlQualifiedName(prefix, name) {
-    return prefix ? prefix + ":" + name : name;
-}
-
-/** Appends a text node into the specified DOM element node.
- * @param domNode - DOM node for the element.
- * @param {String} textNode - Text to append as a child of element.
-*/
-function xmlAppendText(domNode, textNode) {
-    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;
-}
-
-/** Iterates through the XML element's attributes and invokes the callback function for each one.
- * @param element - Wrapped element to iterate over.
- * @param {Function} onAttributeCallback - Callback function to invoke with wrapped attribute nodes.
-*/
-function xmlAttributes(element, onAttributeCallback) {
-    var attributes = element.attributes;
-    var i, len;
-    for (i = 0, len = attributes.length; i < len; i++) {
-        onAttributeCallback(attributes.item(i));
-    }
-}
-
-/** Returns the value of a DOM element's attribute.
- * @param domNode - DOM node for the owning element.
- * @param {String} localName - Local name of the attribute.
- * @param {String} nsURI - Namespace URI of the attribute.
- * @returns {String} - The attribute value, null if not found (may be null)
- */
-function xmlAttributeValue(domNode, localName, nsURI) {
-
-    var attribute = xmlAttributeNode(domNode, localName, nsURI);
-    return attribute ? xmlNodeValue(attribute) : null;
-}
-
-/** Gets an attribute node from a DOM element.
- * @param domNode - DOM node for the owning element.
- * @param {String} localName - Local name of the attribute.
- * @param {String} nsURI - Namespace URI of the attribute.
- * @returns The attribute node, null if not found.
- */
-function xmlAttributeNode(domNode, localName, nsURI) {
-
-    var attributes = domNode.attributes;
-    if (attributes.getNamedItemNS) {
-        return attributes.getNamedItemNS(nsURI || null, localName);
-    }
-
-    return attributes.getQualifiedItem(localName, nsURI) || null;
-}
-
-/** Gets the value of the xml:base attribute on the specified element.
- * @param domNode - Element to get xml:base attribute value from.
- * @param [baseURI] - Base URI used to normalize the value of the xml:base attribute ( may be null)
- * @returns {String} Value of the xml:base attribute if found; the baseURI or null otherwise.
- */
-function xmlBaseURI(domNode, baseURI) {
-
-    var base = xmlAttributeNode(domNode, "base", xmlNS);
-    return (base ? normalizeURI(base.value, baseURI) : baseURI) || null;
-}
-
-
-/** Iterates through the XML element's child DOM elements and invokes the callback function for each one.
- * @param domNode - DOM Node containing the DOM elements to iterate over.
- * @param {Function} onElementCallback - Callback function to invoke for each child DOM element.
-*/
-function xmlChildElements(domNode, onElementCallback) {
-
-    xmlTraverse(domNode, /*recursive*/false, function (child) {
-        if (child.nodeType === 1) {
-            onElementCallback(child);
-        }
-        // continue traversing.
-        return true;
-    });
-}
-
-/** Gets the descendant element under root that corresponds to the specified path and namespace URI.
- * @param root - DOM element node from which to get the descendant element.
- * @param {String} namespaceURI - The namespace URI of the element to match.
- * @param {String} path - Path to the desired descendant element.
- * @return The element specified by path and namespace URI.
- * 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.
- */
-function xmlFindElementByPath(root, namespaceURI, path) {
-    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;
-}
-
-/** Gets the DOM element or DOM attribute node under root that corresponds to the specified path and namespace URI.
- * @param root - DOM element node from which to get the descendant node.
- * @param {String} namespaceURI - The namespace URI of the node to match.
- * @param {String} path - Path to the desired descendant node.
- * @return The node specified by path and namespace URI.
-
-* 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.
-*/
-function xmlFindNodeByPath(root, namespaceURI, path) {
-    
-
-    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;
-}
-
-/** Returns the first child DOM element under the specified DOM node that matches the specified namespace URI and local name.
- * @param domNode - DOM node from which the child DOM element is going to be retrieved.
- * @param {String} [namespaceURI] - 
- * @param {String} [localName] - 
- * @return The node's first child DOM element that matches the specified namespace URI and local name; null otherwise.
- */
-function xmlFirstChildElement(domNode, namespaceURI, localName) {
-
-    return xmlFirstElementMaybeRecursive(domNode, namespaceURI, localName, /*recursive*/false);
-}
-
-/** Returns the first descendant DOM element under the specified DOM node that matches the specified namespace URI and local name.
- * @param domNode - DOM node from which the descendant DOM element is going to be retrieved.
- * @param {String} [namespaceURI] - 
- * @param {String} [localName] - 
- * @return The node's first descendant DOM element that matches the specified namespace URI and local name; null otherwise.
-*/
-function xmlFirstDescendantElement(domNode, namespaceURI, localName) {
-    if (domNode.getElementsByTagNameNS) {
-        var result = domNode.getElementsByTagNameNS(namespaceURI, localName);
-        return result.length > 0 ? result[0] : null;
-    }
-    return xmlFirstElementMaybeRecursive(domNode, namespaceURI, localName, /*recursive*/true);
-}
-
-/** Returns the first descendant DOM element under the specified DOM node that matches the specified namespace URI and local name.
- * @param domNode - DOM node from which the descendant DOM element is going to be retrieved.
- * @param {String} [namespaceURI] - 
- * @param {String} [localName] - 
- * @param {Boolean} recursive 
- * - 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.
- * @return The node's first descendant DOM element that matches the specified namespace URI and local name; null otherwise.
- */
-function xmlFirstElementMaybeRecursive(domNode, namespaceURI, localName, recursive) {
-
-    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;
-}
-
-/** Gets the concatenated value of all immediate child text and CDATA nodes for the specified element.
- * @param xmlElement - Element to get values for.
- * @returns {String} Text for all direct children.
- */
-function xmlInnerText(xmlElement) {
-
-    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;
-}
-
-/** Returns the localName of a XML node.
- * @param domNode - DOM node to get the value from.
- * @returns {String} localName of domNode.
- */
-function xmlLocalName(domNode) {
-
-    return domNode.localName || domNode.baseName;
-}
-
-/** Returns the namespace URI of a XML node.
- * @param domNode - DOM node to get the value from.
- * @returns {String} Namespace URI of domNode.
- */
-function xmlNamespaceURI(domNode) {
-
-    return domNode.namespaceURI || null;
-}
-
-/** Returns the value or the inner text of a XML node.
- * @param domNode - DOM node to get the value from.
- * @return Value of the domNode or the inner text if domNode represents a DOM element node.
- */
-function xmlNodeValue(domNode) {
-    
-    if (domNode.nodeType === 1) {
-        return xmlInnerText(domNode);
-    }
-    return domNode.nodeValue;
-}
-
-/** Walks through the descendants of the domNode and invokes a callback for each node.
- * @param domNode - DOM node whose descendants are going to be traversed.
- * @param {Boolean} recursive
- * - 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 {Boolean} onChildCallback - Called for each child
- * @returns {String} Namespace URI of node.
- */
-function xmlTraverse(domNode, recursive, onChildCallback) {
-
-    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();
-        }
-    }
-}
-
-/** Returns the next sibling DOM element of the specified DOM node.
- * @param domNode - DOM node from which the next sibling is going to be retrieved.
- * @param {String} [namespaceURI] - 
- * @param {String} [localName] - 
- * @return The node's next sibling DOM element, null if there is none.
- */
-function xmlSiblingElement(domNode, namespaceURI, localName) {
-
-    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;
-}
-
-/** Creates a new empty DOM document node.
- * @return New DOM document node.
- *
- * 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.
- */
-function xmlDom() {
-    var implementation = window.document.implementation;
-    return (implementation && implementation.createDocument) ?
-       implementation.createDocument(null, null, null) :
-       msXmlDom();
-}
-
-/** Appends a collection of child nodes or string values to a parent DOM node.
- * @param parent - DOM node to which the children will be appended.
- * @param {Array} children - Array containing DOM nodes or string values that will be appended to the parent.
- * @return The parent with the appended children or string values.
- *  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.
- */
-function xmlAppendChildren(parent, children) {
-    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;
-}
-
-/** Appends a child node or a string value to a parent DOM node.
- * @param parent - DOM node to which the child will be appended.
- * @param child - Child DOM node or string value to append to the parent.
- * @return The parent with the appended child or string value.
- * 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.
- */
-function xmlAppendChild(parent, child) {
-
-    djsassert(parent !== child, "xmlAppendChild() - parent and child are one and the same!");
-    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;
-}
-
-/** Creates a new DOM attribute node.
- * @param dom - DOM document used to create the attribute.
- * @param {String} namespaceURI - Namespace URI.
- * @param {String} qualifiedName - Qualified OData name
- * @param {String} value - Value of the new attribute
- * @return DOM attribute node for the namespace declaration.
- */
-function xmlNewAttribute(dom, namespaceURI, qualifiedName, value) {
-
-    var attribute =
-        dom.createAttributeNS && dom.createAttributeNS(namespaceURI, qualifiedName) ||
-        dom.createNode(2, qualifiedName, namespaceURI || undefined);
-
-    attribute.value = value || "";
-    return attribute;
-}
-
-/** Creates a new DOM element node.
- * @param dom - DOM document used to create the DOM element.
- * @param {String} namespaceURI - Namespace URI of the new DOM element.
- * @param {String} qualifiedName - Qualified name in the form of "prefix:name" of the new DOM element.
- * @param {Array} [children] Collection of child DOM nodes or string values that are going to be appended to the new DOM element.
- * @return New DOM element.
- * 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.
- */
-function xmlNewElement(dom, namespaceURI, qualifiedName, children) {
-    var element =
-        dom.createElementNS && dom.createElementNS(nampespaceURI, qualifiedName) ||
-        dom.createNode(1, qualifiedName, nampespaceURI || undefined);
-
-    return xmlAppendChildren(element, children || []);
-}
-
-/** Creates a namespace declaration attribute.
- * @param dom - DOM document used to create the attribute.
- * @param {String} namespaceURI - Namespace URI.
- * @param {String} prefix - Namespace prefix.
- * @return DOM attribute node for the namespace declaration.
- */
-function xmlNewNSDeclaration(dom, namespaceURI, prefix) {
-    return xmlNewAttribute(dom, xmlnsNS, xmlQualifiedName("xmlns", prefix), namespaceURI);
-}
-
-/** Creates a new DOM document fragment node for the specified xml text.
- * @param dom - DOM document from which the fragment node is going to be created.
- * @param {String} text XML text to be represented by the XmlFragment.
- * @return New DOM document fragment object.
- */
-function xmlNewFragment(dom, text) {
-
-    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;
-}
-
-/** Creates new DOM text node.
- * @param dom - DOM document used to create the text node.
- * @param {String} text - Text value for the DOM text node.
- * @return DOM text node.
- */ 
-function xmlNewText(dom, text) {
-    return dom.createTextNode(text);
-}
-
-/** Creates a new DOM element or DOM attribute node as specified by path and appends it to the DOM tree pointed by root.
- * @param dom - DOM document used to create the new node.
- * @param root - DOM element node used as root of the subtree on which the new nodes are going to be created.
- * @param {String} namespaceURI - Namespace URI of the new DOM element or attribute.
- * @param {String} prefix - Prefix used to qualify the name of the new DOM element or attribute.
- * @param {String} path - Path string describing the location of the new DOM element or attribute from the root element.
- * @return DOM element or attribute node for the last segment of the path.
-
- * 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.
- */
-function xmlNewNodeByPath(dom, root, namespaceURI, prefix, path) {
-    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;
-}
-
-/** Returns the text representation of the document to which the specified node belongs.
- * @param domNode - Wrapped element in the document to serialize.
- * @returns {String} Serialized document.
-*/
-function xmlSerialize(domNode) {
-    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" };
-}
-
-/** Returns the XML representation of the all the descendants of the node.
- * @param domNode - Node to serialize.
- * @returns {String} The XML representation of all the descendants of the node.
- */
-function xmlSerializeDescendants(domNode) {
-    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;
-}
-
-/** Returns the XML representation of the node and all its descendants.
- * @param domNode - Node to serialize
- * @returns {String} The XML representation of the node and all its descendants.
- */
-function xmlSerializeNode(domNode) {
-
-    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" };
-}
-
-exports.http = http;
-exports.w3org = w3org;
-exports.xmlNS = xmlNS;
-exports.xmlnsNS = xmlnsNS;
-
-exports.hasLeadingOrTrailingWhitespace = hasLeadingOrTrailingWhitespace;
-exports.isXmlNSDeclaration = isXmlNSDeclaration;
-exports.xmlAppendChild = xmlAppendChild;
-exports.xmlAppendChildren = xmlAppendChildren;
-exports.xmlAttributeNode = xmlAttributeNode;
-exports.xmlAttributes = xmlAttributes;
-exports.xmlAttributeValue = xmlAttributeValue;
-exports.xmlBaseURI = xmlBaseURI;
-exports.xmlChildElements = xmlChildElements;
-exports.xmlFindElementByPath = xmlFindElementByPath;
-exports.xmlFindNodeByPath = xmlFindNodeByPath;
-exports.xmlFirstChildElement = xmlFirstChildElement;
-exports.xmlFirstDescendantElement = xmlFirstDescendantElement;
-exports.xmlInnerText = xmlInnerText;
-exports.xmlLocalName = xmlLocalName;
-exports.xmlNamespaceURI = xmlNamespaceURI;
-exports.xmlNodeValue = xmlNodeValue;
-exports.xmlDom = xmlDom;
-exports.xmlNewAttribute = xmlNewAttribute;
-exports.xmlNewElement = xmlNewElement;
-exports.xmlNewFragment = xmlNewFragment;
-exports.xmlNewNodeByPath = xmlNewNodeByPath;
-exports.xmlNewNSDeclaration = xmlNewNSDeclaration;
-exports.xmlNewText = xmlNewText;
-exports.xmlParse = xmlParse;
-exports.xmlQualifiedName = xmlQualifiedName;
-exports.xmlSerialize = xmlSerialize;
-exports.xmlSerializeDescendants = xmlSerializeDescendants;
-exports.xmlSiblingElement = xmlSiblingElement;

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/test/test-demo-scenario.js
----------------------------------------------------------------------
diff --git a/test/test-demo-scenario.js b/test/test-demo-scenario.js
index 71e37ff..a4650ac 100644
--- a/test/test-demo-scenario.js
+++ b/test/test-demo-scenario.js
@@ -18,7 +18,7 @@
  */
 'use strict';
 
-var odatajs = require('./../src/index-node.js');
+var odatajs = require('./../index.js');
 var chai = require('chai');
 var assert = chai.assert;
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/test/test-odata-json.js
----------------------------------------------------------------------
diff --git a/test/test-odata-json.js b/test/test-odata-json.js
index 32c243d..fd02881 100644
--- a/test/test-odata-json.js
+++ b/test/test-odata-json.js
@@ -18,7 +18,7 @@
  */
 'use strict';
 
-var odatajs = require('./../src/index-node.js');
+var odatajs = require('./../index.js');
 var chai = require('chai');
 var assert = chai.assert;
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/test/test-utils.js
----------------------------------------------------------------------
diff --git a/test/test-utils.js b/test/test-utils.js
index f377029..720542b 100644
--- a/test/test-utils.js
+++ b/test/test-utils.js
@@ -18,7 +18,7 @@
  */
 'use strict';
 
-var odatajs = require('./../src/index-node.js');
+var odatajs = require('./../index.js');
 var chai = require('chai');
 var assert = chai.assert;
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/tests/node-test-setup.js
----------------------------------------------------------------------
diff --git a/tests/node-test-setup.js b/tests/node-test-setup.js
index 838bb36..ebc82ea 100644
--- a/tests/node-test-setup.js
+++ b/tests/node-test-setup.js
@@ -24,7 +24,7 @@ MockHttpClient = require("./common/mockHttpClient.js").init({});
 
 //lib
 datajs = require('././lib/datajs.js');
-OData = require('./../src/lib/odata.js');
+OData = require('././odata.js');
 
 
 


[2/8] olingo-odata4-js git commit: [OLINGO-442] Cleanup bevore release II and beta-name removal

Posted by ko...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/odata/net-browser.js
----------------------------------------------------------------------
diff --git a/src/lib/odata/net-browser.js b/src/lib/odata/net-browser.js
deleted file mode 100644
index 8d956ff..0000000
--- a/src/lib/odata/net-browser.js
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/** @module odata/net */
-/*for browser*/
-
-
-var utils    = require('./../utils.js');
-// Imports.
-
-var defined = utils.defined;
-var delay = utils.delay;
-
-var ticks = 0;
-
-/* Checks whether the specified request can be satisfied with a JSONP request.
- * @param request - Request object to check.
- * @returns {Boolean} true if the request can be satisfied; false otherwise.
-
- * 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.
- */
-function canUseJSONP(request) {
-    
-    return !(request.method && request.method !== "GET");
-
-
-}
-
-/** Creates an IFRAME tag for loading the JSONP script
- * @param {String} url - The source URL of the script
- * @returns {HTMLElement} The IFRAME tag
- */
-function createIFrame(url) {
-    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;
-}
-
-/** Creates a XmlHttpRequest object.
- * @returns {XmlHttpRequest} XmlHttpRequest object.
- */
-function createXmlHttpRequest() {
-    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;
-}
-
-/** Checks whether the specified URL is an absolute URL.
- * @param {String} url - URL to check.
- * @returns {Boolean} true if the url is an absolute URL; false otherwise.
-*/
-function isAbsoluteUrl(url) {
-    return url.indexOf("http://") === 0 ||
-        url.indexOf("https://") === 0 ||
-        url.indexOf("file://") === 0;
-}
-
-/** Checks whether the specified URL is local to the current context.
- * @param {String} url - URL to check.
- * @returns {Boolean} true if the url is a local URL; false otherwise.
- */
-function isLocalUrl(url) {
-
-    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);
-}
-
-/** Removes a callback used for a JSONP request.
- * @param {String} name - Function name to remove.
- * @param {Number} tick - Tick count used on the callback.
- */
-function removeCallback(name, tick) {
-    try {
-        delete window[name];
-    } catch (err) {
-        window[name] = undefined;
-        if (tick === ticks - 1) {
-            ticks -= 1;
-        }
-    }
-}
-
-/** Removes an iframe.
- * @param {Object} iframe - The iframe to remove.
- * @returns {Object} Null value to be assigned to iframe reference.
- */
-function removeIFrame(iframe) {
-    if (iframe) {
-        writeHtmlToIFrame(iframe, "");
-        iframe.parentNode.removeChild(iframe);
-    }
-
-    return null;
-}
-
-/** Reads response headers into array.
- * @param {XMLHttpRequest} xhr - HTTP request with response available.
- * @param {Array} headers - Target array to fill with name/value pairs.
- */
-function readResponseHeaders(xhr, headers) {
-
-    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];
-        }
-    }
-}
-
-/** Writes HTML to an IFRAME document.
- * @param {HTMLElement} iframe - The IFRAME element to write to.
- * @param {String} html - The HTML to write.
- */
-function writeHtmlToIFrame(iframe, html) {
-    var frameDocument = (iframe.contentWindow) ? iframe.contentWindow.document : iframe.contentDocument.document;
-    frameDocument.open();
-    frameDocument.write(html);
-    frameDocument.close();
-}
-
-exports.defaultHttpClient = {
-    callbackParameterName: "$callback",
-
-    formatQueryString: "$format=json",
-
-    enableJsonpCallback: false,
-
-    /** Performs a network request.
-     * @param {Object} request - Request description
-     * @param {Function} success - Success callback with the response object.
-     * @param {Function} error - Error callback with an error object.
-     * @returns {Object} Object with an 'abort' method for the operation.
-     */
-    request: function createRequest() {
-
-        var that = this;
-
-
-        return function(request, success, error) {
-
-        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 , that.enableJsonpCallback);
-        var callbackParameterName = defined(request.callbackParameterName, that.callbackParameterName);
-        var formatQueryString = defined(request.formatQueryString, that.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;
-    }
-    }()
-};
-
-
-
-exports.canUseJSONP = canUseJSONP;
-exports.isAbsoluteUrl = isAbsoluteUrl;
-exports.isLocalUrl = isLocalUrl;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/odata/net.js
----------------------------------------------------------------------
diff --git a/src/lib/odata/net.js b/src/lib/odata/net.js
deleted file mode 100644
index be45295..0000000
--- a/src/lib/odata/net.js
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-/** @module odata/net */
-
-
-var http = require('http');
-var utils    = require('./../utils.js');
-var url = require("url");
-
-
-var defined = utils.defined;
-var delay = utils.delay;
-
-var ticks = 0;
-
-/* Checks whether the specified request can be satisfied with a JSONP request.
- * @param request - Request object to check.
- * @returns {Boolean} true if the request can be satisfied; false otherwise.
-
- * 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.
- */
-function canUseJSONP(request) {
-    return false;
-}
-
-
-
-/** Checks whether the specified URL is an absolute URL.
- * @param {String} url - URL to check.
- * @returns {Boolean} true if the url is an absolute URL; false otherwise.
-*/
-function isAbsoluteUrl(url) {
-    return url.indexOf("http://") === 0 ||
-           url.indexOf("https://") === 0 ||
-           url.indexOf("file://") === 0;
-}
-
-/** Checks whether the specified URL is local to the current context.
- * @param {String} url - URL to check.
- * @returns {Boolean} true if the url is a local URL; false otherwise.
- */
-function isLocalUrl(url) {
-
-    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);
-}
-
-
-/** Reads response headers into array.
- * @param {Object} inHeader
- * @param {Array} outHeader
- */
-function readResponseHeaders(inHeader, outHeader) {
-    for (var property in inHeader) {
-        
-        if (inHeader.hasOwnProperty(property)) {
-            outHeader[property] = inHeader[property];
-        }
-    }
-}
-
-    
-
-
-
-exports.defaultHttpClient = {
-    formatQueryString: "$format=json",
-
-    
-    /** Performs a network request.
-     * @param {Object} request - Request description
-     * @param {Function} success - Success callback with the response object.
-     * @param {Function} error - Error callback with an error object.
-     * @returns {Object} Object with an 'abort' method for the operation.
-     */
-    request: function (request, success, error) {
-
-        var result = {};
-        var done = false;
-        
-        var options = url.parse(request.requestUri);
-        options.method = request.method || "GET";
-        options.headers = {};
-        //options.auth = request.user + ':' + request.password;
-        //add headers
-        var name;
-        if (request.headers) {
-            for (name in request.headers) {
-                options.headers[name] = request.headers[name];
-            }
-        }   
-        
-
-        var xhr = http.request(options);
-
-        result.abort = function () {
-            if (done) {
-                return;
-            }
-
-            done = true;
-            if (xhr) {
-                xhr.abort();
-                xhr = null;
-            }
-
-            error({ message: "Request aborted" });
-        };
-
-        // Set the timeout if available.
-        if (request.timeoutMS) {
-            xhr.setTimeout(request.timeoutMS,function () {
-                if (!done) {
-                    done = true;
-                    xhr = null;
-                    error({ message: "Request timed out" });
-                }
-            });
-        }
-
-        xhr.on('error', function(e) {
-            var response = { requestUri: url, statusCode: 400, statusText: e.message };
-            error({ message: "HTTP request failed", request: request, response: response });
-        });
-             
-
-        xhr.on('response', function (resp) {
-            if (done || xhr === null) {
-                return;
-            }
-
-            var headers = [];
-            readResponseHeaders(resp.headers, headers);
-                        
-            var body = '';
-
-            resp.on('data', function(chunk) {
-                body+=chunk;
-            });
-            resp.on('end', function() {
-                // do what you do
-                var response = { requestUri: url, statusCode: resp.statusCode, statusText: '', headers: headers, body: body };
-
-                done = true;
-                xhr = null;
-                if (resp.statusCode >= 200 && resp.statusCode <= 299) {
-                    success(response);
-                } else {
-                    error({ message: "HTTP request failed", request: request, response: response });
-                }   
-            });
-        });
-
-        //xhr.open(request.method || "GET", url, true,);
-        if (request.body) {
-            xhr.write(request.body);
-        }
-        xhr.end();
-
-        return result;
-    }
-};
-
-
-
-exports.canUseJSONP = canUseJSONP;
-exports.isAbsoluteUrl = isAbsoluteUrl;
-exports.isLocalUrl = isLocalUrl;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/odata/odatautils.js
----------------------------------------------------------------------
diff --git a/src/lib/odata/odatautils.js b/src/lib/odata/odatautils.js
deleted file mode 100644
index 78b9c5a..0000000
--- a/src/lib/odata/odatautils.js
+++ /dev/null
@@ -1,1273 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
- /** @module odata/utils */
-
-var utils    = require('./../utils.js');
-
-// Imports
-var assigned = utils.assigned;
-var contains = utils.contains;
-var find = utils.find;
-var isArray = utils.isArray;
-var isDate = utils.isDate;
-var isObject = utils.isObject;
-var parseInt10 = utils.parseInt10;
-
-
-/** Gets the type name of a data item value that belongs to a feed, an entry, a complex type property, or a collection property
- * @param {string} value - Value of the data item from which the type name is going to be retrieved.
- * @param {object} [metadata] - Object containing metadata about the data tiem.
- * @returns {string} Data item type name; null if the type name cannot be found within the value or the metadata
- * 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.
- */
-var dataItemTypeName = function (value, metadata) {
-    var valueTypeName = ((value && value.__metadata) || {}).type;
-    return valueTypeName || (metadata ? metadata.type : null);
-};
-
-var EDM = "Edm.";
-var EDM_BOOLEAN = EDM + "Boolean";
-var EDM_BYTE = EDM + "Byte";
-var EDM_SBYTE = EDM + "SByte";
-var EDM_INT16 = EDM + "Int16";
-var EDM_INT32 = EDM + "Int32";
-var EDM_INT64 = EDM + "Int64";
-var EDM_SINGLE = EDM + "Single";
-var EDM_DOUBLE = EDM + "Double";
-var EDM_DECIMAL = EDM + "Decimal";
-var EDM_STRING = EDM + "String";
-
-var EDM_BINARY = EDM + "Binary";
-var EDM_DATE = EDM + "Date";
-var EDM_DATETIMEOFFSET = EDM + "DateTimeOffset";
-var EDM_DURATION = EDM + "Duration";
-var EDM_GUID = EDM + "Guid";
-var EDM_TIMEOFDAY = EDM + "Time";
-
-var GEOGRAPHY = "Geography";
-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 GEOGRAPHY_POINT = GEOGRAPHY + "Point";
-var GEOGRAPHY_LINESTRING = GEOGRAPHY + "LineString";
-var GEOGRAPHY_POLYGON = GEOGRAPHY + "Polygon";
-var GEOGRAPHY_COLLECTION = GEOGRAPHY + "Collection";
-var GEOGRAPHY_MULTIPOLYGON = GEOGRAPHY + "MultiPolygon";
-var GEOGRAPHY_MULTILINESTRING = GEOGRAPHY + "MultiLineString";
-var GEOGRAPHY_MULTIPOINT = GEOGRAPHY + "MultiPoint";
-
-var GEOMETRY = "Geometry";
-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 GEOMETRY_POINT = GEOMETRY + "Point";
-var GEOMETRY_LINESTRING = GEOMETRY + "LineString";
-var GEOMETRY_POLYGON = GEOMETRY + "Polygon";
-var GEOMETRY_COLLECTION = GEOMETRY + "Collection";
-var GEOMETRY_MULTIPOLYGON = GEOMETRY + "MultiPolygon";
-var GEOMETRY_MULTILINESTRING = GEOMETRY + "MultiLineString";
-var GEOMETRY_MULTIPOINT = 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_DATE,
-    EDM_DATETIMEOFFSET,
-    EDM_DURATION,
-    EDM_TIMEOFDAY,
-    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 geometryTypes = [
-    GEOMETRY,
-    GEOMETRY_POINT,
-    GEOMETRY_LINESTRING,
-    GEOMETRY_POLYGON,
-    GEOMETRY_COLLECTION,
-    GEOMETRY_MULTIPOLYGON,
-    GEOMETRY_MULTILINESTRING,
-    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 geographyTypes = [
-    GEOGRAPHY,
-    GEOGRAPHY_POINT,
-    GEOGRAPHY_LINESTRING,
-    GEOGRAPHY_POLYGON,
-    GEOGRAPHY_COLLECTION,
-    GEOGRAPHY_MULTIPOLYGON,
-    GEOGRAPHY_MULTILINESTRING,
-    GEOGRAPHY_MULTIPOINT
-];
-
-/** Invokes a function once per schema in metadata.
- * @param metadata - Metadata store; one of edmx, schema, or an array of any of them.
- * @param {Function} callback - Callback function to invoke once per schema.
- * @returns The first truthy value to be returned from the callback; null or the last falsy value otherwise.
- */
-function forEachSchema(metadata, callback) {
-    
-
-    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);
-    }
-}
-
-/** Formats a millisecond and a nanosecond value into a single string.
- * @param {Number} ms - Number of milliseconds to format.
- * @param {Number} ns - Number of nanoseconds to format.
- * @returns {String} Formatted text.
- * If the value is already as string it's returned as-is.
- */
-function formatMilliseconds(ms, ns) {
-
-    // 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;
-}
-
-function formatDateTimeOffsetJSON(value) {
-    return "\/Date(" + value.getTime() + ")\/";
-}
-
-/** Formats a DateTime or DateTimeOffset value a string.
- * @param {Date} value - Value to format
- * @returns {String} Formatted text.
- * If the value is already as string it's returned as-is
-´*/
-function formatDateTimeOffset(value) {
-
-    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;
-}
-
-/** Converts a duration to a string in xsd:duration format.
- * @param {Object} value - Object with ms and __edmType properties.
- * @returns {String} String representation of the time object in xsd:duration format.
- */
-function formatDuration(value) {
-
-    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";
-}
-
-/** Formats the specified value to the given width.
- * @param {Number} value - Number to format (non-negative).
- * @param {Number} width - Minimum width for number.
- * @param {Boolean} append - Flag indicating if the value is padded at the beginning (false) or at the end (true).
- * @returns {String} Text representation.
- */
-function formatNumberWidth(value, width, append) {
-    var result = value.toString(10);
-    while (result.length < width) {
-        if (append) {
-            result += "0";
-        } else {
-            result = "0" + result;
-        }
-    }
-
-    return result;
-}
-
-/** Gets the canonical timezone representation.
- * @param {String} timezone - Timezone representation.
- * @returns {String} An 'Z' string if the timezone is absent or 0; the timezone otherwise.
- */
-function getCanonicalTimezone(timezone) {
-
-    return (!timezone || timezone === "Z" || timezone === "+00:00" || timezone === "-00:00") ? "Z" : timezone;
-}
-
-/** Gets the type of a collection type name.
- * @param {String} typeName - Type name of the collection.
- * @returns {String} Type of the collection; null if the type name is not a collection type.
- */
-function getCollectionType(typeName) {
-
-    if (typeof typeName === "string") {
-        var end = typeName.indexOf(")", 10);
-        if (typeName.indexOf("Collection(") === 0 && end > 0) {
-            return typeName.substring(11, end);
-        }
-    }
-    return null;
-}
-
-/** Sends a request containing OData payload to a server.
-* @param request - Object that represents the request to be sent..
-* @param success - Callback for a successful read operation.
-* @param error - Callback for handling errors.
-* @param handler - Handler for data serialization.
-* @param httpClient - HTTP client layer.
-* @param context - Context used for processing the request
-*/
-function invokeRequest(request, success, error, handler, httpClient, context) {
-
-    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;
-        }
-        // errors in success handler for sync requests result in error handler calls. So here we fix this. 
-        try {
-            success(response.data, response);
-        } catch (err) {
-            err.bIsSuccessHandlerError = true;
-            throw err;
-        }
-    }, error);
-}
-
-/** Tests whether a value is a batch object in the library's internal representation.
- * @param value - Value to test.
- * @returns {Boolean} True is the value is a batch object; false otherwise.
- */
-function isBatch(value) {
-
-    return isComplex(value) && isArray(value.__batchRequests);
-}
-
-// Regular expression used for testing and parsing for a collection type.
-var collectionTypeRE = /Collection\((.*)\)/;
-
-/** Tests whether a value is a collection value in the library's internal representation.
- * @param value - Value to test.
- * @param {String} typeName - Type name of the value. This is used to disambiguate from a collection property value.
- * @returns {Boolean} True is the value is a feed value; false otherwise.
- */
-function isCollection(value, typeName) {
-
-    var colData = value && value.results || value;
-    return !!colData &&
-        (isCollectionType(typeName)) ||
-        (!typeName && isArray(colData) && !isComplex(colData[0]));
-}
-
-/** Checks whether the specified type name is a collection type.
- * @param {String} typeName - Name of type to check.
- * @returns {Boolean} True if the type is the name of a collection type; false otherwise.
- */
-function isCollectionType(typeName) {
-    return collectionTypeRE.test(typeName);
-}
-
-/** Tests whether a value is a complex type value in the library's internal representation.
- * @param value - Value to test.
- * @returns {Boolean} True is the value is a complex type value; false otherwise.
- */
-function isComplex(value) {
-
-    return !!value &&
-        isObject(value) &&
-        !isArray(value) &&
-        !isDate(value);
-}
-
-/** Checks whether a Date object is DateTimeOffset value
- * @param {Date} value - Value to check
- * @returns {Boolean} true if the value is a DateTimeOffset, false otherwise.
- */
-function isDateTimeOffset(value) {
-    return (value.__edmType === "Edm.DateTimeOffset" || (!value.__edmType && value.__offset));
-}
-
-/** Tests whether a value is a deferred navigation property in the library's internal representation.
- * @param value - Value to test.
- * @returns {Boolean} True is the value is a deferred navigation property; false otherwise.
- */
-function isDeferred(value) {
-
-    if (!value && !isComplex(value)) {
-        return false;
-    }
-    var metadata = value.__metadata || {};
-    var deferred = value.__deferred || {};
-    return !metadata.type && !!deferred.uri;
-}
-
-/** Tests whether a value is an entry object in the library's internal representation.
- * @param value - Value to test.
- * @returns {Boolean} True is the value is an entry object; false otherwise.
- */
-function isEntry(value) {
-
-    return isComplex(value) && value.__metadata && "uri" in value.__metadata;
-}
-
-/** Tests whether a value is a feed value in the library's internal representation.
- * @param value - Value to test.
- * @param {String} typeName - Type name of the value. This is used to disambiguate from a collection property value.
- * @returns {Boolean} True is the value is a feed value; false otherwise.
- */
-function isFeed(value, typeName) {
-
-    var feedData = value && value.results || value;
-    return isArray(feedData) && (
-        (!isCollectionType(typeName)) &&
-        (isComplex(feedData[0]))
-    );
-}
-
-/** Checks whether the specified type name is a geography EDM type.
- * @param {String} typeName - Name of type to check.
- * @returns {Boolean} True if the type is a geography EDM type; false otherwise.
- */
-function isGeographyEdmType(typeName) {
-    //check with edm
-    return contains(geographyEdmTypes, typeName) ||
-        (typeName.indexOf('.') === -1 && contains(geographyTypes, typeName));
-        
-}
-
-/** Checks whether the specified type name is a geometry EDM type.
- * @param {String} typeName - Name of type to check.
- * @returns {Boolean} True if the type is a geometry EDM type; false otherwise.
- */
-function isGeometryEdmType(typeName) {
-    return contains(geometryEdmTypes, typeName) ||
-        (typeName.indexOf('.') === -1 && contains(geometryTypes, typeName));
-}
-
-
-
-/** Tests whether a value is a named stream value in the library's internal representation.
- * @param value - Value to test.
- * @returns {Boolean} True is the value is a named stream; false otherwise.
- */
-function isNamedStream(value) {
-
-    if (!value && !isComplex(value)) {
-        return false;
-    }
-    var metadata = value.__metadata;
-    var mediaResource = value.__mediaresource;
-    return !metadata && !!mediaResource && !!mediaResource.media_src;
-}
-
-/** Tests whether a value is a primitive type value in the library's internal representation.
- * @param value - Value to test.
- * @returns {Boolean} True is the value is a primitive type value.
- * Date objects are considered primitive types by the library.
- */
-function isPrimitive(value) {
-
-    return isDate(value) ||
-        typeof value === "string" ||
-        typeof value === "number" ||
-        typeof value === "boolean";
-}
-
-/** Checks whether the specified type name is a primitive EDM type.
- * @param {String} typeName - Name of type to check.
- * @returns {Boolean} True if the type is a primitive EDM type; false otherwise.
- */
-function isPrimitiveEdmType(typeName) {
-
-    return contains(primitiveEdmTypes, typeName);
-}
-
-/** Gets the kind of a navigation property value.
- * @param value - Value of the navigation property.
- * @param {Object} [propertyModel] - Object that describes the navigation property in an OData conceptual schema.
- * @returns {String} String value describing the kind of the navigation property; null if the kind cannot be determined.
- */
-function navigationPropertyKind(value, propertyModel) {
-
-    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;
-}
-
-/** Looks up a property by name.
- * @param {Array} properties - Array of property objects as per EDM metadata (may be null)
- * @param {String} name - Name to look for.
- * @returns {Object} The property object; null if not found.
- */
-function lookupProperty(properties, name) {
-
-    return find(properties, function (property) {
-        return property.name === name;
-    });
-}
-
-/** Looks up a type object by name.
- * @param {String} name - Name, possibly null or empty.
- * @param metadata - Metadata store; one of edmx, schema, or an array of any of them.
- * @param {String} kind - Kind of object to look for as per EDM metadata.
- * @returns An type description if the name is found; null otherwise
- */
-function lookupInMetadata(name, metadata, kind) {
-
-    return (name) ? forEachSchema(metadata, function (schema) {
-        return lookupInSchema(name, schema, kind);
-    }) : null;
-}
-
-/** Looks up a entity set by name.
- * @param {Array} entitySets - Array of entity set objects as per EDM metadata( may be null)
- * @param {String} name - Name to look for.
- * @returns {Object} The entity set object; null if not found.
- */
-function lookupEntitySet(entitySets, name) {
-
-    return find(entitySets, function (entitySet) {
-        return entitySet.name === name;
-    });
-}
-
-/** Looks up a entity set by name.
- * @param {Array} singletons - Array of entity set objects as per EDM metadata (may be null)
- * @param {String} name - Name to look for.
- * @returns {Object} The entity set object; null if not found.
- */
-function lookupSingleton(singletons, name) {
-
-    return find(singletons, function (singleton) {
-        return singleton.name === name;
-    });
-}
-
-/** Looks up a complex type object by name.
- * @param {String} name - Name, possibly null or empty.
- * @param metadata - Metadata store; one of edmx, schema, or an array of any of them.
- * @returns A complex type description if the name is found; null otherwise.
- */
-function lookupComplexType(name, metadata) {
-
-    return lookupInMetadata(name, metadata, "complexType");
-}
-
-/** Looks up an entity type object by name.
- * @param {String} name - Name, possibly null or empty.
- * @param metadata - Metadata store; one of edmx, schema, or an array of any of them.
- * @returns An entity type description if the name is found; null otherwise.
- */
-function lookupEntityType(name, metadata) {
-
-    return lookupInMetadata(name, metadata, "entityType");
-}
-
-
-/** Looks up an
- * @param metadata - Metadata store; one of edmx, schema, or an array of any of them.
- * @returns An entity container description if the name is found; null otherwise.
- */
-function lookupDefaultEntityContainer(metadata) {
-
-    return forEachSchema(metadata, function (schema) {
-        if (isObject(schema.entityContainer)) { 
-            return schema.entityContainer;
-        }
-    });
-}
-
-/** Looks up an entity container object by name.
- * @param {String} name - Name, possibly null or empty.
- * @param metadata - Metadata store; one of edmx, schema, or an array of any of them.
- * @returns An entity container description if the name is found; null otherwise.
- */
-function lookupEntityContainer(name, metadata) {
-
-    return lookupInMetadata(name, metadata, "entityContainer");
-}
-
-/** Looks up a function import by name.
- * @param {Array} functionImports - Array of function import objects as per EDM metadata (May be null)
- * @param {String} name - Name to look for.
- * @returns {Object} The entity set object; null if not found.
- */
-function lookupFunctionImport(functionImports, name) {
-    return find(functionImports, function (functionImport) {
-        return functionImport.name === name;
-    });
-}
-
-/** Looks up the target entity type for a navigation property.
- * @param {Object} navigationProperty - 
- * @param {Object} metadata - 
- * @returns {String} The entity type name for the specified property, null if not found.
- */
-function lookupNavigationPropertyType(navigationProperty, metadata) {
-
-    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;
-}
-
-/** Looks up the target entityset name for a navigation property.
- * @param {Object} navigationProperty - 
- * @param {Object} sourceEntitySetName -
- * @param {Object} metadata -
- * metadata
- * @returns {String} The entityset name for the specified property, null if not found.
- */
-function lookupNavigationPropertyEntitySet(navigationProperty, sourceEntitySetName, metadata) {
-
-    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;
-}
-
-/** Gets the entitySet info, container name and functionImports for an entitySet
- * @param {Object} entitySetName -
- * @param {Object} metadata - 
- * @returns {Object} The info about the entitySet.
- */
-function getEntitySetInfo(entitySetName, metadata) {
-
-    var info = forEachSchema(metadata, function (schema) {
-        var container = schema.entityContainer;
-        var entitySets = container.entitySet;
-        if (entitySets) {
-            for (var j = 0; j < entitySets.length; j++) {
-                if (entitySets[j].name == entitySetName) {
-                    return { entitySet: entitySets[j], containerName: container.name, functionImport: container.functionImport };
-                }
-            }
-        }
-        return null;
-    });
-
-    return info;
-}
-
-/** Given an expected namespace prefix, removes it from a full name.
- * @param {String} ns - Expected namespace.
- * @param {String} fullName - Full name in 'ns'.'name' form.
- * @returns {String} The local name, null if it isn't found in the expected namespace.
- */
-function removeNamespace(ns, fullName) {
-
-    if (fullName.indexOf(ns) === 0 && fullName.charAt(ns.length) === ".") {
-        return fullName.substr(ns.length + 1);
-    }
-
-    return null;
-}
-
-/** Looks up a schema object by name.
- * @param {String} name - Name (assigned).
- * @param schema - Schema object as per EDM metadata.
- * @param {String} kind - Kind of object to look for as per EDM metadata.
- * @returns An entity type description if the name is found; null otherwise.
- */
-function lookupInSchema(name, schema, kind) {
-
-    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;
-}
-
-/** Compares to version strings and returns the higher one.
- * @param {String} left - Version string in the form "major.minor.rev"
- * @param {String} right - Version string in the form "major.minor.rev"
- * @returns {String} The higher version string.
- */
-function maxVersion(left, right) {
-
-    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",
-    "content-id": "Content-ID",
-    "content-transfer-encoding": "Content-Transfer-Encoding",
-    
-    // Headers used by response
-    "etag": "ETag",
-    "location": "Location",
-    "odata-entityid": "OData-EntityId",
-    "preference-applied": "Preference-Applied",
-    "retry-after": "Retry-After"
-};
-
-/** Normalizes headers so they can be found with consistent casing.
- * @param {Object} headers - Dictionary of name/value pairs.
- */
-function normalizeHeaders(headers) {
-
-    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;
-        }
-    }
-}
-
-/** Parses a string into a boolean value.
- * @param propertyValue - Value to parse.
- * @returns {Boolean} true if the property value is 'true'; false otherwise.
- */
-function parseBool(propertyValue) {
-
-    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+))?(.*)$/;
-
-/** Parses a string into a DateTime value.
- * @param {String} value - Value to parse.
- * @param {Boolean} withOffset - Whether offset is expected.
- * @param {Boolean} nullOnError - return null instead of throwing an exception
- * @returns {Date} The parsed value.
- */
-function parseDateTimeMaybeOffset(value, withOffset, nullOnError) {
-
-    // 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;
-}
-
-/** Parses a string into a Date object.
- * @param {String} propertyValue - Value to parse.
- * @param {Boolean} nullOnError - return null instead of throwing an exception
- * @returns {Date} The parsed with year, month, day set, time values are set to 0
- */
-function parseDate(propertyValue, nullOnError) {
-    var parts = propertyValue.split('-');
-
-    if (parts.length != 3 && nullOnError) {
-        return null;
-    }
-    return new Date(
-        parseInt10(parts[0]),       // Year.
-        parseInt10(parts[1]) - 1,   // Month (zero-based for Date.UTC and setFullYear).
-        parseInt10(parts[2],
-        0,0,0,0)        // Date.
-        );
-
-}
-
-var parseTimeOfDayRE = /^(\d+):(\d+)(:(\d+)(.(\d+))?)?$/;
-
-/**Parses a time into a Date object.
- * @param propertyValue
- * @param {Boolean} nullOnError - return null instead of throwing an exception
- * @returns {{h: Number, m: Number, s: Number, ms: Number}}
- */
-function parseTimeOfDay(propertyValue, nullOnError) {
-    var parts = parseTimeOfDayRE.exec(propertyValue);
-
-
-    return {
-        'h' :parseInt10(parts[1]),
-        'm' :parseInt10(parts[2]),
-        's' :parseInt10(parts[4]),
-        'ms' :parseInt10(parts[6])
-     };
-}
-
-/** Parses a string into a DateTimeOffset value.
- * @param {String} propertyValue - Value to parse.
- * @param {Boolean} nullOnError - return null instead of throwing an exception
- * @returns {Date} The parsed value.
- * 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.
- */
-function parseDateTimeOffset(propertyValue, nullOnError) {
-    
-
-    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)?)?/;
-
-function isEdmDurationValue(value) {
-    parseTimeRE.test(value);
-}
-
-/** Parses a string in xsd:duration format.
- * @param {String} duration - Duration value.
-
- * This method will throw an exception if the input string has a year or a month component.
-
- * @returns {Object} Object representing the time
- */
-function parseDuration(duration) {
-
-    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;
-}
-
-/** Parses a timezone description in (+|-)nn:nn format.
- * @param {String} timezone - Timezone offset.
- * @returns {Object} An object with a (d)irection property of 1 for + and -1 for -, offset (h)ours and offset (m)inutes.
- */
-function parseTimezone(timezone) {
-
-    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 };
-}
-
-/** Prepares a request object so that it can be sent through the network.
-* @param request - Object that represents the request to be sent.
-* @param handler - Handler for data serialization
-* @param context - Context used for preparing the request
-*/
-function prepareRequest(request, handler, context) {
-
-    // 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";
-    }
-
-    if (request.async === undefined) {
-        request.async = true;
-    }
-
-}
-
-/** Traverses a tree of objects invoking callback for every value.
- * @param {Object} item - Object or array to traverse.
- * @param {Object} owner - Pass through each callback
- * @param {Function} callback - Callback function with key and value, similar to JSON.parse reviver.
- * @returns {Object} The object with traversed properties.
- Unlike the JSON reviver, this won't delete null members.
-*/
-function traverseInternal(item, owner, callback) {
-
-    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;
-}
-
-/** Traverses a tree of objects invoking callback for every value.
- * @param {Object} item - Object or array to traverse.
- * @param {Function} callback - Callback function with key and value, similar to JSON.parse reviver.
- * @returns {Object} The traversed object.
- * Unlike the JSON reviver, this won't delete null members.
-*/
-function traverse(item, callback) {
-
-    return callback("", traverseInternal(item, "", callback));
-}
-
-exports.dataItemTypeName = dataItemTypeName;
-exports.EDM_BINARY = EDM_BINARY;
-exports.EDM_BOOLEAN = EDM_BOOLEAN;
-exports.EDM_BYTE = EDM_BYTE;
-exports.EDM_DATE = EDM_DATE;
-exports.EDM_DATETIMEOFFSET = EDM_DATETIMEOFFSET;
-exports.EDM_DURATION = EDM_DURATION;
-exports.EDM_DECIMAL = EDM_DECIMAL;
-exports.EDM_DOUBLE = EDM_DOUBLE;
-exports.EDM_GEOGRAPHY = EDM_GEOGRAPHY;
-exports.EDM_GEOGRAPHY_POINT = EDM_GEOGRAPHY_POINT;
-exports.EDM_GEOGRAPHY_LINESTRING = EDM_GEOGRAPHY_LINESTRING;
-exports.EDM_GEOGRAPHY_POLYGON = EDM_GEOGRAPHY_POLYGON;
-exports.EDM_GEOGRAPHY_COLLECTION = EDM_GEOGRAPHY_COLLECTION;
-exports.EDM_GEOGRAPHY_MULTIPOLYGON = EDM_GEOGRAPHY_MULTIPOLYGON;
-exports.EDM_GEOGRAPHY_MULTILINESTRING = EDM_GEOGRAPHY_MULTILINESTRING;
-exports.EDM_GEOGRAPHY_MULTIPOINT = EDM_GEOGRAPHY_MULTIPOINT;
-exports.EDM_GEOMETRY = EDM_GEOMETRY;
-exports.EDM_GEOMETRY_POINT = EDM_GEOMETRY_POINT;
-exports.EDM_GEOMETRY_LINESTRING = EDM_GEOMETRY_LINESTRING;
-exports.EDM_GEOMETRY_POLYGON = EDM_GEOMETRY_POLYGON;
-exports.EDM_GEOMETRY_COLLECTION = EDM_GEOMETRY_COLLECTION;
-exports.EDM_GEOMETRY_MULTIPOLYGON = EDM_GEOMETRY_MULTIPOLYGON;
-exports.EDM_GEOMETRY_MULTILINESTRING = EDM_GEOMETRY_MULTILINESTRING;
-exports.EDM_GEOMETRY_MULTIPOINT = EDM_GEOMETRY_MULTIPOINT;
-exports.EDM_GUID = EDM_GUID;
-exports.EDM_INT16 = EDM_INT16;
-exports.EDM_INT32 = EDM_INT32;
-exports.EDM_INT64 = EDM_INT64;
-exports.EDM_SBYTE = EDM_SBYTE;
-exports.EDM_SINGLE = EDM_SINGLE;
-exports.EDM_STRING = EDM_STRING;
-exports.EDM_TIMEOFDAY = EDM_TIMEOFDAY;
-exports.GEOJSON_POINT = GEOJSON_POINT;
-exports.GEOJSON_LINESTRING = GEOJSON_LINESTRING;
-exports.GEOJSON_POLYGON = GEOJSON_POLYGON;
-exports.GEOJSON_MULTIPOINT = GEOJSON_MULTIPOINT;
-exports.GEOJSON_MULTILINESTRING = GEOJSON_MULTILINESTRING;
-exports.GEOJSON_MULTIPOLYGON = GEOJSON_MULTIPOLYGON;
-exports.GEOJSON_GEOMETRYCOLLECTION = GEOJSON_GEOMETRYCOLLECTION;
-exports.forEachSchema = forEachSchema;
-exports.formatDateTimeOffset = formatDateTimeOffset;
-exports.formatDateTimeOffsetJSON = formatDateTimeOffsetJSON;
-exports.formatDuration = formatDuration;
-exports.formatNumberWidth = formatNumberWidth;
-exports.getCanonicalTimezone = getCanonicalTimezone;
-exports.getCollectionType = getCollectionType;
-exports.invokeRequest = invokeRequest;
-exports.isBatch = isBatch;
-exports.isCollection = isCollection;
-exports.isCollectionType = isCollectionType;
-exports.isComplex = isComplex;
-exports.isDateTimeOffset = isDateTimeOffset;
-exports.isDeferred = isDeferred;
-exports.isEntry = isEntry;
-exports.isFeed = isFeed;
-exports.isGeographyEdmType = isGeographyEdmType;
-exports.isGeometryEdmType = isGeometryEdmType;
-exports.isNamedStream = isNamedStream;
-exports.isPrimitive = isPrimitive;
-exports.isPrimitiveEdmType = isPrimitiveEdmType;
-exports.lookupComplexType = lookupComplexType;
-exports.lookupDefaultEntityContainer = lookupDefaultEntityContainer;
-exports.lookupEntityContainer = lookupEntityContainer;
-exports.lookupEntitySet = lookupEntitySet;
-exports.lookupSingleton = lookupSingleton;
-exports.lookupEntityType = lookupEntityType;
-exports.lookupFunctionImport = lookupFunctionImport;
-exports.lookupNavigationPropertyType = lookupNavigationPropertyType;
-exports.lookupNavigationPropertyEntitySet = lookupNavigationPropertyEntitySet;
-exports.lookupInSchema = lookupInSchema;
-exports.lookupProperty = lookupProperty;
-exports.lookupInMetadata = lookupInMetadata;
-exports.getEntitySetInfo = getEntitySetInfo;
-exports.maxVersion = maxVersion;
-exports.navigationPropertyKind = navigationPropertyKind;
-exports.normalizeHeaders = normalizeHeaders;
-exports.parseBool = parseBool;
-
-
-exports.parseDate = parseDate;
-exports.parseDateTimeOffset = parseDateTimeOffset;
-exports.parseDuration = parseDuration;
-exports.parseTimeOfDay = parseTimeOfDay;
-
-exports.parseInt10 = parseInt10;
-exports.prepareRequest = prepareRequest;
-exports.removeNamespace = removeNamespace;
-exports.traverse = traverse;
-
-

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/store.js
----------------------------------------------------------------------
diff --git a/src/lib/store.js b/src/lib/store.js
deleted file mode 100644
index d7e321d..0000000
--- a/src/lib/store.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-//'use strict';
-
- /** @module store */
-
-
-
-
-
-exports.defaultStoreMechanism = "best";
-
-/** Creates a new store object.
- * @param {String} name - Store name.
- * @param {String} [mechanism] - 
- * @returns {Object} Store object.
-*/
-exports.createStore = function (name, mechanism) {
-
-
-    if (!mechanism) {
-        mechanism = exports.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 };
-};
-
-exports.DomStore       = DomStore       = require('./store/dom.js');
-exports.IndexedDBStore = IndexedDBStore = require('./store/indexeddb.js');
-exports.MemoryStore    = MemoryStore    = require('./store/memory.js');
-
-var mechanisms = {
-    indexeddb: IndexedDBStore,
-    dom: DomStore,
-    memory: MemoryStore
-};
-
-exports.mechanisms = mechanisms;
-
-
-
-

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/store/dom.js
----------------------------------------------------------------------
diff --git a/src/lib/store/dom.js b/src/lib/store/dom.js
deleted file mode 100644
index e14bb6b..0000000
--- a/src/lib/store/dom.js
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-/** @module store/dom */
-
-
-
-var utils = require('./../utils.js');
-
-// Imports.
-var throwErrorCallback = utils.throwErrorCallback;
-var delay = utils.delay;
-
-var localStorage = null;
-
-/** This method is used to override the Date.toJSON method and is called only by
- * JSON.stringify.  It should never be called directly.
- * @summary Converts a Date object into an object representation friendly to JSON serialization.
- * @returns {Object} Object that represents the Date.
- */
-function domStoreDateToJSON() {
-    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;
-}
-
-/** This method is used during JSON parsing and invoked only by the reviver function.
- * It should never be called directly.
- * @summary JSON reviver function for converting an object representing a Date in a JSON stream to a Date object
- * @param value _
- * @param value - Object to convert.
- * @returns {Date} Date object.
- */
-function domStoreJSONToDate(_, value) {
-    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;
-}
-
-/** Qualifies the key with the name of the store.
- * @param {Object} store - Store object whose name will be used for qualifying the key.
- * @param {String} key - Key string.
- * @returns {String} Fully qualified key string.
- */
-function qualifyDomStoreKey(store, key) {
-    return store.name + "#!#" + key;
-}
-
-/** Gets the key part of a fully qualified key string.
- * @param {Object} store - Store object whose name will be used for qualifying the key.
- * @param {String} key - Fully qualified key string.
- * @returns {String} Key part string
- */
-function unqualifyDomStoreKey(store, key) {
-    return key.replace(store.name + "#!#", "");
-}
-
-/** Constructor for store objects that use DOM storage as the underlying mechanism.
- * @class DomStore
- * @constructor
- * @param {String} name - Store name.
- */
-function DomStore(name) {
-    this.name = name;
-}
-
-/** Creates a store object that uses DOM Storage as its underlying mechanism.
- * @method module:store/dom~DomStore.create
- * @param {String} name - Store name.
- * @returns {Object} Store object.
- */
-DomStore.create = function (name) {
-
-    if (DomStore.isSupported()) {
-        localStorage = localStorage || window.localStorage;
-        return new DomStore(name);
-    }
-
-    throw { message: "Web Storage not supported by the browser" };
-};
-
-/** Checks whether the underlying mechanism for this kind of store objects is supported by the browser.
- * @method DomStore.isSupported
- * @returns {Boolean} - True if the mechanism is supported by the browser; otherwise false.
-*/
-DomStore.isSupported = function () {
-    return !!window.localStorage;
-};
-
-/** Adds a new value identified by a key to the store.
- * @method module:store/dom~DomStore#add
- * @param {String} key - Key string.
- * @param value - Value that is going to be added to the store.
- * @param {Function} success - Callback for a successful add operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
- * This method errors out if the store already contains the specified key.
- */
-DomStore.prototype.add = function (key, value, success, error) {
-    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);
-};
-
-/** 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.
- * @summary Adds or updates a value identified by a key to the store.
- * @method module:store/dom~DomStore#addOrUpdate
- * @param {String} key - Key string.
- * @param value - Value that is going to be added or updated to the store.
- * @param {Function} success - Callback for a successful add or update operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
- */
-DomStore.prototype.addOrUpdate = function (key, value, success, error) {
-    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;
-        }
-    }
-};
-
-/** In case of an error, this method will not restore any keys that might have been deleted at that point.
- * @summary Removes all the data associated with this store object.
- * @method module:store/dom~DomStore#clear
- * @param {Function} success - Callback for a successful clear operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
- */
-DomStore.prototype.clear = function (success, error) {
-
-    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);
-    }
-};
-
-/** This function does nothing in DomStore as it does not have a connection model
- * @method module:store/dom~DomStore#close
- */
-DomStore.prototype.close = function () {
-};
-
-/** Checks whether a key exists in the store.
- * @method module:store/dom~DomStore#contains
- * @param {String} key - Key string.
- * @param {Function} success - Callback indicating whether the store contains the key or not.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
-*/
-DomStore.prototype.contains = function (key, success, error) {
-    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;
-
-/** Gets all the keys that exist in the store.
- * @method module:store/dom~DomStore#getAllKeys
- * @param {Function} success - Callback for a successful get operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
- */
-DomStore.prototype.getAllKeys = function (success, error) {
-
-    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);
-    }
-};
-
-/** Identifies the underlying mechanism used by the store.*/
-DomStore.prototype.mechanism = "dom";
-
-/** Reads the value associated to a key in the store.
- * @method module:store/dom~DomStore#read
- * @param {String} key - Key string.
- * @param {Function} success - Callback for a successful reads operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
- */
-DomStore.prototype.read = function (key, success, error) {
-
-    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);
-        }
-    }
-};
-
-/** Removes a key and its value from the store.
- * @method module:store/dom~DomStore#remove
- * @param {String} key - Key string.
- * @param {Function} success - Callback for a successful remove operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
- */
-DomStore.prototype.remove = function (key, success, error) {
-    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);
-        }
-    }
-};
-
-/** Updates the value associated to a key in the store.
- * @method module:store/dom~DomStore#update
- * @param {String} key - Key string.
- * @param value - New value.
- * @param {Function} success - Callback for a successful update operation.
- * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked
- * This method errors out if the specified key is not found in the store.
- */
-DomStore.prototype.update = function (key, value, success, error) {
-    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);
-};
-
-module.exports = DomStore;
\ No newline at end of file


[5/8] olingo-odata4-js git commit: [OLINGO-442] Cleanup bevore release II and beta-name removal

Posted by ko...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/store/dom.js
----------------------------------------------------------------------
diff --git a/lib/store/dom.js b/lib/store/dom.js
new file mode 100644
index 0000000..e14bb6b
--- /dev/null
+++ b/lib/store/dom.js
@@ -0,0 +1,332 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+/** @module store/dom */
+
+
+
+var utils = require('./../utils.js');
+
+// Imports.
+var throwErrorCallback = utils.throwErrorCallback;
+var delay = utils.delay;
+
+var localStorage = null;
+
+/** This method is used to override the Date.toJSON method and is called only by
+ * JSON.stringify.  It should never be called directly.
+ * @summary Converts a Date object into an object representation friendly to JSON serialization.
+ * @returns {Object} Object that represents the Date.
+ */
+function domStoreDateToJSON() {
+    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;
+}
+
+/** This method is used during JSON parsing and invoked only by the reviver function.
+ * It should never be called directly.
+ * @summary JSON reviver function for converting an object representing a Date in a JSON stream to a Date object
+ * @param value _
+ * @param value - Object to convert.
+ * @returns {Date} Date object.
+ */
+function domStoreJSONToDate(_, value) {
+    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;
+}
+
+/** Qualifies the key with the name of the store.
+ * @param {Object} store - Store object whose name will be used for qualifying the key.
+ * @param {String} key - Key string.
+ * @returns {String} Fully qualified key string.
+ */
+function qualifyDomStoreKey(store, key) {
+    return store.name + "#!#" + key;
+}
+
+/** Gets the key part of a fully qualified key string.
+ * @param {Object} store - Store object whose name will be used for qualifying the key.
+ * @param {String} key - Fully qualified key string.
+ * @returns {String} Key part string
+ */
+function unqualifyDomStoreKey(store, key) {
+    return key.replace(store.name + "#!#", "");
+}
+
+/** Constructor for store objects that use DOM storage as the underlying mechanism.
+ * @class DomStore
+ * @constructor
+ * @param {String} name - Store name.
+ */
+function DomStore(name) {
+    this.name = name;
+}
+
+/** Creates a store object that uses DOM Storage as its underlying mechanism.
+ * @method module:store/dom~DomStore.create
+ * @param {String} name - Store name.
+ * @returns {Object} Store object.
+ */
+DomStore.create = function (name) {
+
+    if (DomStore.isSupported()) {
+        localStorage = localStorage || window.localStorage;
+        return new DomStore(name);
+    }
+
+    throw { message: "Web Storage not supported by the browser" };
+};
+
+/** Checks whether the underlying mechanism for this kind of store objects is supported by the browser.
+ * @method DomStore.isSupported
+ * @returns {Boolean} - True if the mechanism is supported by the browser; otherwise false.
+*/
+DomStore.isSupported = function () {
+    return !!window.localStorage;
+};
+
+/** Adds a new value identified by a key to the store.
+ * @method module:store/dom~DomStore#add
+ * @param {String} key - Key string.
+ * @param value - Value that is going to be added to the store.
+ * @param {Function} success - Callback for a successful add operation.
+ * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
+ * This method errors out if the store already contains the specified key.
+ */
+DomStore.prototype.add = function (key, value, success, error) {
+    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);
+};
+
+/** 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.
+ * @summary Adds or updates a value identified by a key to the store.
+ * @method module:store/dom~DomStore#addOrUpdate
+ * @param {String} key - Key string.
+ * @param value - Value that is going to be added or updated to the store.
+ * @param {Function} success - Callback for a successful add or update operation.
+ * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
+ */
+DomStore.prototype.addOrUpdate = function (key, value, success, error) {
+    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;
+        }
+    }
+};
+
+/** In case of an error, this method will not restore any keys that might have been deleted at that point.
+ * @summary Removes all the data associated with this store object.
+ * @method module:store/dom~DomStore#clear
+ * @param {Function} success - Callback for a successful clear operation.
+ * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
+ */
+DomStore.prototype.clear = function (success, error) {
+
+    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);
+    }
+};
+
+/** This function does nothing in DomStore as it does not have a connection model
+ * @method module:store/dom~DomStore#close
+ */
+DomStore.prototype.close = function () {
+};
+
+/** Checks whether a key exists in the store.
+ * @method module:store/dom~DomStore#contains
+ * @param {String} key - Key string.
+ * @param {Function} success - Callback indicating whether the store contains the key or not.
+ * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
+*/
+DomStore.prototype.contains = function (key, success, error) {
+    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;
+
+/** Gets all the keys that exist in the store.
+ * @method module:store/dom~DomStore#getAllKeys
+ * @param {Function} success - Callback for a successful get operation.
+ * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
+ */
+DomStore.prototype.getAllKeys = function (success, error) {
+
+    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);
+    }
+};
+
+/** Identifies the underlying mechanism used by the store.*/
+DomStore.prototype.mechanism = "dom";
+
+/** Reads the value associated to a key in the store.
+ * @method module:store/dom~DomStore#read
+ * @param {String} key - Key string.
+ * @param {Function} success - Callback for a successful reads operation.
+ * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
+ */
+DomStore.prototype.read = function (key, success, error) {
+
+    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);
+        }
+    }
+};
+
+/** Removes a key and its value from the store.
+ * @method module:store/dom~DomStore#remove
+ * @param {String} key - Key string.
+ * @param {Function} success - Callback for a successful remove operation.
+ * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
+ */
+DomStore.prototype.remove = function (key, success, error) {
+    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);
+        }
+    }
+};
+
+/** Updates the value associated to a key in the store.
+ * @method module:store/dom~DomStore#update
+ * @param {String} key - Key string.
+ * @param value - New value.
+ * @param {Function} success - Callback for a successful update operation.
+ * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked
+ * This method errors out if the specified key is not found in the store.
+ */
+DomStore.prototype.update = function (key, value, success, error) {
+    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);
+};
+
+module.exports = DomStore;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/store/indexeddb.js
----------------------------------------------------------------------
diff --git a/lib/store/indexeddb.js b/lib/store/indexeddb.js
new file mode 100644
index 0000000..d7527c1
--- /dev/null
+++ b/lib/store/indexeddb.js
@@ -0,0 +1,447 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+/** @module store/indexeddb */
+var utils = require('./../utils.js');
+
+// Imports.
+var throwErrorCallback = utils.throwErrorCallback;
+var delay = utils.delay;
+
+
+var indexedDB = utils.inBrowser() ? window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.indexedDB : undefined;
+var IDBKeyRange = utils.inBrowser() ? window.IDBKeyRange || window.webkitIDBKeyRange : undefined;
+var IDBTransaction = utils.inBrowser() ? window.IDBTransaction || window.webkitIDBTransaction || {} : {} ;
+
+var IDBT_READ_ONLY = IDBTransaction.READ_ONLY || "readonly";
+var IDBT_READ_WRITE = IDBTransaction.READ_WRITE || "readwrite";
+
+/** Returns either a specific error handler or the default error handler
+ * @param {Function} error - The specific error handler
+ * @param {Function} defaultError - The default error handler
+ * @returns {Function} The error callback
+ */
+function getError(error, defaultError) {
+
+    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 });
+    };
+}
+
+/** Opens the store object's indexed db database.
+ * @param {IndexedDBStore} store - The store object
+ * @param {Function} success - The success callback
+ * @param {Function} error - The error callback
+ */
+function openStoreDb(store, success, error) {
+
+    var storeName = store.name;
+    var dbName = "_odatajs_" + 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);
+    };
+}
+
+/** Opens a new transaction to the store
+ * @param {IndexedDBStore} store - The store object
+ * @param {Integer} mode - The read/write mode of the transaction (constants from IDBTransaction)
+ * @param {Function} success - The success callback
+ * @param {Function} error - The error callback
+ */
+function openTransaction(store, mode, success, error) {
+
+    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);
+}
+
+/** Creates a new IndexedDBStore.
+ * @class IndexedDBStore
+ * @constructor
+ * @param {String} name - The name of the store.
+ * @returns {Object} The new IndexedDBStore.
+ */
+function IndexedDBStore(name) {
+    this.name = name;
+}
+
+/** Creates a new IndexedDBStore.
+ * @method module:store/indexeddb~IndexedDBStore.create
+ * @param {String} name - The name of the store.
+ * @returns {Object} The new IndexedDBStore.
+ */
+IndexedDBStore.create = function (name) {
+    if (IndexedDBStore.isSupported()) {
+        return new IndexedDBStore(name);
+    }
+
+    throw { message: "IndexedDB is not supported on this browser" };
+};
+
+/** Returns whether IndexedDB is supported.
+ * @method module:store/indexeddb~IndexedDBStore.isSupported
+ * @returns {Boolean} True if IndexedDB is supported, false otherwise.
+ */
+IndexedDBStore.isSupported = function () {
+    return !!indexedDB;
+};
+
+/** Adds a key/value pair to the store
+ * @method module:store/indexeddb~IndexedDBStore#add
+ * @param {String} key - The key
+ * @param {Object} value - The value
+ * @param {Function} success - The success callback
+ * @param {Function} error - The error callback
+*/
+IndexedDBStore.prototype.add = function (key, value, success, error) {
+    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);
+};
+
+/** Adds or updates a key/value pair in the store
+ * @method module:store/indexeddb~IndexedDBStore#addOrUpdate
+ * @param {String} key - The key
+ * @param {Object} value - The value
+ * @param {Function} success - The success callback
+ * @param {Function} error - The error callback
+ */
+IndexedDBStore.prototype.addOrUpdate = function (key, value, success, error) {
+    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);
+};
+
+/** Clears the store
+ * @method module:store/indexeddb~IndexedDBStore#clear
+ * @param {Function} success - The success callback
+ * @param {Function} error - The error callback
+ */
+IndexedDBStore.prototype.clear = function (success, error) {
+    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);
+};
+
+/** Closes the connection to the database
+ * @method module:store/indexeddb~IndexedDBStore#close
+*/
+IndexedDBStore.prototype.close = function () {
+    
+    if (this.db) {
+        this.db.close();
+        this.db = null;
+    }
+};
+
+/** Returns whether the store contains a key
+ * @method module:store/indexeddb~IndexedDBStore#contains
+ * @param {String} key - The key
+ * @param {Function} success - The success callback
+ * @param {Function} error - The error callback
+ */
+IndexedDBStore.prototype.contains = function (key, success, error) {
+    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;
+
+/** Gets all the keys from the store
+ * @method module:store/indexeddb~IndexedDBStore#getAllKeys
+ * @param {Function} success - The success callback
+ * @param {Function} error - The error callback
+ */
+IndexedDBStore.prototype.getAllKeys = function (success, error) {
+    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);
+};
+
+/** Identifies the underlying mechanism used by the store.
+*/
+IndexedDBStore.prototype.mechanism = "indexeddb";
+
+/** Reads the value for the specified key
+ * @method module:store/indexeddb~IndexedDBStore#read
+ * @param {String} key - The key
+ * @param {Function} success - The success callback
+ * @param {Function} error - The error callback
+ * If the key does not exist, the success handler will be called with value = undefined
+ */
+IndexedDBStore.prototype.read = function (key, success, error) {
+    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);
+};
+
+/** Removes the specified key from the store
+ * @method module:store/indexeddb~IndexedDBStore#remove
+ * @param {String} key - The key
+ * @param {Function} success - The success callback
+ * @param {Function} error - The error callback
+ */
+IndexedDBStore.prototype.remove = function (key, success, error) {
+
+    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);
+};
+
+/** Updates a key/value pair in the store
+ * @method module:store/indexeddb~IndexedDBStore#update
+ * @param {String} key - The key
+ * @param {Object} value - The value
+ * @param {Function} success - The success callback
+ * @param {Function} error - The error callback
+ */
+IndexedDBStore.prototype.update = function (key, value, success, error) {
+    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);
+};
+
+
+module.exports = IndexedDBStore;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/store/memory.js
----------------------------------------------------------------------
diff --git a/lib/store/memory.js b/lib/store/memory.js
new file mode 100644
index 0000000..a9c69d4
--- /dev/null
+++ b/lib/store/memory.js
@@ -0,0 +1,247 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+/** @module store/memory */
+
+
+var utils = require('./../utils.js');
+
+// Imports.
+var throwErrorCallback = utils.throwErrorCallback;
+var delay = utils.delay;
+
+/** Constructor for store objects that use a sorted array as the underlying mechanism.
+ * @class MemoryStore
+ * @constructor
+ * @param {String} name - Store name.
+ */
+function MemoryStore(name) {
+
+    var holes = [];
+    var items = [];
+    var keys = {};
+
+    this.name = name;
+
+    var getErrorCallback = function (error) {
+        return error || this.defaultError;
+    };
+
+    /** Validates that the specified key is not undefined, not null, and not an array
+     * @param key - Key value.
+     * @param {Function} error - Error callback.
+     * @returns {Boolean} True if the key is valid. False if the key is invalid and the error callback has been queued for execution.
+     */
+    function validateKeyInput(key, error) {
+
+        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 method errors out if the store already contains the specified key.
+     * @summary Adds a new value identified by a key to the store.
+     * @method module:store/memory~MemoryStore#add
+     * @param {String} key - Key string.
+     * @param value - Value that is going to be added to the store.
+     * @param {Function} success - Callback for a successful add operation.
+     * @param {Function} error - Callback for handling errors. If not specified then store.defaultError is invoked.
+     */
+    this.add = function (key, value, success, error) {
+        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 method will overwrite the key's current value if it already exists in the store; otherwise it simply adds the new key and value.
+     * @summary Adds or updates a value identified by a key to the store.
+     * @method module:store/memory~MemoryStore#addOrUpdate
+     * @param {String} key - Key string.
+     * @param value - Value that is going to be added or updated to the store.
+     * @param {Function} success - Callback for a successful add or update operation.
+     * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
+    */
+    this.addOrUpdate = function (key, value, success, error) {
+        
+        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);
+        }
+    };
+
+    /** Removes all the data associated with this store object.
+     * @method module:store/memory~MemoryStore#clear
+     * @param {Function} success - Callback for a successful clear operation.
+     */
+    this.clear = function (success) {
+        items = [];
+        keys = {};
+        holes = [];
+        delay(success);
+    };
+
+    /** Checks whether a key exists in the store.
+     * @method module:store/memory~MemoryStore#contains
+     * @param {String} key - Key string.
+     * @param {Function} success - Callback indicating whether the store contains the key or not.
+     */
+    this.contains = function (key, success) {
+        var contained = keys.hasOwnProperty(key);
+        delay(success, contained);
+    };
+
+    /** Gets all the keys that exist in the store.
+     * @method module:store/memory~MemoryStore#getAllKeys
+     * @param {Function} success - Callback for a successful get operation.
+     */
+    this.getAllKeys = function (success) {
+
+        var results = [];
+        for (var name in keys) {
+            results.push(name);
+        }
+        delay(success, results);
+    };
+
+    /** Reads the value associated to a key in the store.
+     * @method module:store/memory~MemoryStore#read
+     * @param {String} key - Key string.
+     * @param {Function} success - Callback for a successful reads operation.
+     * @param {Function} error - Callback for handling errors. If not specified then store.defaultError is invoked.
+     */
+    this.read = function (key, success, error) {
+        error = getErrorCallback(error);
+
+        if (validateKeyInput(key, error)) {
+            var index = keys[key];
+            delay(success, key, items[index]);
+        }
+    };
+
+    /** Removes a key and its value from the store.
+     * @method module:store/memory~MemoryStore#remove
+     * @param {String} key - Key string.
+     * @param {Function} success - Callback for a successful remove operation.
+     * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
+     */
+    this.remove = function (key, success, error) {
+        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);
+        }
+    };
+
+    /** Updates the value associated to a key in the store.
+     * @method module:store/memory~MemoryStore#update
+     * @param {String} key - Key string.
+     * @param value - New value.
+     * @param {Function} success - Callback for a successful update operation.
+     * @param {Function} [error] - Callback for handling errors. If not specified then store.defaultError is invoked.
+     * This method errors out if the specified key is not found in the store.
+     */
+    this.update = function (key, value, success, error) {
+        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 });
+            }
+        }
+    };
+}
+
+/** Creates a store object that uses memory storage as its underlying mechanism.
+ * @method MemoryStore.create
+ * @param {String} name - Store name.
+ * @returns {Object} Store object.
+ */
+MemoryStore.create = function (name) {
+    return new MemoryStore(name);
+};
+
+/** Checks whether the underlying mechanism for this kind of store objects is supported by the browser.
+ * @method MemoryStore.isSupported
+ * @returns {Boolean} True if the mechanism is supported by the browser; otherwise false.
+ */
+MemoryStore.isSupported = function () {
+    return true;
+};
+
+/** This function does nothing in MemoryStore as it does not have a connection model.
+*/
+MemoryStore.prototype.close = function () {
+};
+
+MemoryStore.prototype.defaultError = throwErrorCallback;
+
+/** Identifies the underlying mechanism used by the store.
+*/
+MemoryStore.prototype.mechanism = "memory";
+
+
+/** MemoryStore (see {@link MemoryStore}) */
+module.exports = MemoryStore;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/utils.js
----------------------------------------------------------------------
diff --git a/lib/utils.js b/lib/utils.js
new file mode 100644
index 0000000..429a56a
--- /dev/null
+++ b/lib/utils.js
@@ -0,0 +1,581 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+/** @module odatajs/utils */
+
+
+function inBrowser() {
+    return typeof window !== 'undefined';
+}
+
+/** Creates a new ActiveXObject from the given progId.
+ * @param {String} progId - ProgId string of the desired ActiveXObject.
+ * @returns {Object} The ActiveXObject instance. Null if ActiveX is not supported by the browser.
+ * This function throws whatever exception might occur during the creation
+ * of the ActiveXObject.
+*/
+var activeXObject = function (progId) {
+    
+    if (window.ActiveXObject) {
+        return new window.ActiveXObject(progId);
+    }
+    return null;
+};
+
+/** Checks whether the specified value is different from null and undefined.
+ * @param [value] Value to check ( may be null)
+ * @returns {Boolean} true if the value is assigned; false otherwise.
+*/     
+function assigned(value) {
+    return value !== null && value !== undefined;
+}
+
+/** Checks whether the specified item is in the array.
+ * @param {Array} [arr] Array to check in.
+ * @param item - Item to look for.
+ * @returns {Boolean} true if the item is contained, false otherwise.
+*/
+function contains(arr, item) {
+    var i, len;
+    for (i = 0, len = arr.length; i < len; i++) {
+        if (arr[i] === item) {
+            return true;
+        }
+    }
+    return false;
+}
+
+/** Given two values, picks the first one that is not undefined.
+ * @param a - First value.
+ * @param b - Second value.
+ * @returns a if it's a defined value; else b.
+ */
+function defined(a, b) {
+    return (a !== undefined) ? a : b;
+}
+
+/** Delays the invocation of the specified function until execution unwinds.
+ * @param {Function} callback - Callback function.
+ */
+function delay(callback) {
+
+    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);
+}
+
+/** Throws an exception in case that a condition evaluates to false.
+ * @param {Boolean} condition - Condition to evaluate.
+ * @param {String} message - Message explaining the assertion.
+ * @param {Object} data - Additional data to be included in the exception.
+ */
+function djsassert(condition, message, data) {
+
+
+    if (!condition) {
+        throw { message: "Assert fired: " + message, data: data };
+    }
+}
+
+/** Extends the target with the specified values.
+ * @param {Object} target - Object to add properties to.
+ * @param {Object} values - Object with properties to add into target.
+ * @returns {Object} The target object.
+*/
+function extend(target, values) {
+    for (var name in values) {
+        target[name] = values[name];
+    }
+
+    return target;
+}
+
+function find(arr, callback) {
+    /** Returns the first item in the array that makes the callback function true.
+     * @param {Array} [arr] Array to check in. ( may be null)
+     * @param {Function} callback - Callback function to invoke once per item in the array.
+     * @returns The first item that makes the callback return true; null otherwise or if the array is null.
+    */
+
+    if (arr) {
+        var i, len;
+        for (i = 0, len = arr.length; i < len; i++) {
+            if (callback(arr[i])) {
+                return arr[i];
+            }
+        }
+    }
+    return null;
+}
+
+function isArray(value) {
+    /** Checks whether the specified value is an array object.
+     * @param value - Value to check.
+     * @returns {Boolean} true if the value is an array object; false otherwise.
+     */
+
+    return Object.prototype.toString.call(value) === "[object Array]";
+}
+
+/** Checks whether the specified value is a Date object.
+ * @param value - Value to check.
+ * @returns {Boolean} true if the value is a Date object; false otherwise.
+ */
+function isDate(value) {
+    return Object.prototype.toString.call(value) === "[object Date]";
+}
+
+/** Tests whether a value is an object.
+ * @param value - Value to test.
+ * @returns {Boolean} True is the value is an object; false otherwise.
+ * Per javascript rules, null and array values are objects and will cause this function to return true.
+ */
+function isObject(value) {
+    return typeof value === "object";
+}
+
+/** Parses a value in base 10.
+ * @param {String} value - String value to parse.
+ * @returns {Number} The parsed value, NaN if not a valid value.
+*/   
+function parseInt10(value) {
+    return parseInt(value, 10);
+}
+
+/** Renames a property in an object.
+ * @param {Object} obj - Object in which the property will be renamed.
+ * @param {String} oldName - Name of the property that will be renamed.
+ * @param {String} newName - New name of the property.
+ * This function will not do anything if the object doesn't own a property with the specified old name.
+ */
+function renameProperty(obj, oldName, newName) {
+    if (obj.hasOwnProperty(oldName)) {
+        obj[newName] = obj[oldName];
+        delete obj[oldName];
+    }
+}
+
+/** Default error handler.
+ * @param {Object} error - Error to handle.
+ */
+function throwErrorCallback(error) {
+    throw error;
+}
+
+/** Removes leading and trailing whitespaces from a string.
+ * @param {String} str String to trim
+ * @returns {String} The string with no leading or trailing whitespace.
+ */
+function trimString(str) {
+    if (str.trim) {
+        return str.trim();
+    }
+
+    return str.replace(/^\s+|\s+$/g, '');
+}
+
+/** Returns a default value in place of undefined.
+ * @param [value] Value to check (may be null)
+ * @param defaultValue - Value to return if value is undefined.
+ * @returns value if it's defined; defaultValue otherwise.
+ * This should only be used for cases where falsy values are valid;
+ * otherwise the pattern should be 'x = (value) ? value : defaultValue;'.
+ */
+function undefinedDefault(value, defaultValue) {
+    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"];
+
+/** Gets information about the components of the specified URI.
+ * @param {String} uri - URI to get information from.
+ * @return  {Object} An object with an isAbsolute flag and part names (scheme, authority, etc.) if available.
+ */
+function getURIInfo(uri) {
+    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;
+}
+
+/** Builds a URI string from its components.
+ * @param {Object} uriInfo -  An object with uri parts (scheme, authority, etc.).
+ * @returns {String} URI string.
+ */
+function getURIFromInfo(uriInfo) {
+    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;
+
+/** Normalizes the casing of a URI.
+ * @param {String} uri - URI to normalize, absolute or relative.
+ * @returns {String} The URI normalized to lower case.
+*/
+function normalizeURICase(uri) {
+    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();
+    });
+}
+
+/** Normalizes a possibly relative URI with a base URI.
+ * @param {String} uri - URI to normalize, absolute or relative
+ * @param {String} base - Base URI to compose with (may be null)
+ * @returns {String} The composed URI if relative; the original one if absolute.
+ */
+function normalizeURI(uri, base) {
+    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);
+}
+
+/** Merges the path of a relative URI and a base URI.
+ * @param {String} uriPath - Relative URI path.
+ * @param {String} basePath - Base URI path.
+ * @returns {String} A string with the merged path.
+ */
+function mergeUriPathWithBase(uriPath, basePath) {
+    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;
+}
+
+/** Removes the special folders . and .. from a URI's path.
+ * @param {string} path - URI path component.
+ * @returns {String} Path without any . and .. folders.
+ */
+function removeDotsFromPath(path) {
+    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;
+}
+
+function convertByteArrayToHexString(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;
+}
+
+function decodeBase64(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;
+}
+
+function getBase64IndexValue(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;
+    }
+}
+
+function addBase64Padding(binaryString) {
+    while (binaryString.length < 6) {
+        binaryString = "0" + binaryString;
+    }
+    return binaryString;
+
+}
+
+function getJsonValueArraryLength(data) {
+    if (data && data.value) {
+        return data.value.length;
+    }
+
+    return 0;
+}
+
+function sliceJsonValueArray(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;
+}
+
+function concatJsonValueArray(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;
+}
+
+function endsWith(input, search) {
+    return input.indexOf(search, input.length - search.length) !== -1;
+}
+
+function startsWith (input, search) {
+    return input.indexOf(search) === 0;
+}
+
+function getFormatKind(format, defaultFormatKind) {
+    var formatKind = defaultFormatKind;
+    if (!assigned(format)) {
+        return formatKind;
+    }
+
+    var normalizedFormat = format.toLowerCase();
+    switch (normalizedFormat) {
+        case "none":
+            formatKind = 0;
+            break;
+        case "minimal":
+            formatKind = 1;
+            break;
+        case "full":
+            formatKind = 2;
+            break;
+        default:
+            break;
+    }
+
+    return formatKind;
+}
+
+
+    
+    
+exports.inBrowser = inBrowser;
+exports.activeXObject = activeXObject;
+exports.assigned = assigned;
+exports.contains = contains;
+exports.defined = defined;
+exports.delay = delay;
+exports.djsassert = djsassert;
+exports.extend = extend;
+exports.find = find;
+exports.getURIInfo = getURIInfo;
+exports.isArray = isArray;
+exports.isDate = isDate;
+exports.isObject = isObject;
+exports.normalizeURI = normalizeURI;
+exports.normalizeURICase = normalizeURICase;
+exports.parseInt10 = parseInt10;
+exports.renameProperty = renameProperty;
+exports.throwErrorCallback = throwErrorCallback;
+exports.trimString = trimString;
+exports.undefinedDefault = undefinedDefault;
+exports.decodeBase64 = decodeBase64;
+exports.convertByteArrayToHexString = convertByteArrayToHexString;
+exports.getJsonValueArraryLength = getJsonValueArraryLength;
+exports.sliceJsonValueArray = sliceJsonValueArray;
+exports.concatJsonValueArray = concatJsonValueArray;
+exports.startsWith = startsWith;
+exports.endsWith = endsWith;
+exports.getFormatKind = getFormatKind;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/xml.js
----------------------------------------------------------------------
diff --git a/lib/xml.js b/lib/xml.js
new file mode 100644
index 0000000..194b4ba
--- /dev/null
+++ b/lib/xml.js
@@ -0,0 +1,824 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+ 
+
+/** @module odatajs/xml */
+
+var utils    = require('./utils.js');
+
+var activeXObject = utils.activeXObject;
+var djsassert = utils.djsassert;
+var extend = utils.extend;
+var isArray = utils.isArray;
+var normalizeURI = utils.normalizeURI;
+
+// 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";
+
+/** Checks whether the specified string has leading or trailing spaces.
+ * @param {String} text - String to check.
+ * @returns {Boolean} true if text has any leading or trailing whitespace; false otherwise.
+ */
+function hasLeadingOrTrailingWhitespace(text) {
+    var re = /(^\s)|(\s$)/;
+    return re.test(text);
+}
+
+/** Determines whether the specified text is empty or whitespace.
+ * @param {String} text - Value to inspect.
+ * @returns {Boolean} true if the text value is empty or all whitespace; false otherwise.
+ */
+function isWhitespace(text) {
+
+
+    var ws = /^\s*$/;
+    return text === null || ws.test(text);
+}
+
+/** Determines whether the specified element has xml:space='preserve' applied.
+ * @param domElement - Element to inspect.
+ * @returns {Boolean} Whether xml:space='preserve' is in effect.
+ */
+function isWhitespacePreserveContext(domElement) {
+
+
+    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;
+}
+
+/** Determines whether the attribute is a XML namespace declaration.
+ * @param domAttribute - Element to inspect.
+ * @return {Boolean} True if the attribute is a namespace declaration (its name is 'xmlns' or starts with 'xmlns:'; false otherwise.
+ */
+function isXmlNSDeclaration(domAttribute) {
+    var nodeName = domAttribute.nodeName;
+    return nodeName == "xmlns" || nodeName.indexOf("xmlns:") === 0;
+}
+
+/** Safely set as property in an object by invoking obj.setProperty.
+ * @param obj - Object that exposes a setProperty method.
+ * @param {String} name - Property name
+ * @param value - Property value.
+ */
+function safeSetProperty(obj, name, value) {
+
+
+    try {
+        obj.setProperty(name, value);
+    } catch (_) { }
+}
+
+/** Creates an configures new MSXML 3.0 ActiveX object.
+ * @returns {Object} New MSXML 3.0 ActiveX object.
+ * This function throws any exception that occurs during the creation
+ * of the MSXML 3.0 ActiveX object.
+ */
+function msXmlDom3() {
+    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;
+}
+
+/** Creates an configures new MSXML 6.0 or MSXML 3.0 ActiveX object.
+ * @returns {Object} New MSXML 3.0 ActiveX object.
+ * 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.
+ */
+function msXmlDom() {
+    try {
+        var msxml = activeXObject("Msxml2.DOMDocument.6.0");
+        if (msxml) {
+            msxml.async = true;
+        }
+        return msxml;
+    } catch (_) {
+        return msXmlDom3();
+    }
+}
+
+/** Parses an XML string using the MSXML DOM.
+ * @returns {Object} New MSXML DOMDocument node representing the parsed XML string.
+ * 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.
+ */
+function msXmlParse(text) {
+    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;
+}
+
+/** Throws a new exception containing XML parsing error information.
+ * @param exceptionOrReason - String indicating the reason of the parsing failure or Object detailing the parsing error.
+ * @param {String} srcText -     String indicating the part of the XML string that caused the parsing error.
+ * @param {String} errorXmlText - XML string for wich the parsing failed.
+ */
+function xmlThrowParserError(exceptionOrReason, srcText, errorXmlText) {
+
+    if (typeof exceptionOrReason === "string") {
+        exceptionOrReason = { message: exceptionOrReason };
+    }
+    throw extend(exceptionOrReason, { srcText: srcText || "", errorXmlText: errorXmlText || "" });
+}
+
+/** Returns an XML DOM document from the specified text.
+ * @param {String} text - Document text.
+ * @returns XML DOM document.
+ * This function will throw an exception in case of a parse error
+ */
+function xmlParse(text) {
+    var domParser = undefined;
+    if (utils.inBrowser()) {
+        domParser = window.DOMParser && new window.DOMParser();
+    } else {
+        domParser = new (require('xmldom').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;
+}
+
+/** Builds a XML qualified name string in the form of "prefix:name".
+ * @param {String} prefix - Prefix string (may be null)
+ * @param {String} name - Name string to qualify with the prefix.
+ * @returns {String} Qualified name.
+ */
+function xmlQualifiedName(prefix, name) {
+    return prefix ? prefix + ":" + name : name;
+}
+
+/** Appends a text node into the specified DOM element node.
+ * @param domNode - DOM node for the element.
+ * @param {String} textNode - Text to append as a child of element.
+*/
+function xmlAppendText(domNode, textNode) {
+    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;
+}
+
+/** Iterates through the XML element's attributes and invokes the callback function for each one.
+ * @param element - Wrapped element to iterate over.
+ * @param {Function} onAttributeCallback - Callback function to invoke with wrapped attribute nodes.
+*/
+function xmlAttributes(element, onAttributeCallback) {
+    var attributes = element.attributes;
+    var i, len;
+    for (i = 0, len = attributes.length; i < len; i++) {
+        onAttributeCallback(attributes.item(i));
+    }
+}
+
+/** Returns the value of a DOM element's attribute.
+ * @param domNode - DOM node for the owning element.
+ * @param {String} localName - Local name of the attribute.
+ * @param {String} nsURI - Namespace URI of the attribute.
+ * @returns {String} - The attribute value, null if not found (may be null)
+ */
+function xmlAttributeValue(domNode, localName, nsURI) {
+
+    var attribute = xmlAttributeNode(domNode, localName, nsURI);
+    return attribute ? xmlNodeValue(attribute) : null;
+}
+
+/** Gets an attribute node from a DOM element.
+ * @param domNode - DOM node for the owning element.
+ * @param {String} localName - Local name of the attribute.
+ * @param {String} nsURI - Namespace URI of the attribute.
+ * @returns The attribute node, null if not found.
+ */
+function xmlAttributeNode(domNode, localName, nsURI) {
+
+    var attributes = domNode.attributes;
+    if (attributes.getNamedItemNS) {
+        return attributes.getNamedItemNS(nsURI || null, localName);
+    }
+
+    return attributes.getQualifiedItem(localName, nsURI) || null;
+}
+
+/** Gets the value of the xml:base attribute on the specified element.
+ * @param domNode - Element to get xml:base attribute value from.
+ * @param [baseURI] - Base URI used to normalize the value of the xml:base attribute ( may be null)
+ * @returns {String} Value of the xml:base attribute if found; the baseURI or null otherwise.
+ */
+function xmlBaseURI(domNode, baseURI) {
+
+    var base = xmlAttributeNode(domNode, "base", xmlNS);
+    return (base ? normalizeURI(base.value, baseURI) : baseURI) || null;
+}
+
+
+/** Iterates through the XML element's child DOM elements and invokes the callback function for each one.
+ * @param domNode - DOM Node containing the DOM elements to iterate over.
+ * @param {Function} onElementCallback - Callback function to invoke for each child DOM element.
+*/
+function xmlChildElements(domNode, onElementCallback) {
+
+    xmlTraverse(domNode, /*recursive*/false, function (child) {
+        if (child.nodeType === 1) {
+            onElementCallback(child);
+        }
+        // continue traversing.
+        return true;
+    });
+}
+
+/** Gets the descendant element under root that corresponds to the specified path and namespace URI.
+ * @param root - DOM element node from which to get the descendant element.
+ * @param {String} namespaceURI - The namespace URI of the element to match.
+ * @param {String} path - Path to the desired descendant element.
+ * @return The element specified by path and namespace URI.
+ * 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.
+ */
+function xmlFindElementByPath(root, namespaceURI, path) {
+    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;
+}
+
+/** Gets the DOM element or DOM attribute node under root that corresponds to the specified path and namespace URI.
+ * @param root - DOM element node from which to get the descendant node.
+ * @param {String} namespaceURI - The namespace URI of the node to match.
+ * @param {String} path - Path to the desired descendant node.
+ * @return The node specified by path and namespace URI.
+
+* 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.
+*/
+function xmlFindNodeByPath(root, namespaceURI, path) {
+    
+
+    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;
+}
+
+/** Returns the first child DOM element under the specified DOM node that matches the specified namespace URI and local name.
+ * @param domNode - DOM node from which the child DOM element is going to be retrieved.
+ * @param {String} [namespaceURI] - 
+ * @param {String} [localName] - 
+ * @return The node's first child DOM element that matches the specified namespace URI and local name; null otherwise.
+ */
+function xmlFirstChildElement(domNode, namespaceURI, localName) {
+
+    return xmlFirstElementMaybeRecursive(domNode, namespaceURI, localName, /*recursive*/false);
+}
+
+/** Returns the first descendant DOM element under the specified DOM node that matches the specified namespace URI and local name.
+ * @param domNode - DOM node from which the descendant DOM element is going to be retrieved.
+ * @param {String} [namespaceURI] - 
+ * @param {String} [localName] - 
+ * @return The node's first descendant DOM element that matches the specified namespace URI and local name; null otherwise.
+*/
+function xmlFirstDescendantElement(domNode, namespaceURI, localName) {
+    if (domNode.getElementsByTagNameNS) {
+        var result = domNode.getElementsByTagNameNS(namespaceURI, localName);
+        return result.length > 0 ? result[0] : null;
+    }
+    return xmlFirstElementMaybeRecursive(domNode, namespaceURI, localName, /*recursive*/true);
+}
+
+/** Returns the first descendant DOM element under the specified DOM node that matches the specified namespace URI and local name.
+ * @param domNode - DOM node from which the descendant DOM element is going to be retrieved.
+ * @param {String} [namespaceURI] - 
+ * @param {String} [localName] - 
+ * @param {Boolean} recursive 
+ * - 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.
+ * @return The node's first descendant DOM element that matches the specified namespace URI and local name; null otherwise.
+ */
+function xmlFirstElementMaybeRecursive(domNode, namespaceURI, localName, recursive) {
+
+    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;
+}
+
+/** Gets the concatenated value of all immediate child text and CDATA nodes for the specified element.
+ * @param xmlElement - Element to get values for.
+ * @returns {String} Text for all direct children.
+ */
+function xmlInnerText(xmlElement) {
+
+    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;
+}
+
+/** Returns the localName of a XML node.
+ * @param domNode - DOM node to get the value from.
+ * @returns {String} localName of domNode.
+ */
+function xmlLocalName(domNode) {
+
+    return domNode.localName || domNode.baseName;
+}
+
+/** Returns the namespace URI of a XML node.
+ * @param domNode - DOM node to get the value from.
+ * @returns {String} Namespace URI of domNode.
+ */
+function xmlNamespaceURI(domNode) {
+
+    return domNode.namespaceURI || null;
+}
+
+/** Returns the value or the inner text of a XML node.
+ * @param domNode - DOM node to get the value from.
+ * @return Value of the domNode or the inner text if domNode represents a DOM element node.
+ */
+function xmlNodeValue(domNode) {
+    
+    if (domNode.nodeType === 1) {
+        return xmlInnerText(domNode);
+    }
+    return domNode.nodeValue;
+}
+
+/** Walks through the descendants of the domNode and invokes a callback for each node.
+ * @param domNode - DOM node whose descendants are going to be traversed.
+ * @param {Boolean} recursive
+ * - 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 {Boolean} onChildCallback - Called for each child
+ * @returns {String} Namespace URI of node.
+ */
+function xmlTraverse(domNode, recursive, onChildCallback) {
+
+    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();
+        }
+    }
+}
+
+/** Returns the next sibling DOM element of the specified DOM node.
+ * @param domNode - DOM node from which the next sibling is going to be retrieved.
+ * @param {String} [namespaceURI] - 
+ * @param {String} [localName] - 
+ * @return The node's next sibling DOM element, null if there is none.
+ */
+function xmlSiblingElement(domNode, namespaceURI, localName) {
+
+    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;
+}
+
+/** Creates a new empty DOM document node.
+ * @return New DOM document node.
+ *
+ * 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.
+ */
+function xmlDom() {
+    var implementation = window.document.implementation;
+    return (implementation && implementation.createDocument) ?
+       implementation.createDocument(null, null, null) :
+       msXmlDom();
+}
+
+/** Appends a collection of child nodes or string values to a parent DOM node.
+ * @param parent - DOM node to which the children will be appended.
+ * @param {Array} children - Array containing DOM nodes or string values that will be appended to the parent.
+ * @return The parent with the appended children or string values.
+ *  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.
+ */
+function xmlAppendChildren(parent, children) {
+    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;
+}
+
+/** Appends a child node or a string value to a parent DOM node.
+ * @param parent - DOM node to which the child will be appended.
+ * @param child - Child DOM node or string value to append to the parent.
+ * @return The parent with the appended child or string value.
+ * 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.
+ */
+function xmlAppendChild(parent, child) {
+
+    djsassert(parent !== child, "xmlAppendChild() - parent and child are one and the same!");
+    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;
+}
+
+/** Creates a new DOM attribute node.
+ * @param dom - DOM document used to create the attribute.
+ * @param {String} namespaceURI - Namespace URI.
+ * @param {String} qualifiedName - Qualified OData name
+ * @param {String} value - Value of the new attribute
+ * @return DOM attribute node for the namespace declaration.
+ */
+function xmlNewAttribute(dom, namespaceURI, qualifiedName, value) {
+
+    var attribute =
+        dom.createAttributeNS && dom.createAttributeNS(namespaceURI, qualifiedName) ||
+        dom.createNode(2, qualifiedName, namespaceURI || undefined);
+
+    attribute.value = value || "";
+    return attribute;
+}
+
+/** Creates a new DOM element node.
+ * @param dom - DOM document used to create the DOM element.
+ * @param {String} namespaceURI - Namespace URI of the new DOM element.
+ * @param {String} qualifiedName - Qualified name in the form of "prefix:name" of the new DOM element.
+ * @param {Array} [children] Collection of child DOM nodes or string values that are going to be appended to the new DOM element.
+ * @return New DOM element.
+ * 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.
+ */
+function xmlNewElement(dom, namespaceURI, qualifiedName, children) {
+    var element =
+        dom.createElementNS && dom.createElementNS(nampespaceURI, qualifiedName) ||
+        dom.createNode(1, qualifiedName, nampespaceURI || undefined);
+
+    return xmlAppendChildren(element, children || []);
+}
+
+/** Creates a namespace declaration attribute.
+ * @param dom - DOM document used to create the attribute.
+ * @param {String} namespaceURI - Namespace URI.
+ * @param {String} prefix - Namespace prefix.
+ * @return DOM attribute node for the namespace declaration.
+ */
+function xmlNewNSDeclaration(dom, namespaceURI, prefix) {
+    return xmlNewAttribute(dom, xmlnsNS, xmlQualifiedName("xmlns", prefix), namespaceURI);
+}
+
+/** Creates a new DOM document fragment node for the specified xml text.
+ * @param dom - DOM document from which the fragment node is going to be created.
+ * @param {String} text XML text to be represented by the XmlFragment.
+ * @return New DOM document fragment object.
+ */
+function xmlNewFragment(dom, text) {
+
+    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;
+}
+
+/** Creates new DOM text node.
+ * @param dom - DOM document used to create the text node.
+ * @param {String} text - Text value for the DOM text node.
+ * @return DOM text node.
+ */ 
+function xmlNewText(dom, text) {
+    return dom.createTextNode(text);
+}
+
+/** Creates a new DOM element or DOM attribute node as specified by path and appends it to the DOM tree pointed by root.
+ * @param dom - DOM document used to create the new node.
+ * @param root - DOM element node used as root of the subtree on which the new nodes are going to be created.
+ * @param {String} namespaceURI - Namespace URI of the new DOM element or attribute.
+ * @param {String} prefix - Prefix used to qualify the name of the new DOM element or attribute.
+ * @param {String} path - Path string describing the location of the new DOM element or attribute from the root element.
+ * @return DOM element or attribute node for the last segment of the path.
+
+ * 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.
+ */
+function xmlNewNodeByPath(dom, root, namespaceURI, prefix, path) {
+    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;
+}
+
+/** Returns the text representation of the document to which the specified node belongs.
+ * @param domNode - Wrapped element in the document to serialize.
+ * @returns {String} Serialized document.
+*/
+function xmlSerialize(domNode) {
+    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" };
+}
+
+/** Returns the XML representation of the all the descendants of the node.
+ * @param domNode - Node to serialize.
+ * @returns {String} The XML representation of all the descendants of the node.
+ */
+function xmlSerializeDescendants(domNode) {
+    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;
+}
+
+/** Returns the XML representation of the node and all its descendants.
+ * @param domNode - Node to serialize
+ * @returns {String} The XML representation of the node and all its descendants.
+ */
+function xmlSerializeNode(domNode) {
+
+    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" };
+}
+
+exports.http = http;
+exports.w3org = w3org;
+exports.xmlNS = xmlNS;
+exports.xmlnsNS = xmlnsNS;
+
+exports.hasLeadingOrTrailingWhitespace = hasLeadingOrTrailingWhitespace;
+exports.isXmlNSDeclaration = isXmlNSDeclaration;
+exports.xmlAppendChild = xmlAppendChild;
+exports.xmlAppendChildren = xmlAppendChildren;
+exports.xmlAttributeNode = xmlAttributeNode;
+exports.xmlAttributes = xmlAttributes;
+exports.xmlAttributeValue = xmlAttributeValue;
+exports.xmlBaseURI = xmlBaseURI;
+exports.xmlChildElements = xmlChildElements;
+exports.xmlFindElementByPath = xmlFindElementByPath;
+exports.xmlFindNodeByPath = xmlFindNodeByPath;
+exports.xmlFirstChildElement = xmlFirstChildElement;
+exports.xmlFirstDescendantElement = xmlFirstDescendantElement;
+exports.xmlInnerText = xmlInnerText;
+exports.xmlLocalName = xmlLocalName;
+exports.xmlNamespaceURI = xmlNamespaceURI;
+exports.xmlNodeValue = xmlNodeValue;
+exports.xmlDom = xmlDom;
+exports.xmlNewAttribute = xmlNewAttribute;
+exports.xmlNewElement = xmlNewElement;
+exports.xmlNewFragment = xmlNewFragment;
+exports.xmlNewNodeByPath = xmlNewNodeByPath;
+exports.xmlNewNSDeclaration = xmlNewNSDeclaration;
+exports.xmlNewText = xmlNewText;
+exports.xmlParse = xmlParse;
+exports.xmlQualifiedName = xmlQualifiedName;
+exports.xmlSerialize = xmlSerialize;
+exports.xmlSerializeDescendants = xmlSerializeDescendants;
+exports.xmlSiblingElement = xmlSiblingElement;

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index e48ba0a..044cb81 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "odatajs",
   "version": "4.0.0",
-  "postfix": "beta-01",
+  "postfix": "",
   "releaseCandidate": "",
   "title": "Olingo OData Client for JavaScript",
   "description": "the Olingo OData Client for JavaScript library is a new cross-browser JavaScript library that enables data-centric web applications by leveraging modern protocols such as JSON and OData and HTML5-enabled browser features. It's designed to be small, fast and easy to use.",


[6/8] olingo-odata4-js git commit: [OLINGO-442] Cleanup bevore release II and beta-name removal

Posted by ko...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/odata/metadata.js
----------------------------------------------------------------------
diff --git a/lib/odata/metadata.js b/lib/odata/metadata.js
new file mode 100644
index 0000000..9fdcdfd
--- /dev/null
+++ b/lib/odata/metadata.js
@@ -0,0 +1,523 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+/** @module odata/metadata */
+
+var utils    = require('./../utils.js');
+var oDSxml    = require('./../xml.js');
+var odataHandler    = require('./handler.js');
+
+
+
+// imports 
+var contains = utils.contains;
+var normalizeURI = utils.normalizeURI;
+var xmlAttributes = oDSxml.xmlAttributes;
+var xmlChildElements = oDSxml.xmlChildElements;
+var xmlFirstChildElement = oDSxml.xmlFirstChildElement;
+var xmlInnerText = oDSxml.xmlInnerText;
+var xmlLocalName = oDSxml.xmlLocalName;
+var xmlNamespaceURI = oDSxml.xmlNamespaceURI;
+var xmlNS = oDSxml.xmlNS;
+var xmlnsNS = oDSxml.xmlnsNS;
+var xmlParse = oDSxml.xmlParse;
+
+var ado = oDSxml.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 odataMetaXmlNs = adoDs + "/metadata";           // http://docs.oasis-open.org/odata/ns/metadata
+var MAX_DATA_SERVICE_VERSION = odataHandler.MAX_DATA_SERVICE_VERSION;
+
+var xmlMediaType = "application/xml";
+
+/** Creates an object that describes an element in an schema.
+ * @param {Array} attributes - List containing the names of the attributes allowed for this element.
+ * @param {Array} elements - List containing the names of the child elements allowed for this element.
+ * @param {Boolean} text - Flag indicating if the element's text value is of interest or not.
+ * @param {String} ns - Namespace to which the element belongs to.
+ * If a child element name ends with * then it is understood by the schema that that child element can appear 0 or more times.
+ * @returns {Object} Object with attributes, elements, text, and ns fields.
+ */
+function schemaElement(attributes, elements, text, ns) {
+
+    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"]
+        )
+    }
+};
+
+
+/** Converts a Pascal-case identifier into a camel-case identifier.
+ * @param {String} text - Text to convert.
+ * @returns {String} Converted text.
+ * If the text starts with multiple uppercase characters, it is left as-is.
+ */
+function scriptCase(text) {
+
+    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();
+}
+
+/** Gets the schema node for the specified element.
+ * @param {Object} parentSchema - Schema of the parent XML node of 'element'.
+ * @param candidateName - XML element name to consider.
+ * @returns {Object} The schema that describes the specified element; null if not found.
+ */
+function getChildSchema(parentSchema, candidateName) {
+
+    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;
+}
+
+/** Checks whether the specifies namespace URI is one of the known CSDL namespace URIs.
+ * @param {String} nsURI - Namespace URI to check.
+ * @returns {Boolean} true if nsURI is a known CSDL namespace; false otherwise.
+ */
+function isEdmNamespace(nsURI) {
+
+    return nsURI === edmNs1;
+}
+
+/** Parses a CSDL document.
+ * @param element - DOM element to parse.
+ * @returns {Object} An object describing the parsed element.
+ */
+function parseConceptualModelElement(element) {
+
+    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;
+        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;
+}
+
+/** Parses a metadata document.
+ * @param handler - This handler.
+ * @param {String} text - Metadata text.
+ * @returns An object representation of the conceptual model.
+ */
+function metadataParser(handler, text) {
+
+    var doc = xmlParse(text);
+    var root = xmlFirstChildElement(doc);
+    return parseConceptualModelElement(root) || undefined;
+}
+
+
+
+exports.metadataHandler = odataHandler.handler(metadataParser, null, xmlMediaType, MAX_DATA_SERVICE_VERSION);
+
+exports.schema = schema;
+exports.scriptCase = scriptCase;
+exports.getChildSchema = getChildSchema;
+exports.parseConceptualModelElement = parseConceptualModelElement;
+exports.metadataParser = metadataParser;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/odata/net-browser.js
----------------------------------------------------------------------
diff --git a/lib/odata/net-browser.js b/lib/odata/net-browser.js
new file mode 100644
index 0000000..8d956ff
--- /dev/null
+++ b/lib/odata/net-browser.js
@@ -0,0 +1,344 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/** @module odata/net */
+/*for browser*/
+
+
+var utils    = require('./../utils.js');
+// Imports.
+
+var defined = utils.defined;
+var delay = utils.delay;
+
+var ticks = 0;
+
+/* Checks whether the specified request can be satisfied with a JSONP request.
+ * @param request - Request object to check.
+ * @returns {Boolean} true if the request can be satisfied; false otherwise.
+
+ * 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.
+ */
+function canUseJSONP(request) {
+    
+    return !(request.method && request.method !== "GET");
+
+
+}
+
+/** Creates an IFRAME tag for loading the JSONP script
+ * @param {String} url - The source URL of the script
+ * @returns {HTMLElement} The IFRAME tag
+ */
+function createIFrame(url) {
+    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;
+}
+
+/** Creates a XmlHttpRequest object.
+ * @returns {XmlHttpRequest} XmlHttpRequest object.
+ */
+function createXmlHttpRequest() {
+    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;
+}
+
+/** Checks whether the specified URL is an absolute URL.
+ * @param {String} url - URL to check.
+ * @returns {Boolean} true if the url is an absolute URL; false otherwise.
+*/
+function isAbsoluteUrl(url) {
+    return url.indexOf("http://") === 0 ||
+        url.indexOf("https://") === 0 ||
+        url.indexOf("file://") === 0;
+}
+
+/** Checks whether the specified URL is local to the current context.
+ * @param {String} url - URL to check.
+ * @returns {Boolean} true if the url is a local URL; false otherwise.
+ */
+function isLocalUrl(url) {
+
+    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);
+}
+
+/** Removes a callback used for a JSONP request.
+ * @param {String} name - Function name to remove.
+ * @param {Number} tick - Tick count used on the callback.
+ */
+function removeCallback(name, tick) {
+    try {
+        delete window[name];
+    } catch (err) {
+        window[name] = undefined;
+        if (tick === ticks - 1) {
+            ticks -= 1;
+        }
+    }
+}
+
+/** Removes an iframe.
+ * @param {Object} iframe - The iframe to remove.
+ * @returns {Object} Null value to be assigned to iframe reference.
+ */
+function removeIFrame(iframe) {
+    if (iframe) {
+        writeHtmlToIFrame(iframe, "");
+        iframe.parentNode.removeChild(iframe);
+    }
+
+    return null;
+}
+
+/** Reads response headers into array.
+ * @param {XMLHttpRequest} xhr - HTTP request with response available.
+ * @param {Array} headers - Target array to fill with name/value pairs.
+ */
+function readResponseHeaders(xhr, headers) {
+
+    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];
+        }
+    }
+}
+
+/** Writes HTML to an IFRAME document.
+ * @param {HTMLElement} iframe - The IFRAME element to write to.
+ * @param {String} html - The HTML to write.
+ */
+function writeHtmlToIFrame(iframe, html) {
+    var frameDocument = (iframe.contentWindow) ? iframe.contentWindow.document : iframe.contentDocument.document;
+    frameDocument.open();
+    frameDocument.write(html);
+    frameDocument.close();
+}
+
+exports.defaultHttpClient = {
+    callbackParameterName: "$callback",
+
+    formatQueryString: "$format=json",
+
+    enableJsonpCallback: false,
+
+    /** Performs a network request.
+     * @param {Object} request - Request description
+     * @param {Function} success - Success callback with the response object.
+     * @param {Function} error - Error callback with an error object.
+     * @returns {Object} Object with an 'abort' method for the operation.
+     */
+    request: function createRequest() {
+
+        var that = this;
+
+
+        return function(request, success, error) {
+
+        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 , that.enableJsonpCallback);
+        var callbackParameterName = defined(request.callbackParameterName, that.callbackParameterName);
+        var formatQueryString = defined(request.formatQueryString, that.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;
+    }
+    }()
+};
+
+
+
+exports.canUseJSONP = canUseJSONP;
+exports.isAbsoluteUrl = isAbsoluteUrl;
+exports.isLocalUrl = isLocalUrl;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/odata/net.js
----------------------------------------------------------------------
diff --git a/lib/odata/net.js b/lib/odata/net.js
new file mode 100644
index 0000000..be45295
--- /dev/null
+++ b/lib/odata/net.js
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+/** @module odata/net */
+
+
+var http = require('http');
+var utils    = require('./../utils.js');
+var url = require("url");
+
+
+var defined = utils.defined;
+var delay = utils.delay;
+
+var ticks = 0;
+
+/* Checks whether the specified request can be satisfied with a JSONP request.
+ * @param request - Request object to check.
+ * @returns {Boolean} true if the request can be satisfied; false otherwise.
+
+ * 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.
+ */
+function canUseJSONP(request) {
+    return false;
+}
+
+
+
+/** Checks whether the specified URL is an absolute URL.
+ * @param {String} url - URL to check.
+ * @returns {Boolean} true if the url is an absolute URL; false otherwise.
+*/
+function isAbsoluteUrl(url) {
+    return url.indexOf("http://") === 0 ||
+           url.indexOf("https://") === 0 ||
+           url.indexOf("file://") === 0;
+}
+
+/** Checks whether the specified URL is local to the current context.
+ * @param {String} url - URL to check.
+ * @returns {Boolean} true if the url is a local URL; false otherwise.
+ */
+function isLocalUrl(url) {
+
+    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);
+}
+
+
+/** Reads response headers into array.
+ * @param {Object} inHeader
+ * @param {Array} outHeader
+ */
+function readResponseHeaders(inHeader, outHeader) {
+    for (var property in inHeader) {
+        
+        if (inHeader.hasOwnProperty(property)) {
+            outHeader[property] = inHeader[property];
+        }
+    }
+}
+
+    
+
+
+
+exports.defaultHttpClient = {
+    formatQueryString: "$format=json",
+
+    
+    /** Performs a network request.
+     * @param {Object} request - Request description
+     * @param {Function} success - Success callback with the response object.
+     * @param {Function} error - Error callback with an error object.
+     * @returns {Object} Object with an 'abort' method for the operation.
+     */
+    request: function (request, success, error) {
+
+        var result = {};
+        var done = false;
+        
+        var options = url.parse(request.requestUri);
+        options.method = request.method || "GET";
+        options.headers = {};
+        //options.auth = request.user + ':' + request.password;
+        //add headers
+        var name;
+        if (request.headers) {
+            for (name in request.headers) {
+                options.headers[name] = request.headers[name];
+            }
+        }   
+        
+
+        var xhr = http.request(options);
+
+        result.abort = function () {
+            if (done) {
+                return;
+            }
+
+            done = true;
+            if (xhr) {
+                xhr.abort();
+                xhr = null;
+            }
+
+            error({ message: "Request aborted" });
+        };
+
+        // Set the timeout if available.
+        if (request.timeoutMS) {
+            xhr.setTimeout(request.timeoutMS,function () {
+                if (!done) {
+                    done = true;
+                    xhr = null;
+                    error({ message: "Request timed out" });
+                }
+            });
+        }
+
+        xhr.on('error', function(e) {
+            var response = { requestUri: url, statusCode: 400, statusText: e.message };
+            error({ message: "HTTP request failed", request: request, response: response });
+        });
+             
+
+        xhr.on('response', function (resp) {
+            if (done || xhr === null) {
+                return;
+            }
+
+            var headers = [];
+            readResponseHeaders(resp.headers, headers);
+                        
+            var body = '';
+
+            resp.on('data', function(chunk) {
+                body+=chunk;
+            });
+            resp.on('end', function() {
+                // do what you do
+                var response = { requestUri: url, statusCode: resp.statusCode, statusText: '', headers: headers, body: body };
+
+                done = true;
+                xhr = null;
+                if (resp.statusCode >= 200 && resp.statusCode <= 299) {
+                    success(response);
+                } else {
+                    error({ message: "HTTP request failed", request: request, response: response });
+                }   
+            });
+        });
+
+        //xhr.open(request.method || "GET", url, true,);
+        if (request.body) {
+            xhr.write(request.body);
+        }
+        xhr.end();
+
+        return result;
+    }
+};
+
+
+
+exports.canUseJSONP = canUseJSONP;
+exports.isAbsoluteUrl = isAbsoluteUrl;
+exports.isLocalUrl = isLocalUrl;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/odata/odatautils.js
----------------------------------------------------------------------
diff --git a/lib/odata/odatautils.js b/lib/odata/odatautils.js
new file mode 100644
index 0000000..78b9c5a
--- /dev/null
+++ b/lib/odata/odatautils.js
@@ -0,0 +1,1273 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+ /** @module odata/utils */
+
+var utils    = require('./../utils.js');
+
+// Imports
+var assigned = utils.assigned;
+var contains = utils.contains;
+var find = utils.find;
+var isArray = utils.isArray;
+var isDate = utils.isDate;
+var isObject = utils.isObject;
+var parseInt10 = utils.parseInt10;
+
+
+/** Gets the type name of a data item value that belongs to a feed, an entry, a complex type property, or a collection property
+ * @param {string} value - Value of the data item from which the type name is going to be retrieved.
+ * @param {object} [metadata] - Object containing metadata about the data tiem.
+ * @returns {string} Data item type name; null if the type name cannot be found within the value or the metadata
+ * 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.
+ */
+var dataItemTypeName = function (value, metadata) {
+    var valueTypeName = ((value && value.__metadata) || {}).type;
+    return valueTypeName || (metadata ? metadata.type : null);
+};
+
+var EDM = "Edm.";
+var EDM_BOOLEAN = EDM + "Boolean";
+var EDM_BYTE = EDM + "Byte";
+var EDM_SBYTE = EDM + "SByte";
+var EDM_INT16 = EDM + "Int16";
+var EDM_INT32 = EDM + "Int32";
+var EDM_INT64 = EDM + "Int64";
+var EDM_SINGLE = EDM + "Single";
+var EDM_DOUBLE = EDM + "Double";
+var EDM_DECIMAL = EDM + "Decimal";
+var EDM_STRING = EDM + "String";
+
+var EDM_BINARY = EDM + "Binary";
+var EDM_DATE = EDM + "Date";
+var EDM_DATETIMEOFFSET = EDM + "DateTimeOffset";
+var EDM_DURATION = EDM + "Duration";
+var EDM_GUID = EDM + "Guid";
+var EDM_TIMEOFDAY = EDM + "Time";
+
+var GEOGRAPHY = "Geography";
+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 GEOGRAPHY_POINT = GEOGRAPHY + "Point";
+var GEOGRAPHY_LINESTRING = GEOGRAPHY + "LineString";
+var GEOGRAPHY_POLYGON = GEOGRAPHY + "Polygon";
+var GEOGRAPHY_COLLECTION = GEOGRAPHY + "Collection";
+var GEOGRAPHY_MULTIPOLYGON = GEOGRAPHY + "MultiPolygon";
+var GEOGRAPHY_MULTILINESTRING = GEOGRAPHY + "MultiLineString";
+var GEOGRAPHY_MULTIPOINT = GEOGRAPHY + "MultiPoint";
+
+var GEOMETRY = "Geometry";
+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 GEOMETRY_POINT = GEOMETRY + "Point";
+var GEOMETRY_LINESTRING = GEOMETRY + "LineString";
+var GEOMETRY_POLYGON = GEOMETRY + "Polygon";
+var GEOMETRY_COLLECTION = GEOMETRY + "Collection";
+var GEOMETRY_MULTIPOLYGON = GEOMETRY + "MultiPolygon";
+var GEOMETRY_MULTILINESTRING = GEOMETRY + "MultiLineString";
+var GEOMETRY_MULTIPOINT = 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_DATE,
+    EDM_DATETIMEOFFSET,
+    EDM_DURATION,
+    EDM_TIMEOFDAY,
+    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 geometryTypes = [
+    GEOMETRY,
+    GEOMETRY_POINT,
+    GEOMETRY_LINESTRING,
+    GEOMETRY_POLYGON,
+    GEOMETRY_COLLECTION,
+    GEOMETRY_MULTIPOLYGON,
+    GEOMETRY_MULTILINESTRING,
+    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 geographyTypes = [
+    GEOGRAPHY,
+    GEOGRAPHY_POINT,
+    GEOGRAPHY_LINESTRING,
+    GEOGRAPHY_POLYGON,
+    GEOGRAPHY_COLLECTION,
+    GEOGRAPHY_MULTIPOLYGON,
+    GEOGRAPHY_MULTILINESTRING,
+    GEOGRAPHY_MULTIPOINT
+];
+
+/** Invokes a function once per schema in metadata.
+ * @param metadata - Metadata store; one of edmx, schema, or an array of any of them.
+ * @param {Function} callback - Callback function to invoke once per schema.
+ * @returns The first truthy value to be returned from the callback; null or the last falsy value otherwise.
+ */
+function forEachSchema(metadata, callback) {
+    
+
+    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);
+    }
+}
+
+/** Formats a millisecond and a nanosecond value into a single string.
+ * @param {Number} ms - Number of milliseconds to format.
+ * @param {Number} ns - Number of nanoseconds to format.
+ * @returns {String} Formatted text.
+ * If the value is already as string it's returned as-is.
+ */
+function formatMilliseconds(ms, ns) {
+
+    // 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;
+}
+
+function formatDateTimeOffsetJSON(value) {
+    return "\/Date(" + value.getTime() + ")\/";
+}
+
+/** Formats a DateTime or DateTimeOffset value a string.
+ * @param {Date} value - Value to format
+ * @returns {String} Formatted text.
+ * If the value is already as string it's returned as-is
+´*/
+function formatDateTimeOffset(value) {
+
+    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;
+}
+
+/** Converts a duration to a string in xsd:duration format.
+ * @param {Object} value - Object with ms and __edmType properties.
+ * @returns {String} String representation of the time object in xsd:duration format.
+ */
+function formatDuration(value) {
+
+    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";
+}
+
+/** Formats the specified value to the given width.
+ * @param {Number} value - Number to format (non-negative).
+ * @param {Number} width - Minimum width for number.
+ * @param {Boolean} append - Flag indicating if the value is padded at the beginning (false) or at the end (true).
+ * @returns {String} Text representation.
+ */
+function formatNumberWidth(value, width, append) {
+    var result = value.toString(10);
+    while (result.length < width) {
+        if (append) {
+            result += "0";
+        } else {
+            result = "0" + result;
+        }
+    }
+
+    return result;
+}
+
+/** Gets the canonical timezone representation.
+ * @param {String} timezone - Timezone representation.
+ * @returns {String} An 'Z' string if the timezone is absent or 0; the timezone otherwise.
+ */
+function getCanonicalTimezone(timezone) {
+
+    return (!timezone || timezone === "Z" || timezone === "+00:00" || timezone === "-00:00") ? "Z" : timezone;
+}
+
+/** Gets the type of a collection type name.
+ * @param {String} typeName - Type name of the collection.
+ * @returns {String} Type of the collection; null if the type name is not a collection type.
+ */
+function getCollectionType(typeName) {
+
+    if (typeof typeName === "string") {
+        var end = typeName.indexOf(")", 10);
+        if (typeName.indexOf("Collection(") === 0 && end > 0) {
+            return typeName.substring(11, end);
+        }
+    }
+    return null;
+}
+
+/** Sends a request containing OData payload to a server.
+* @param request - Object that represents the request to be sent..
+* @param success - Callback for a successful read operation.
+* @param error - Callback for handling errors.
+* @param handler - Handler for data serialization.
+* @param httpClient - HTTP client layer.
+* @param context - Context used for processing the request
+*/
+function invokeRequest(request, success, error, handler, httpClient, context) {
+
+    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;
+        }
+        // errors in success handler for sync requests result in error handler calls. So here we fix this. 
+        try {
+            success(response.data, response);
+        } catch (err) {
+            err.bIsSuccessHandlerError = true;
+            throw err;
+        }
+    }, error);
+}
+
+/** Tests whether a value is a batch object in the library's internal representation.
+ * @param value - Value to test.
+ * @returns {Boolean} True is the value is a batch object; false otherwise.
+ */
+function isBatch(value) {
+
+    return isComplex(value) && isArray(value.__batchRequests);
+}
+
+// Regular expression used for testing and parsing for a collection type.
+var collectionTypeRE = /Collection\((.*)\)/;
+
+/** Tests whether a value is a collection value in the library's internal representation.
+ * @param value - Value to test.
+ * @param {String} typeName - Type name of the value. This is used to disambiguate from a collection property value.
+ * @returns {Boolean} True is the value is a feed value; false otherwise.
+ */
+function isCollection(value, typeName) {
+
+    var colData = value && value.results || value;
+    return !!colData &&
+        (isCollectionType(typeName)) ||
+        (!typeName && isArray(colData) && !isComplex(colData[0]));
+}
+
+/** Checks whether the specified type name is a collection type.
+ * @param {String} typeName - Name of type to check.
+ * @returns {Boolean} True if the type is the name of a collection type; false otherwise.
+ */
+function isCollectionType(typeName) {
+    return collectionTypeRE.test(typeName);
+}
+
+/** Tests whether a value is a complex type value in the library's internal representation.
+ * @param value - Value to test.
+ * @returns {Boolean} True is the value is a complex type value; false otherwise.
+ */
+function isComplex(value) {
+
+    return !!value &&
+        isObject(value) &&
+        !isArray(value) &&
+        !isDate(value);
+}
+
+/** Checks whether a Date object is DateTimeOffset value
+ * @param {Date} value - Value to check
+ * @returns {Boolean} true if the value is a DateTimeOffset, false otherwise.
+ */
+function isDateTimeOffset(value) {
+    return (value.__edmType === "Edm.DateTimeOffset" || (!value.__edmType && value.__offset));
+}
+
+/** Tests whether a value is a deferred navigation property in the library's internal representation.
+ * @param value - Value to test.
+ * @returns {Boolean} True is the value is a deferred navigation property; false otherwise.
+ */
+function isDeferred(value) {
+
+    if (!value && !isComplex(value)) {
+        return false;
+    }
+    var metadata = value.__metadata || {};
+    var deferred = value.__deferred || {};
+    return !metadata.type && !!deferred.uri;
+}
+
+/** Tests whether a value is an entry object in the library's internal representation.
+ * @param value - Value to test.
+ * @returns {Boolean} True is the value is an entry object; false otherwise.
+ */
+function isEntry(value) {
+
+    return isComplex(value) && value.__metadata && "uri" in value.__metadata;
+}
+
+/** Tests whether a value is a feed value in the library's internal representation.
+ * @param value - Value to test.
+ * @param {String} typeName - Type name of the value. This is used to disambiguate from a collection property value.
+ * @returns {Boolean} True is the value is a feed value; false otherwise.
+ */
+function isFeed(value, typeName) {
+
+    var feedData = value && value.results || value;
+    return isArray(feedData) && (
+        (!isCollectionType(typeName)) &&
+        (isComplex(feedData[0]))
+    );
+}
+
+/** Checks whether the specified type name is a geography EDM type.
+ * @param {String} typeName - Name of type to check.
+ * @returns {Boolean} True if the type is a geography EDM type; false otherwise.
+ */
+function isGeographyEdmType(typeName) {
+    //check with edm
+    return contains(geographyEdmTypes, typeName) ||
+        (typeName.indexOf('.') === -1 && contains(geographyTypes, typeName));
+        
+}
+
+/** Checks whether the specified type name is a geometry EDM type.
+ * @param {String} typeName - Name of type to check.
+ * @returns {Boolean} True if the type is a geometry EDM type; false otherwise.
+ */
+function isGeometryEdmType(typeName) {
+    return contains(geometryEdmTypes, typeName) ||
+        (typeName.indexOf('.') === -1 && contains(geometryTypes, typeName));
+}
+
+
+
+/** Tests whether a value is a named stream value in the library's internal representation.
+ * @param value - Value to test.
+ * @returns {Boolean} True is the value is a named stream; false otherwise.
+ */
+function isNamedStream(value) {
+
+    if (!value && !isComplex(value)) {
+        return false;
+    }
+    var metadata = value.__metadata;
+    var mediaResource = value.__mediaresource;
+    return !metadata && !!mediaResource && !!mediaResource.media_src;
+}
+
+/** Tests whether a value is a primitive type value in the library's internal representation.
+ * @param value - Value to test.
+ * @returns {Boolean} True is the value is a primitive type value.
+ * Date objects are considered primitive types by the library.
+ */
+function isPrimitive(value) {
+
+    return isDate(value) ||
+        typeof value === "string" ||
+        typeof value === "number" ||
+        typeof value === "boolean";
+}
+
+/** Checks whether the specified type name is a primitive EDM type.
+ * @param {String} typeName - Name of type to check.
+ * @returns {Boolean} True if the type is a primitive EDM type; false otherwise.
+ */
+function isPrimitiveEdmType(typeName) {
+
+    return contains(primitiveEdmTypes, typeName);
+}
+
+/** Gets the kind of a navigation property value.
+ * @param value - Value of the navigation property.
+ * @param {Object} [propertyModel] - Object that describes the navigation property in an OData conceptual schema.
+ * @returns {String} String value describing the kind of the navigation property; null if the kind cannot be determined.
+ */
+function navigationPropertyKind(value, propertyModel) {
+
+    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;
+}
+
+/** Looks up a property by name.
+ * @param {Array} properties - Array of property objects as per EDM metadata (may be null)
+ * @param {String} name - Name to look for.
+ * @returns {Object} The property object; null if not found.
+ */
+function lookupProperty(properties, name) {
+
+    return find(properties, function (property) {
+        return property.name === name;
+    });
+}
+
+/** Looks up a type object by name.
+ * @param {String} name - Name, possibly null or empty.
+ * @param metadata - Metadata store; one of edmx, schema, or an array of any of them.
+ * @param {String} kind - Kind of object to look for as per EDM metadata.
+ * @returns An type description if the name is found; null otherwise
+ */
+function lookupInMetadata(name, metadata, kind) {
+
+    return (name) ? forEachSchema(metadata, function (schema) {
+        return lookupInSchema(name, schema, kind);
+    }) : null;
+}
+
+/** Looks up a entity set by name.
+ * @param {Array} entitySets - Array of entity set objects as per EDM metadata( may be null)
+ * @param {String} name - Name to look for.
+ * @returns {Object} The entity set object; null if not found.
+ */
+function lookupEntitySet(entitySets, name) {
+
+    return find(entitySets, function (entitySet) {
+        return entitySet.name === name;
+    });
+}
+
+/** Looks up a entity set by name.
+ * @param {Array} singletons - Array of entity set objects as per EDM metadata (may be null)
+ * @param {String} name - Name to look for.
+ * @returns {Object} The entity set object; null if not found.
+ */
+function lookupSingleton(singletons, name) {
+
+    return find(singletons, function (singleton) {
+        return singleton.name === name;
+    });
+}
+
+/** Looks up a complex type object by name.
+ * @param {String} name - Name, possibly null or empty.
+ * @param metadata - Metadata store; one of edmx, schema, or an array of any of them.
+ * @returns A complex type description if the name is found; null otherwise.
+ */
+function lookupComplexType(name, metadata) {
+
+    return lookupInMetadata(name, metadata, "complexType");
+}
+
+/** Looks up an entity type object by name.
+ * @param {String} name - Name, possibly null or empty.
+ * @param metadata - Metadata store; one of edmx, schema, or an array of any of them.
+ * @returns An entity type description if the name is found; null otherwise.
+ */
+function lookupEntityType(name, metadata) {
+
+    return lookupInMetadata(name, metadata, "entityType");
+}
+
+
+/** Looks up an
+ * @param metadata - Metadata store; one of edmx, schema, or an array of any of them.
+ * @returns An entity container description if the name is found; null otherwise.
+ */
+function lookupDefaultEntityContainer(metadata) {
+
+    return forEachSchema(metadata, function (schema) {
+        if (isObject(schema.entityContainer)) { 
+            return schema.entityContainer;
+        }
+    });
+}
+
+/** Looks up an entity container object by name.
+ * @param {String} name - Name, possibly null or empty.
+ * @param metadata - Metadata store; one of edmx, schema, or an array of any of them.
+ * @returns An entity container description if the name is found; null otherwise.
+ */
+function lookupEntityContainer(name, metadata) {
+
+    return lookupInMetadata(name, metadata, "entityContainer");
+}
+
+/** Looks up a function import by name.
+ * @param {Array} functionImports - Array of function import objects as per EDM metadata (May be null)
+ * @param {String} name - Name to look for.
+ * @returns {Object} The entity set object; null if not found.
+ */
+function lookupFunctionImport(functionImports, name) {
+    return find(functionImports, function (functionImport) {
+        return functionImport.name === name;
+    });
+}
+
+/** Looks up the target entity type for a navigation property.
+ * @param {Object} navigationProperty - 
+ * @param {Object} metadata - 
+ * @returns {String} The entity type name for the specified property, null if not found.
+ */
+function lookupNavigationPropertyType(navigationProperty, metadata) {
+
+    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;
+}
+
+/** Looks up the target entityset name for a navigation property.
+ * @param {Object} navigationProperty - 
+ * @param {Object} sourceEntitySetName -
+ * @param {Object} metadata -
+ * metadata
+ * @returns {String} The entityset name for the specified property, null if not found.
+ */
+function lookupNavigationPropertyEntitySet(navigationProperty, sourceEntitySetName, metadata) {
+
+    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;
+}
+
+/** Gets the entitySet info, container name and functionImports for an entitySet
+ * @param {Object} entitySetName -
+ * @param {Object} metadata - 
+ * @returns {Object} The info about the entitySet.
+ */
+function getEntitySetInfo(entitySetName, metadata) {
+
+    var info = forEachSchema(metadata, function (schema) {
+        var container = schema.entityContainer;
+        var entitySets = container.entitySet;
+        if (entitySets) {
+            for (var j = 0; j < entitySets.length; j++) {
+                if (entitySets[j].name == entitySetName) {
+                    return { entitySet: entitySets[j], containerName: container.name, functionImport: container.functionImport };
+                }
+            }
+        }
+        return null;
+    });
+
+    return info;
+}
+
+/** Given an expected namespace prefix, removes it from a full name.
+ * @param {String} ns - Expected namespace.
+ * @param {String} fullName - Full name in 'ns'.'name' form.
+ * @returns {String} The local name, null if it isn't found in the expected namespace.
+ */
+function removeNamespace(ns, fullName) {
+
+    if (fullName.indexOf(ns) === 0 && fullName.charAt(ns.length) === ".") {
+        return fullName.substr(ns.length + 1);
+    }
+
+    return null;
+}
+
+/** Looks up a schema object by name.
+ * @param {String} name - Name (assigned).
+ * @param schema - Schema object as per EDM metadata.
+ * @param {String} kind - Kind of object to look for as per EDM metadata.
+ * @returns An entity type description if the name is found; null otherwise.
+ */
+function lookupInSchema(name, schema, kind) {
+
+    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;
+}
+
+/** Compares to version strings and returns the higher one.
+ * @param {String} left - Version string in the form "major.minor.rev"
+ * @param {String} right - Version string in the form "major.minor.rev"
+ * @returns {String} The higher version string.
+ */
+function maxVersion(left, right) {
+
+    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",
+    "content-id": "Content-ID",
+    "content-transfer-encoding": "Content-Transfer-Encoding",
+    
+    // Headers used by response
+    "etag": "ETag",
+    "location": "Location",
+    "odata-entityid": "OData-EntityId",
+    "preference-applied": "Preference-Applied",
+    "retry-after": "Retry-After"
+};
+
+/** Normalizes headers so they can be found with consistent casing.
+ * @param {Object} headers - Dictionary of name/value pairs.
+ */
+function normalizeHeaders(headers) {
+
+    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;
+        }
+    }
+}
+
+/** Parses a string into a boolean value.
+ * @param propertyValue - Value to parse.
+ * @returns {Boolean} true if the property value is 'true'; false otherwise.
+ */
+function parseBool(propertyValue) {
+
+    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+))?(.*)$/;
+
+/** Parses a string into a DateTime value.
+ * @param {String} value - Value to parse.
+ * @param {Boolean} withOffset - Whether offset is expected.
+ * @param {Boolean} nullOnError - return null instead of throwing an exception
+ * @returns {Date} The parsed value.
+ */
+function parseDateTimeMaybeOffset(value, withOffset, nullOnError) {
+
+    // 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;
+}
+
+/** Parses a string into a Date object.
+ * @param {String} propertyValue - Value to parse.
+ * @param {Boolean} nullOnError - return null instead of throwing an exception
+ * @returns {Date} The parsed with year, month, day set, time values are set to 0
+ */
+function parseDate(propertyValue, nullOnError) {
+    var parts = propertyValue.split('-');
+
+    if (parts.length != 3 && nullOnError) {
+        return null;
+    }
+    return new Date(
+        parseInt10(parts[0]),       // Year.
+        parseInt10(parts[1]) - 1,   // Month (zero-based for Date.UTC and setFullYear).
+        parseInt10(parts[2],
+        0,0,0,0)        // Date.
+        );
+
+}
+
+var parseTimeOfDayRE = /^(\d+):(\d+)(:(\d+)(.(\d+))?)?$/;
+
+/**Parses a time into a Date object.
+ * @param propertyValue
+ * @param {Boolean} nullOnError - return null instead of throwing an exception
+ * @returns {{h: Number, m: Number, s: Number, ms: Number}}
+ */
+function parseTimeOfDay(propertyValue, nullOnError) {
+    var parts = parseTimeOfDayRE.exec(propertyValue);
+
+
+    return {
+        'h' :parseInt10(parts[1]),
+        'm' :parseInt10(parts[2]),
+        's' :parseInt10(parts[4]),
+        'ms' :parseInt10(parts[6])
+     };
+}
+
+/** Parses a string into a DateTimeOffset value.
+ * @param {String} propertyValue - Value to parse.
+ * @param {Boolean} nullOnError - return null instead of throwing an exception
+ * @returns {Date} The parsed value.
+ * 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.
+ */
+function parseDateTimeOffset(propertyValue, nullOnError) {
+    
+
+    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)?)?/;
+
+function isEdmDurationValue(value) {
+    parseTimeRE.test(value);
+}
+
+/** Parses a string in xsd:duration format.
+ * @param {String} duration - Duration value.
+
+ * This method will throw an exception if the input string has a year or a month component.
+
+ * @returns {Object} Object representing the time
+ */
+function parseDuration(duration) {
+
+    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;
+}
+
+/** Parses a timezone description in (+|-)nn:nn format.
+ * @param {String} timezone - Timezone offset.
+ * @returns {Object} An object with a (d)irection property of 1 for + and -1 for -, offset (h)ours and offset (m)inutes.
+ */
+function parseTimezone(timezone) {
+
+    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 };
+}
+
+/** Prepares a request object so that it can be sent through the network.
+* @param request - Object that represents the request to be sent.
+* @param handler - Handler for data serialization
+* @param context - Context used for preparing the request
+*/
+function prepareRequest(request, handler, context) {
+
+    // 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";
+    }
+
+    if (request.async === undefined) {
+        request.async = true;
+    }
+
+}
+
+/** Traverses a tree of objects invoking callback for every value.
+ * @param {Object} item - Object or array to traverse.
+ * @param {Object} owner - Pass through each callback
+ * @param {Function} callback - Callback function with key and value, similar to JSON.parse reviver.
+ * @returns {Object} The object with traversed properties.
+ Unlike the JSON reviver, this won't delete null members.
+*/
+function traverseInternal(item, owner, callback) {
+
+    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;
+}
+
+/** Traverses a tree of objects invoking callback for every value.
+ * @param {Object} item - Object or array to traverse.
+ * @param {Function} callback - Callback function with key and value, similar to JSON.parse reviver.
+ * @returns {Object} The traversed object.
+ * Unlike the JSON reviver, this won't delete null members.
+*/
+function traverse(item, callback) {
+
+    return callback("", traverseInternal(item, "", callback));
+}
+
+exports.dataItemTypeName = dataItemTypeName;
+exports.EDM_BINARY = EDM_BINARY;
+exports.EDM_BOOLEAN = EDM_BOOLEAN;
+exports.EDM_BYTE = EDM_BYTE;
+exports.EDM_DATE = EDM_DATE;
+exports.EDM_DATETIMEOFFSET = EDM_DATETIMEOFFSET;
+exports.EDM_DURATION = EDM_DURATION;
+exports.EDM_DECIMAL = EDM_DECIMAL;
+exports.EDM_DOUBLE = EDM_DOUBLE;
+exports.EDM_GEOGRAPHY = EDM_GEOGRAPHY;
+exports.EDM_GEOGRAPHY_POINT = EDM_GEOGRAPHY_POINT;
+exports.EDM_GEOGRAPHY_LINESTRING = EDM_GEOGRAPHY_LINESTRING;
+exports.EDM_GEOGRAPHY_POLYGON = EDM_GEOGRAPHY_POLYGON;
+exports.EDM_GEOGRAPHY_COLLECTION = EDM_GEOGRAPHY_COLLECTION;
+exports.EDM_GEOGRAPHY_MULTIPOLYGON = EDM_GEOGRAPHY_MULTIPOLYGON;
+exports.EDM_GEOGRAPHY_MULTILINESTRING = EDM_GEOGRAPHY_MULTILINESTRING;
+exports.EDM_GEOGRAPHY_MULTIPOINT = EDM_GEOGRAPHY_MULTIPOINT;
+exports.EDM_GEOMETRY = EDM_GEOMETRY;
+exports.EDM_GEOMETRY_POINT = EDM_GEOMETRY_POINT;
+exports.EDM_GEOMETRY_LINESTRING = EDM_GEOMETRY_LINESTRING;
+exports.EDM_GEOMETRY_POLYGON = EDM_GEOMETRY_POLYGON;
+exports.EDM_GEOMETRY_COLLECTION = EDM_GEOMETRY_COLLECTION;
+exports.EDM_GEOMETRY_MULTIPOLYGON = EDM_GEOMETRY_MULTIPOLYGON;
+exports.EDM_GEOMETRY_MULTILINESTRING = EDM_GEOMETRY_MULTILINESTRING;
+exports.EDM_GEOMETRY_MULTIPOINT = EDM_GEOMETRY_MULTIPOINT;
+exports.EDM_GUID = EDM_GUID;
+exports.EDM_INT16 = EDM_INT16;
+exports.EDM_INT32 = EDM_INT32;
+exports.EDM_INT64 = EDM_INT64;
+exports.EDM_SBYTE = EDM_SBYTE;
+exports.EDM_SINGLE = EDM_SINGLE;
+exports.EDM_STRING = EDM_STRING;
+exports.EDM_TIMEOFDAY = EDM_TIMEOFDAY;
+exports.GEOJSON_POINT = GEOJSON_POINT;
+exports.GEOJSON_LINESTRING = GEOJSON_LINESTRING;
+exports.GEOJSON_POLYGON = GEOJSON_POLYGON;
+exports.GEOJSON_MULTIPOINT = GEOJSON_MULTIPOINT;
+exports.GEOJSON_MULTILINESTRING = GEOJSON_MULTILINESTRING;
+exports.GEOJSON_MULTIPOLYGON = GEOJSON_MULTIPOLYGON;
+exports.GEOJSON_GEOMETRYCOLLECTION = GEOJSON_GEOMETRYCOLLECTION;
+exports.forEachSchema = forEachSchema;
+exports.formatDateTimeOffset = formatDateTimeOffset;
+exports.formatDateTimeOffsetJSON = formatDateTimeOffsetJSON;
+exports.formatDuration = formatDuration;
+exports.formatNumberWidth = formatNumberWidth;
+exports.getCanonicalTimezone = getCanonicalTimezone;
+exports.getCollectionType = getCollectionType;
+exports.invokeRequest = invokeRequest;
+exports.isBatch = isBatch;
+exports.isCollection = isCollection;
+exports.isCollectionType = isCollectionType;
+exports.isComplex = isComplex;
+exports.isDateTimeOffset = isDateTimeOffset;
+exports.isDeferred = isDeferred;
+exports.isEntry = isEntry;
+exports.isFeed = isFeed;
+exports.isGeographyEdmType = isGeographyEdmType;
+exports.isGeometryEdmType = isGeometryEdmType;
+exports.isNamedStream = isNamedStream;
+exports.isPrimitive = isPrimitive;
+exports.isPrimitiveEdmType = isPrimitiveEdmType;
+exports.lookupComplexType = lookupComplexType;
+exports.lookupDefaultEntityContainer = lookupDefaultEntityContainer;
+exports.lookupEntityContainer = lookupEntityContainer;
+exports.lookupEntitySet = lookupEntitySet;
+exports.lookupSingleton = lookupSingleton;
+exports.lookupEntityType = lookupEntityType;
+exports.lookupFunctionImport = lookupFunctionImport;
+exports.lookupNavigationPropertyType = lookupNavigationPropertyType;
+exports.lookupNavigationPropertyEntitySet = lookupNavigationPropertyEntitySet;
+exports.lookupInSchema = lookupInSchema;
+exports.lookupProperty = lookupProperty;
+exports.lookupInMetadata = lookupInMetadata;
+exports.getEntitySetInfo = getEntitySetInfo;
+exports.maxVersion = maxVersion;
+exports.navigationPropertyKind = navigationPropertyKind;
+exports.normalizeHeaders = normalizeHeaders;
+exports.parseBool = parseBool;
+
+
+exports.parseDate = parseDate;
+exports.parseDateTimeOffset = parseDateTimeOffset;
+exports.parseDuration = parseDuration;
+exports.parseTimeOfDay = parseTimeOfDay;
+
+exports.parseInt10 = parseInt10;
+exports.prepareRequest = prepareRequest;
+exports.removeNamespace = removeNamespace;
+exports.traverse = traverse;
+
+

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/store.js
----------------------------------------------------------------------
diff --git a/lib/store.js b/lib/store.js
new file mode 100644
index 0000000..d7e321d
--- /dev/null
+++ b/lib/store.js
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+//'use strict';
+
+ /** @module store */
+
+
+
+
+
+exports.defaultStoreMechanism = "best";
+
+/** Creates a new store object.
+ * @param {String} name - Store name.
+ * @param {String} [mechanism] - 
+ * @returns {Object} Store object.
+*/
+exports.createStore = function (name, mechanism) {
+
+
+    if (!mechanism) {
+        mechanism = exports.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 };
+};
+
+exports.DomStore       = DomStore       = require('./store/dom.js');
+exports.IndexedDBStore = IndexedDBStore = require('./store/indexeddb.js');
+exports.MemoryStore    = MemoryStore    = require('./store/memory.js');
+
+var mechanisms = {
+    indexeddb: IndexedDBStore,
+    dom: DomStore,
+    memory: MemoryStore
+};
+
+exports.mechanisms = mechanisms;
+
+
+
+


[7/8] olingo-odata4-js git commit: [OLINGO-442] Cleanup bevore release II and beta-name removal

Posted by ko...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/odata.js
----------------------------------------------------------------------
diff --git a/lib/odata.js b/lib/odata.js
new file mode 100644
index 0000000..6f660f6
--- /dev/null
+++ b/lib/odata.js
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+ /** @module odata */
+
+// Imports
+var odataUtils    = exports.utils     = require('./odata/odatautils.js');
+var odataHandler  = exports.handler   = require('./odata/handler.js');
+var odataMetadata = exports.metadata  = require('./odata/metadata.js');
+var odataNet      = exports.net       = require('./odata/net.js');
+var odataJson     = exports.json      = require('./odata/json.js');
+                    exports.batch     = require('./odata/batch.js');
+                    
+
+
+var utils = require('./utils.js');
+var assigned = utils.assigned;
+
+var defined = utils.defined;
+var throwErrorCallback = utils.throwErrorCallback;
+
+var invokeRequest = odataUtils.invokeRequest;
+var MAX_DATA_SERVICE_VERSION = odataHandler.MAX_DATA_SERVICE_VERSION;
+var prepareRequest = odataUtils.prepareRequest;
+var metadataParser = odataMetadata.metadataParser;
+
+// CONTENT START
+
+var handlers = [odataJson.jsonHandler, odataHandler.textHandler];
+
+/** Dispatches an operation to handlers.
+ * @param {String} handlerMethod - Name of handler method to invoke.
+ * @param {Object} requestOrResponse - request/response argument for delegated call.
+ * @param {Object} context - context argument for delegated call.
+ */
+function dispatchHandler(handlerMethod, requestOrResponse, context) {
+
+    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" };
+    }
+}
+
+/** Default success handler for OData.
+ * @param data - Data to process.
+ */
+exports.defaultSuccess = function (data) {
+
+    window.alert(window.JSON.stringify(data));
+};
+
+exports.defaultError = throwErrorCallback;
+
+exports.defaultHandler = {
+
+        /** Reads the body of the specified response by delegating to JSON handlers.
+        * @param response - Response object.
+        * @param context - Operation context.
+        */
+        read: function (response, context) {
+
+            if (response && assigned(response.body) && response.headers["Content-Type"]) {
+                dispatchHandler("read", response, context);
+            }
+        },
+
+        /** Write the body of the specified request by delegating to JSON handlers.
+        * @param request - Reques tobject.
+        * @param context - Operation context.
+        */
+        write: function (request, context) {
+
+            dispatchHandler("write", request, context);
+        },
+
+        maxDataServiceVersion: MAX_DATA_SERVICE_VERSION,
+        accept: "application/json;q=0.9, */*;q=0.1"
+    };
+
+exports.defaultMetadata = []; //TODO check why is the defaultMetadata an Array? and not an Object.
+
+/** Reads data from the specified URL.
+ * @param urlOrRequest - URL to read data from.
+ * @param {Function} [success] - 
+ * @param {Function} [error] - 
+ * @param {Object} [handler] - 
+ * @param {Object} [httpClient] - 
+ * @param {Object} [metadata] - 
+ */
+exports.read = function (urlOrRequest, success, error, handler, httpClient, metadata) {
+
+    var request;
+    if (urlOrRequest instanceof String || typeof urlOrRequest === "string") {
+        request = { requestUri: urlOrRequest };
+    } else {
+        request = urlOrRequest;
+    }
+
+    return exports.request(request, success, error, handler, httpClient, metadata);
+};
+
+/** Sends a request containing OData payload to a server.
+ * @param {Object} request - Object that represents the request to be sent.
+ * @param {Function} [success] - 
+ * @param {Function} [error] - 
+ * @param {Object} [handler] - 
+ * @param {Object} [httpClient] - 
+ * @param {Object} [metadata] - 
+ */
+exports.request = function (request, success, error, handler, httpClient, metadata) {
+
+    success = success || exports.defaultSuccess;
+    error = error || exports.defaultError;
+    handler = handler || exports.defaultHandler;
+    httpClient = httpClient || odataNet.defaultHttpClient;
+    metadata = metadata || exports.defaultMetadata;
+
+    // Augment the request with additional defaults.
+    request.recognizeDates = utils.defined(request.recognizeDates, odataJson.jsonHandler.recognizeDates);
+    request.callbackParameterName = utils.defined(request.callbackParameterName, odataNet.defaultHttpClient.callbackParameterName);
+    request.formatQueryString = utils.defined(request.formatQueryString, odataNet.defaultHttpClient.formatQueryString);
+    request.enableJsonpCallback = utils.defined(request.enableJsonpCallback, odataNet.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 {
+        odataUtils.prepareRequest(request, handler, context);
+        return odataUtils.invokeRequest(request, success, error, handler, httpClient, context);
+    } catch (err) {
+        // errors in success handler for sync requests are catched here and result in error handler calls. 
+        // So here we fix this and throw that error further.
+        if (err.bIsSuccessHandlerError) {
+            throw err;
+        } else {
+            error(err);
+        }
+    }
+
+};
+
+/** Parses the csdl metadata to ODataJS metatdata format. This method can be used when the metadata is retrieved using something other than odatajs
+ * @param {string} csdlMetadataDocument - A string that represents the entire csdl metadata.
+ * @returns {Object} An object that has the representation of the metadata in odatajs format.
+ */
+exports.parseMetadata = function (csdlMetadataDocument) {
+
+    return metadataParser(null, csdlMetadataDocument);
+};
+
+// Configure the batch handler to use the default handler for the batch parts.
+exports.batch.batchHandler.partHandler = exports.defaultHandler;
+exports.metadataHandler =  odataMetadata.metadataHandler;
+exports.jsonHandler =  odataJson.jsonHandler;

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/odata/batch.js
----------------------------------------------------------------------
diff --git a/lib/odata/batch.js b/lib/odata/batch.js
new file mode 100644
index 0000000..d33ac53
--- /dev/null
+++ b/lib/odata/batch.js
@@ -0,0 +1,377 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+/** @module odata/batch */
+
+var utils    = require('./../utils.js');
+var odataUtils    = require('./odatautils.js');
+var odataHandler = require('./handler.js');
+
+var extend = utils.extend;
+var isArray = utils.isArray;
+var trimString = utils.trimString;
+
+var contentType = odataHandler.contentType;
+var handler = odataHandler.handler;
+var isBatch = odataUtils.isBatch;
+var MAX_DATA_SERVICE_VERSION = odataHandler.MAX_DATA_SERVICE_VERSION;
+var normalizeHeaders = odataUtils.normalizeHeaders;
+//TODO var payloadTypeOf = odata.payloadTypeOf;
+var prepareRequest = odataUtils.prepareRequest;
+
+
+// Imports
+
+// CONTENT START
+var batchMediaType = "multipart/mixed";
+var responseStatusRegex = /^HTTP\/1\.\d (\d{3}) (.*)$/i;
+var responseHeaderRegex = /^([^()<>@,;:\\"\/[\]?={} \t]+)\s?:\s?(.*)/;
+
+/** Calculates a random 16 bit number and returns it in hexadecimal format.
+ * @returns {String} A 16-bit number in hex format.
+ */
+function hex16() {
+
+    return Math.floor((1 + Math.random()) * 0x10000).toString(16).substr(1);
+}
+
+/** Creates a string that can be used as a multipart request boundary.
+ * @param {String} [prefix] - 
+ * @returns {String} Boundary string of the format: <prefix><hex16>-<hex16>-<hex16>
+ */
+function createBoundary(prefix) {
+
+    return prefix + hex16() + "-" + hex16() + "-" + hex16();
+}
+
+/** Gets the handler for data serialization of individual requests / responses in a batch.
+ * @param context - Context used for data serialization.
+ * @returns Handler object
+ */
+function partHandler(context) {
+
+    return context.handler.partHandler;
+}
+
+/** Gets the current boundary used for parsing the body of a multipart response.
+ * @param context - Context used for parsing a multipart response.
+ * @returns {String} Boundary string.
+ */
+function currentBoundary(context) {
+    var boundaries = context.boundaries;
+    return boundaries[boundaries.length - 1];
+}
+
+/** Parses a batch response.
+ * @param handler - This handler.
+ * @param {String} text - Batch text.
+ * @param {Object} context - Object with parsing context.
+ * @return An object representation of the batch.
+ */
+function batchParser(handler, text, context) {
+
+    var boundary = context.contentType.properties["boundary"];
+    return { __batchResponses: readBatch(text, { boundaries: [boundary], handlerContext: context }) };
+}
+
+/** Serializes a batch object representation into text.
+ * @param handler - This handler.
+ * @param {Object} data - Representation of a batch.
+ * @param {Object} context - Object with parsing context.
+ * @return An text representation of the batch object; undefined if not applicable.#
+ */
+function batchSerializer(handler, data, context) {
+
+    var cType = context.contentType = context.contentType || contentType(batchMediaType);
+    if (cType.mediaType === batchMediaType) {
+        return writeBatch(data, context);
+    }
+}
+
+/** Parses a multipart/mixed response body from from the position defined by the context.
+ * @param {String}  text - Body of the multipart/mixed response.
+ * @param context - Context used for parsing.
+ * @return Array of objects representing the individual responses.
+ */
+function readBatch(text, context) {
+    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 = null;
+
+    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;
+}
+
+/** Parses the http headers in the text from the position defined by the context.
+ * @param {String} text - Text containing an http response's headers
+ * @param context - Context used for parsing.
+ * @returns Object containing the headers as key value pairs.
+ * This function doesn't support split headers and it will stop reading when it hits two consecutive line breaks.
+*/
+function readHeaders(text, context) {
+    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;
+}
+
+/** Parses an HTTP response.
+ * @param {String} text -Text representing the http response.
+ * @param context optional - Context used for parsing.
+ * @param {String} delimiter -String used as delimiter of the multipart response parts.
+ * @return Object representing the http response.
+ */
+function readResponse(text, context, delimiter) {
+    // 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)
+    };
+}
+
+/** Returns a substring from the position defined by the context up to the next line break (CRLF).
+ * @param {String} text - Input string.
+ * @param context - Context used for reading the input string.
+ * @returns {String} Substring to the first ocurrence of a line break or null if none can be found. 
+ */
+function readLine(text, context) {
+
+    return readTo(text, context, "\r\n");
+}
+
+/** 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.
+ * @param {String} text - Input string.
+ * @param context - Context used for reading the input string.
+ * @param {String} [str] - Substring to read up to.
+ * @returns {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.
+ */
+function readTo(text, context, str) {
+    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);
+}
+
+/** Serializes a batch request object to a string.
+ * @param data - Batch request object in payload representation format
+ * @param context - Context used for the serialization
+ * @returns {String} String representing the batch request
+ */
+function writeBatch(data, context) {
+    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;
+}
+
+/** Creates the delimiter that indicates that start or end of an individual request.
+ * @param {String} boundary Boundary string used to indicate the start of the request
+ * @param {Boolean} close - Flag indicating that a close delimiter string should be generated
+ * @returns {String} Delimiter string
+ */
+function writeBatchPartDelimiter(boundary, close) {
+    var result = "\r\n--" + boundary;
+    if (close) {
+        result += "--";
+    }
+
+    return result + "\r\n";
+}
+
+/** 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.
+ * @param part - Request or change set object in payload representation format
+ * @param context - Object containing context information used for the serialization
+ * @param {boolean} [nested] - 
+ * @returns {String} String representing the serialized part
+ * A change set is an array of request objects and they cannot be nested inside other change sets.
+ */
+function writeBatchPart(part, context, nested) {
+    
+
+    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;
+}
+
+/** Serializes a request object to a string.
+ * @param request - Request object to serialize
+ * @returns {String} String representing the serialized request
+ */
+function writeRequest(request) {
+    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;
+}
+
+
+
+/** batchHandler (see {@link module:odata/batch~batchParser}) */
+exports.batchHandler = handler(batchParser, batchSerializer, batchMediaType, MAX_DATA_SERVICE_VERSION);
+
+/** batchSerializer (see {@link module:odata/batch~batchSerializer}) */
+exports.batchSerializer = batchSerializer;
+
+/** writeRequest (see {@link module:odata/batch~writeRequest}) */
+exports.writeRequest = writeRequest;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/odata/handler.js
----------------------------------------------------------------------
diff --git a/lib/odata/handler.js b/lib/odata/handler.js
new file mode 100644
index 0000000..4c7260a
--- /dev/null
+++ b/lib/odata/handler.js
@@ -0,0 +1,284 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+/** @module odata/handler */
+
+
+var utils    = require('./../utils.js');
+var oDataUtils    = require('./odatautils.js');
+
+// Imports.
+var assigned = utils.assigned;
+var extend = utils.extend;
+var trimString = utils.trimString;
+var maxVersion = oDataUtils.maxVersion;
+var MAX_DATA_SERVICE_VERSION = "4.0";
+
+/** Parses a string into an object with media type and properties.
+ * @param {String} str - String with media type to parse.
+ * @return null if the string is empty; an object with 'mediaType' and a 'properties' dictionary otherwise.
+ */
+function contentType(str) {
+
+    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 };
+}
+
+/** Serializes an object with media type and properties dictionary into a string.
+ * @param contentType - Object with media type and properties dictionary to serialize.
+ * @return String representation of the media type object; undefined if contentType is null or undefined.
+ */
+function contentTypeToString(contentType) {
+    if (!contentType) {
+        return undefined;
+    }
+
+    var result = contentType.mediaType;
+    var property;
+    for (property in contentType.properties) {
+        result += ";" + property + "=" + contentType.properties[property];
+    }
+    return result;
+}
+
+/** Creates an object that is going to be used as the context for the handler's parser and serializer.
+ * @param contentType - Object with media type and properties dictionary.
+ * @param {String} dataServiceVersion - String indicating the version of the protocol to use.
+ * @param context - Operation context.
+ * @param handler - Handler object that is processing a resquest or response.
+ * @return Context object.
+ */
+function createReadWriteContext(contentType, dataServiceVersion, context, handler) {
+
+    var rwContext = {};
+    extend(rwContext, context);
+    extend(rwContext, {
+        contentType: contentType,
+        dataServiceVersion: dataServiceVersion,
+        handler: handler
+    });
+
+    return rwContext;
+}
+
+/** 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.
+ * @param request - Request object on which the header will be set.
+ * @param {String} name - Header name.
+ * @param {String} value - Header value.
+ */
+function fixRequestHeader(request, name, value) {
+    if (!request) {
+        return;
+    }
+
+    var headers = request.headers;
+    if (!headers[name]) {
+        headers[name] = value;
+    }
+}
+
+/** Sets the DataServiceVersion header of the request if its value is not yet defined or of a lower version.
+ * @param request - Request object on which the header will be set.
+ * @param {String} version - Version value.
+ *  If the request has already a version value higher than the one supplied the this function does nothing.
+ */
+function fixDataServiceVersionHeader(request, version) {   
+
+    if (request) {
+        var headers = request.headers;
+        var dsv = headers["OData-Version"];
+        headers["OData-Version"] = dsv ? maxVersion(dsv, version) : version;
+    }
+}
+
+/** Gets the value of a request or response header.
+ * @param requestOrResponse - Object representing a request or a response.
+ * @param {String} name - Name of the header to retrieve.
+ * @returns {String} String value of the header; undefined if the header cannot be found.
+ */
+function getRequestOrResponseHeader(requestOrResponse, name) {
+
+    var headers = requestOrResponse.headers;
+    return (headers && headers[name]) || undefined;
+}
+
+/** Gets the value of the Content-Type header from a request or response.
+ * @param requestOrResponse - Object representing a request or a response.
+ * @returns {Object} Object with 'mediaType' and a 'properties' dictionary; null in case that the header is not found or doesn't have a value.
+ */
+function getContentType(requestOrResponse) {
+
+    return contentType(getRequestOrResponseHeader(requestOrResponse, "Content-Type"));
+}
+
+var versionRE = /^\s?(\d+\.\d+);?.*$/;
+/** Gets the value of the DataServiceVersion header from a request or response.
+ * @param requestOrResponse - Object representing a request or a response.
+ * @returns {String} Data service version; undefined if the header cannot be found.
+ */
+function getDataServiceVersion(requestOrResponse) {
+
+    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.
+}
+
+/** Checks that a handler can process a particular mime type.
+ * @param handler - Handler object that is processing a resquest or response.
+ * @param cType - Object with 'mediaType' and a 'properties' dictionary.
+ * @returns {Boolean} True if the handler can process the mime type; false otherwise.
+ *
+ * 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.
+ */
+function handlerAccepts(handler, cType) {
+    return handler.accept.indexOf(cType.mediaType) >= 0;
+}
+
+/** Invokes the parser associated with a handler for reading the payload of a HTTP response.
+ * @param handler - Handler object that is processing the response.
+ * @param {Function} parseCallback - Parser function that will process the response payload.
+ * @param response - HTTP response whose payload is going to be processed.
+ * @param context - Object used as the context for processing the response.
+ * @returns {Boolean} True if the handler processed the response payload and the response.data property was set; false otherwise.
+ */
+function handlerRead(handler, parseCallback, response, context) {
+
+    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;
+}
+
+/** Invokes the serializer associated with a handler for generating the payload of a HTTP request.
+ * @param handler - Handler object that is processing the request.
+ * @param {Function} serializeCallback - Serializer function that will generate the request payload.
+ * @param request - HTTP request whose payload is going to be generated.
+ * @param context - Object used as the context for serializing the request.
+ * @returns {Boolean} True if the handler serialized the request payload and the request.body property was set; false otherwise.
+ */
+function handlerWrite(handler, serializeCallback, request, context) {
+    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;
+}
+
+/** Creates a handler object for processing HTTP requests and responses.
+ * @param {Function} parseCallback - Parser function that will process the response payload.
+ * @param {Function} serializeCallback - Serializer function that will generate the request payload.
+ * @param {String} accept - String containing a comma separated list of the mime types that this handler can work with.
+ * @param {String} maxDataServiceVersion - String indicating the highest version of the protocol that this handler can work with.
+ * @returns {Object} Handler object.
+ */
+function handler(parseCallback, serializeCallback, accept, maxDataServiceVersion) {
+
+    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);
+        }
+    };
+}
+
+function textParse(handler, body /*, context */) {
+    return body;
+}
+
+function textSerialize(handler, data /*, context */) {
+    if (assigned(data)) {
+        return data.toString();
+    } else {
+        return undefined;
+    }
+}
+
+
+
+
+exports.textHandler = handler(textParse, textSerialize, "text/plain", MAX_DATA_SERVICE_VERSION);
+exports.contentType = contentType;
+exports.contentTypeToString = contentTypeToString;
+exports.handler = handler;
+exports.createReadWriteContext = createReadWriteContext;
+exports.fixRequestHeader = fixRequestHeader;
+exports.getRequestOrResponseHeader = getRequestOrResponseHeader;
+exports.getContentType = getContentType;
+exports.getDataServiceVersion = getDataServiceVersion;
+exports.MAX_DATA_SERVICE_VERSION = MAX_DATA_SERVICE_VERSION;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/odata/json.js
----------------------------------------------------------------------
diff --git a/lib/odata/json.js b/lib/odata/json.js
new file mode 100644
index 0000000..f00b54c
--- /dev/null
+++ b/lib/odata/json.js
@@ -0,0 +1,1008 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/** @module odata/json */
+
+
+
+var utils        = require('./../utils.js');
+var oDataUtils   = require('./odatautils.js');
+var oDataHandler = require('./handler.js');
+
+var odataNs = "odata";
+var odataAnnotationPrefix = odataNs + ".";
+var contextUrlAnnotation = "@" + odataAnnotationPrefix + "context";
+
+var assigned = utils.assigned;
+var defined = utils.defined;
+var isArray = utils.isArray;
+//var isDate = utils.isDate;
+var isObject = utils.isObject;
+//var normalizeURI = utils.normalizeURI;
+var parseInt10 = utils.parseInt10;
+var getFormatKind = utils.getFormatKind;
+var convertByteArrayToHexString = utils.convertByteArrayToHexString;
+
+
+var formatDateTimeOffset = oDataUtils.formatDateTimeOffset;
+var formatDuration = oDataUtils.formatDuration;
+var formatNumberWidth = oDataUtils.formatNumberWidth;
+var getCanonicalTimezone = oDataUtils.getCanonicalTimezone;
+var handler = oDataUtils.handler;
+var isComplex = oDataUtils.isComplex;
+var isPrimitive = oDataUtils.isPrimitive;
+var isCollectionType = oDataUtils.isCollectionType;
+var lookupComplexType = oDataUtils.lookupComplexType;
+var lookupEntityType = oDataUtils.lookupEntityType;
+var lookupSingleton = oDataUtils.lookupSingleton;
+var lookupEntitySet = oDataUtils.lookupEntitySet;
+var lookupDefaultEntityContainer = oDataUtils.lookupDefaultEntityContainer;
+var lookupProperty = oDataUtils.lookupProperty;
+var MAX_DATA_SERVICE_VERSION = oDataUtils.MAX_DATA_SERVICE_VERSION;
+var maxVersion = oDataUtils.maxVersion;
+
+var isPrimitiveEdmType = oDataUtils.isPrimitiveEdmType;
+var isGeographyEdmType = oDataUtils.isGeographyEdmType;
+var isGeometryEdmType = oDataUtils.isGeometryEdmType;
+
+var PAYLOADTYPE_FEED = "f";
+var PAYLOADTYPE_ENTRY = "e";
+var PAYLOADTYPE_PROPERTY = "p";
+var PAYLOADTYPE_COLLECTION = "c";
+var PAYLOADTYPE_ENUMERATION_PROPERTY = "enum";
+var PAYLOADTYPE_SVCDOC = "s";
+var PAYLOADTYPE_ENTITY_REF_LINK = "erl";
+var PAYLOADTYPE_ENTITY_REF_LINKS = "erls";
+
+var PAYLOADTYPE_VALUE = "v";
+
+var PAYLOADTYPE_DELTA = "d";
+var DELTATYPE_FEED = "f";
+var DELTATYPE_DELETED_ENTRY = "de";
+var DELTATYPE_LINK = "l";
+var DELTATYPE_DELETED_LINK = "dl";
+
+var jsonMediaType = "application/json";
+var jsonContentType = oDataHandler.contentType(jsonMediaType);
+
+var jsonSerializableMetadata = ["@odata.id", "@odata.type"];
+
+
+
+
+
+/** Extend JSON OData payload with metadata
+ * @param handler - This handler.
+ * @param text - Payload text (this parser also handles pre-parsed objects).
+ * @param {Object} context - Object with parsing context.
+ * @return An object representation of the OData payload.
+ */
+function jsonParser(handler, text, context) {
+    var recognizeDates = defined(context.recognizeDates, handler.recognizeDates);
+    var model = context.metadata;
+    var json = (typeof text === "string") ? JSON.parse(text) : text;
+    var metadataContentType;
+    if (assigned(context.contentType) && assigned(context.contentType.properties)) {
+        metadataContentType = context.contentType.properties["odata.metadata"]; //TODO convert to lower before comparism
+    }
+
+    var payloadFormat = getFormatKind(metadataContentType, 1); // none: 0, minimal: 1, full: 2
+
+    // No errors should be throw out if we could not parse the json payload, instead we should just return the original json object.
+    if (payloadFormat === 0) {
+        return json;
+    }
+    else if (payloadFormat === 1) {
+        return addMinimalMetadataToJsonPayload(json, model, recognizeDates);
+    }
+    else if (payloadFormat === 2) {
+        // to do: using the EDM Model to get the type of each property instead of just guessing.
+        return addFullMetadataToJsonPayload(json, model, recognizeDates);
+    }
+    else {
+        return json;
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// 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+)?\)\/$/;
+
+
+// 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 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;
+    }
+};
+
+/** Serializes a ODataJs payload structure to the wire format which can be send to the server
+ * @param handler - This handler.
+ * @param data - Data to serialize.
+ * @param {Object} context - Object with serialization context.
+ * @returns {String} The string representation of data.
+ */
+function jsonSerializer(handler, data, context) {
+
+    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 = formatJsonRequestPayload(data);
+        if (newdata) {
+            return JSON.stringify(newdata,jsonReplacer);
+        }
+    }
+    return undefined;
+}
+
+
+
+
+/** Convert OData objects for serialisation in to a new data structure
+ * @param data - Data to serialize.
+ * @returns {String} The string representation of data.
+ */
+function formatJsonRequestPayload(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] = formatJsonRequestPayload(data[i]);
+        }
+
+        return newArrayData;
+    }
+
+    var newdata = {};
+    for (var property in data) {
+        if (isJsonSerializableProperty(property)) {
+            newdata[property] = formatJsonRequestPayload(data[property]);
+        }
+    }
+
+    return newdata;
+}
+
+/** Determine form the attribute name if the attribute is a serializable property
+ * @param attribute
+ * @returns {boolean}
+ */
+function isJsonSerializableProperty(attribute) {
+    if (!attribute) {
+        return false;
+    }
+
+    if (attribute.indexOf("@odata.") == -1) {
+        return true;
+    }
+
+    var i, len;
+    for (i = 0, len = jsonSerializableMetadata.length; i < len; i++) {
+        var name = jsonSerializableMetadata[i];
+        if (attribute.indexOf(name) != -1) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+/** Creates an object containing information for the json payload.
+ * @param {String} kind - JSON payload kind
+ * @param {String} type - Type name of the JSON payload.
+ * @returns {Object} Object with kind and type fields.
+ */
+function jsonMakePayloadInfo(kind, type) {
+    return { kind: kind, type: type || null };
+}
+
+
+
+/** Add metadata to an JSON payload complex object containing full metadata
+ * @param {Object} data - Data structure to be extended
+ * @param {Object} model - Metadata model
+ * @param {Boolean} recognizeDates - Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.
+ */
+function addFullMetadataToJsonPayload(data, model, recognizeDates) {
+    var type;
+    if (utils.isObject(data)) {
+        for (var key in data) {
+            if (data.hasOwnProperty(key)) {
+                if (key.indexOf('@') === -1) {
+                    if (utils.isArray(data[key])) {
+                        for (var i = 0; i < data[key].length; ++i) {
+                            addFullMetadataToJsonPayload(data[key][i], model, recognizeDates);
+                        }
+                    } else if (utils.isObject(data[key])) {
+                        if (data[key] !== null) {
+                            //don't step into geo.. objects
+                            type = data[key+'@odata.type'];
+                            if (!type) {
+                                //type unknown
+                                addFullMetadataToJsonPayload(data[key], model, recognizeDates);
+                            } else {
+                                type = type.substring(1);
+                                if  (isGeographyEdmType(type) || isGeometryEdmType(type)) {
+                                    // don't add type info for geo* types
+                                } else {
+                                    addFullMetadataToJsonPayload(data[key], model, recognizeDates);
+                                }
+                            }
+                        }
+                    } else {
+                        type = data[key + '@odata.type'];
+
+                        // On .Net OData library, some basic EDM type is omitted, e.g. Edm.String, Edm.Int, and etc.
+                        // For the full metadata payload, we need to full fill the @data.type for each property if it is missing.
+                        // We do this is to help the OlingoJS consumers to easily get the type of each property.
+                        if (!assigned(type)) {
+                            // Guessing the "type" from the type of the value is not the right way here.
+                            // To do: we need to get the type from metadata instead of guessing.
+                            var typeFromObject = typeof data[key];
+                            if (typeFromObject === 'string') {
+                                addType(data, key, 'String');
+                            } else if (typeFromObject === 'boolean') {
+                                addType(data, key, 'Boolean');
+                            } else if (typeFromObject === 'number') {
+                                if (data[key] % 1 === 0) { // has fraction
+                                    addType(data, key, 'Int32'); // the biggst integer
+                                } else {
+                                    addType(data, key, 'Decimal'); // the biggst float single,doulbe,decimal
+                                }
+                            }
+                        }
+                        else {
+                            if (recognizeDates) {
+                                convertDatesNoEdm(data, key, type.substring(1));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return data;
+}
+
+/** Loop through the properties of an JSON payload object, look up the type info of the property and call
+ * the appropriate add*MetadataToJsonPayloadObject function
+ * @param {Object} data - Data structure to be extended
+ * @param {String} objectInfoType - Information about the data (name,type,typename,...)
+ * @param {String} baseURI - Base Url
+ * @param {Object} model - Metadata model
+ * @param {Boolean} recognizeDates - Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.
+ */
+function checkProperties(data, objectInfoType, baseURI, model, recognizeDates) {
+    for (var name in data) {
+        if (name.indexOf("@") === -1) {
+            var curType = objectInfoType;
+            var propertyValue = data[name];
+            var property = lookupProperty(curType.property,name); //TODO SK add check for parent type
+
+            while (( property === null) && (curType.baseType !== undefined)) {
+                curType = lookupEntityType(curType.baseType, model);
+                property = lookupProperty(curType.property,name);
+            }
+
+            if ( isArray(propertyValue)) {
+                //data[name+'@odata.type'] = '#' + property.type;
+                if (isCollectionType(property.type)) {
+                    addTypeColNoEdm(data,name,property.type.substring(11,property.type.length-1));
+                } else {
+                    addTypeNoEdm(data,name,property.type);
+                }
+
+
+                for ( var i = 0; i < propertyValue.length; i++) {
+                    addMetadataToJsonMinimalPayloadComplex(propertyValue[i], property, baseURI, model, recognizeDates);
+                }
+            } else if (isObject(propertyValue) && (propertyValue !== null)) {
+                addMetadataToJsonMinimalPayloadComplex(propertyValue, property, baseURI, model, recognizeDates);
+            } else {
+                //data[name+'@odata.type'] = '#' + property.type;
+                addTypeNoEdm(data,name,property.type);
+                if (recognizeDates) {
+                    convertDates(data, name, property.type);
+                }
+            }
+        }
+    }
+}
+
+
+
+/** Add metadata to an JSON payload object containing minimal metadata
+ * @param {Object} data - Json response payload object
+ * @param {Object} model - Object describing an OData conceptual schema
+ * @param {Boolean} recognizeDates - Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.
+ * @returns {Object} Object in the library's representation.
+ */
+function addMinimalMetadataToJsonPayload(data, model, recognizeDates) {
+
+    if (!assigned(model) || isArray(model)) {
+        return data;
+    }
+
+    var baseURI = data[contextUrlAnnotation];
+    var payloadInfo = createPayloadInfo(data, model);
+
+    switch (payloadInfo.detectedPayloadKind) {
+
+        case PAYLOADTYPE_VALUE:
+            if (payloadInfo.type !== null) {
+                return addMetadataToJsonMinimalPayloadEntity(data, payloadInfo, baseURI, model, recognizeDates);
+            } else {
+                return addTypeNoEdm(data,'value', payloadInfo.typeName);
+            }
+
+        case PAYLOADTYPE_FEED:
+            return addMetadataToJsonMinimalPayloadFeed(data, model, payloadInfo, baseURI, recognizeDates);
+
+        case PAYLOADTYPE_ENTRY:
+            return addMetadataToJsonMinimalPayloadEntity(data, payloadInfo, baseURI, model, recognizeDates);
+
+        case PAYLOADTYPE_COLLECTION:
+            return addMetadataToJsonMinimalPayloadCollection(data, model, payloadInfo, baseURI, recognizeDates);
+
+        case PAYLOADTYPE_PROPERTY:
+            if (payloadInfo.type !== null) {
+                return addMetadataToJsonMinimalPayloadEntity(data, payloadInfo, baseURI, model, recognizeDates);
+            } else {
+                return addTypeNoEdm(data,'value', payloadInfo.typeName);
+            }
+
+        case PAYLOADTYPE_SVCDOC:
+            return data;
+
+        case PAYLOADTYPE_LINKS:
+            return data;
+    }
+
+    return data;
+}
+
+/** Add metadata to an JSON payload feed object containing minimal metadata
+ * @param {Object} data - Data structure to be extended
+ * @param {Object} model - Metadata model
+ * @param {String} feedInfo - Information about the data (name,type,typename,...)
+ * @param {String} baseURI - Base Url
+ * @param {Boolean} recognizeDates - Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.
+ */
+function addMetadataToJsonMinimalPayloadFeed(data, model, feedInfo, baseURI, recognizeDates) {
+    var entries = [];
+    var items = data.value;
+    var i,len;
+    var entry;
+    for (i = 0, len = items.length; i < len; i++) {
+        var item = items[i];
+        if ( defined(item['@odata.type'])) { // in case of mixed feeds
+            var typeName = item['@odata.type'].substring(1);
+            var type = lookupEntityType( typeName, model);
+            var entryInfo = {
+                contentTypeOdata : feedInfo.contentTypeOdata,
+                detectedPayloadKind : feedInfo.detectedPayloadKind,
+                name : feedInfo.name,
+                type : type,
+                typeName : typeName
+            };
+
+            entry = addMetadataToJsonMinimalPayloadEntity(item, entryInfo, baseURI, model, recognizeDates);
+        } else {
+            entry = addMetadataToJsonMinimalPayloadEntity(item, feedInfo, baseURI, model, recognizeDates);
+        }
+
+        entries.push(entry);
+    }
+    data.value = entries;
+    return data;
+}
+
+
+/** Add metadata to an JSON payload entity object containing minimal metadata
+ * @param {Object} data - Data structure to be extended
+ * @param {String} objectInfo - Information about the data (name,type,typename,...)
+ * @param {String} baseURI - Base Url
+ * @param {Object} model - Metadata model
+ * @param {Boolean} recognizeDates - Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.
+ */
+function addMetadataToJsonMinimalPayloadEntity(data, objectInfo, baseURI, model, recognizeDates) {
+    addType(data,'',objectInfo.typeName);
+
+    var keyType = objectInfo.type;
+    while ((defined(keyType)) && ( keyType.key === undefined) && (keyType.baseType !== undefined)) {
+        keyType = lookupEntityType(keyType.baseType, model);
+    }
+
+    if (keyType.key !== undefined) {
+        var lastIdSegment = objectInfo.name + jsonGetEntryKey(data, keyType);
+        data['@odata.id'] = baseURI.substring(0, baseURI.lastIndexOf("$metadata")) + lastIdSegment;
+        data['@odata.editLink'] = lastIdSegment;
+    }
+
+    //var serviceURI = baseURI.substring(0, baseURI.lastIndexOf("$metadata"));
+
+    checkProperties(data, objectInfo.type, baseURI, model, recognizeDates);
+
+    return data;
+}
+
+/** Add metadata to an JSON payload complex object containing minimal metadata
+ * @param {Object} data - Data structure to be extended
+ * @param {String} property - Information about the data (name,type,typename,...)
+ * @param {String} baseURI - Base Url
+ * @param {Object} model - Metadata model
+ * @param {Boolean} recognizeDates - Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.
+ */
+function addMetadataToJsonMinimalPayloadComplex(data, property, baseURI, model, recognizeDates) {
+    var type = property.type;
+    if (isCollectionType(property.type)) {
+        type =property.type.substring(11,property.type.length-1);
+    }
+
+    addType(data,'',property.type);
+
+    var propertyType = lookupComplexType(type, model);
+    if (propertyType === null)  {
+        return; //TODO check what to do if the type is not known e.g. type #GeometryCollection
+    }
+
+    checkProperties(data, propertyType, baseURI, model, recognizeDates);
+}
+
+/** Add metadata to an JSON payload collection object containing minimal metadata
+ * @param {Object} data - Data structure to be extended
+ * @param {Object} model - Metadata model
+ * @param {String} collectionInfo - Information about the data (name,type,typename,...)
+ * @param {String} baseURI - Base Url
+ * @param {Boolean} recognizeDates - Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.
+ */
+function addMetadataToJsonMinimalPayloadCollection(data, model, collectionInfo, baseURI, recognizeDates) {
+
+    addTypeColNoEdm(data,'', collectionInfo.typeName);
+
+    if (collectionInfo.type !== null) {
+        var entries = [];
+
+        var items = data.value;
+        var i,len;
+        var entry;
+        for (i = 0, len = items.length; i < len; i++) {
+            var item = items[i];
+            if ( defined(item['@odata.type'])) { // in case of mixed collections
+                var typeName = item['@odata.type'].substring(1);
+                var type = lookupEntityType( typeName, model);
+                var entryInfo = {
+                    contentTypeOdata : collectionInfo.contentTypeOdata,
+                    detectedPayloadKind : collectionInfo.detectedPayloadKind,
+                    name : collectionInfo.name,
+                    type : type,
+                    typeName : typeName
+                };
+
+                entry = addMetadataToJsonMinimalPayloadEntity(item, entryInfo, baseURI, model, recognizeDates);
+            } else {
+                entry = addMetadataToJsonMinimalPayloadEntity(item, collectionInfo, baseURI, model, recognizeDates);
+            }
+
+            entries.push(entry);
+        }
+        data.value = entries;
+    }
+    return data;
+}
+
+/** Add an OData type tag to an JSON payload object
+ * @param {Object} data - Data structure to be extended
+ * @param {String} name - Name of the property whose type is set
+ * @param {String} value - Type name
+ */
+function addType(data, name, value ) {
+    var fullName = name + '@odata.type';
+
+    if ( data[fullName] === undefined) {
+        data[fullName] = '#' + value;
+    }
+}
+
+/** Add an OData type tag to an JSON payload object collection (without "Edm." namespace)
+ * @param {Object} data - Data structure to be extended
+ * @param {String} name - Name of the property whose type is set
+ * @param {String} typeName - Type name
+ */
+function addTypeColNoEdm(data, name, typeName ) {
+    var fullName = name + '@odata.type';
+
+    if ( data[fullName] === undefined) {
+        if ( typeName.substring(0,4)==='Edm.') {
+            data[fullName] = '#Collection('+typeName.substring(4)+ ')';
+        } else {
+            data[fullName] = '#Collection('+typeName+ ')';
+        }
+    }
+}
+
+
+/** Add an OData type tag to an JSON payload object (without "Edm." namespace)
+ * @param {Object} data - Data structure to be extended
+ * @param {String} name - Name of the property whose type is set
+ * @param {String} value - Type name
+ */
+function addTypeNoEdm(data, name, value ) {
+    var fullName = name + '@odata.type';
+
+    if ( data[fullName] === undefined) {
+        if ( value.substring(0,4)==='Edm.') {
+            data[fullName] = '#' + value.substring(4);
+        } else {
+            data[fullName] = '#' + value;
+        }
+    }
+    return data;
+}
+/** Convert the date/time format of an property from the JSON payload object (without "Edm." namespace)
+ * @param {Object} data - Data structure to be extended
+ * @param propertyName - Name of the property to be changed
+ * @param type - Type
+ */
+function convertDates(data, propertyName,type) {
+    if (type === 'Edm.Date') {
+        data[propertyName] = oDataUtils.parseDate(data[propertyName], true);
+    } else if (type === 'Edm.DateTimeOffset') {
+        data[propertyName] = oDataUtils.parseDateTimeOffset(data[propertyName], true);
+    } else if (type === 'Edm.Duration') {
+        data[propertyName] = oDataUtils.parseDuration(data[propertyName], true);
+    } else if (type === 'Edm.Time') {
+        data[propertyName] = oDataUtils.parseTime(data[propertyName], true);
+    }
+}
+
+/** Convert the date/time format of an property from the JSON payload object
+ * @param {Object} data - Data structure to be extended
+ * @param propertyName - Name of the property to be changed
+ * @param type - Type
+ */
+function convertDatesNoEdm(data, propertyName,type) {
+    if (type === 'Date') {
+        data[propertyName] = oDataUtils.parseDate(data[propertyName], true);
+    } else if (type === 'DateTimeOffset') {
+        data[propertyName] = oDataUtils.parseDateTimeOffset(data[propertyName], true);
+    } else if (type === 'Duration') {
+        data[propertyName] = oDataUtils.parseDuration(data[propertyName], true);
+    } else if (type === 'Time') {
+        data[propertyName] = oDataUtils.parseTime(data[propertyName], true);
+    }
+}
+
+/** Formats a value according to Uri literal format
+ * @param value - Value to be formatted.
+ * @param type - Edm type of the value
+ * @returns {string} Value after formatting
+ */
+function formatLiteral(value, type) {
+
+    value = "" + formatRawLiteral(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;
+    }
+}
+
+/** convert raw byteArray to hexString if the property is an binary property
+ * @param value - Value to be formatted.
+ * @param type - Edm type of the value
+ * @returns {string} Value after formatting
+ */
+function formatRawLiteral(value, type) {
+    switch (type) {
+        case "Edm.Binary":
+            return convertByteArrayToHexString(value);
+        default:
+            return value;
+    }
+}
+
+/** Formats the given minutes into (+/-)hh:mm format.
+ * @param {Number} minutes - Number of minutes to format.
+ * @returns {String} The minutes in (+/-)hh:mm format.
+ */
+function minutesToOffset(minutes) {
+
+    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);
+}
+
+/** Parses the JSON Date representation into a Date object.
+ * @param {String} value - String value.
+ * @returns {Date} A Date object if the value matches one; falsy otherwise.
+ */
+function parseJsonDateString(value) {
+
+    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.
+}
+
+/** Creates an object containing information for the context
+ * @param {String} fragments - Uri fragment
+ * @param {Object} model - Object describing an OData conceptual schema
+ * @returns {Object} type(optional)  object containing type information for entity- and complex-types ( null if a typeName is a primitive)
+ */
+function parseContextUriFragment( fragments, model ) {
+    var ret = {};
+
+    if (fragments.indexOf('/') === -1 ) {
+        if (fragments.length === 0) {
+            // Capter 10.1
+            ret.detectedPayloadKind = PAYLOADTYPE_SVCDOC;
+            return ret;
+        } else if (fragments === 'Edm.Null') {
+            // Capter 10.15
+            ret.detectedPayloadKind = PAYLOADTYPE_VALUE;
+            ret.isNullProperty = true;
+            return ret;
+        } else if (fragments === 'Collection($ref)') {
+            // Capter 10.11
+            ret.detectedPayloadKind = PAYLOADTYPE_ENTITY_REF_LINKS;
+            return ret;
+        } else if (fragments === '$ref') {
+            // Capter 10.12
+            ret.detectedPayloadKind = PAYLOADTYPE_ENTITY_REF_LINK;
+            return ret;
+        } else {
+            //TODO check for navigation resource
+        }
+    }
+
+    ret.type = undefined;
+    ret.typeName = undefined;
+
+    var fragmentParts = fragments.split("/");
+    var type;
+
+    for(var i = 0; i < fragmentParts.length; ++i) {
+        var fragment = fragmentParts[i];
+        if (ret.typeName === undefined) {
+            //preparation
+            if ( fragment.indexOf('(') !== -1 ) {
+                //remove the query function, cut fragment to matching '('
+                var index = fragment.length - 2 ;
+                for ( var rCount = 1; rCount > 0 && index > 0; --index) {
+                    if ( fragment.charAt(index)=='(') {
+                        rCount --;
+                    } else if ( fragment.charAt(index)==')') {
+                        rCount ++;
+                    }
+                }
+
+                if (index === 0) {
+                    //TODO throw error
+                }
+
+                //remove the projected entity from the fragment; TODO decide if we want to store the projected entity
+                var inPharenthesis = fragment.substring(index+2,fragment.length - 1);
+                fragment = fragment.substring(0,index+1);
+
+                if (utils.startsWith(fragment, 'Collection')) {
+                    ret.detectedPayloadKind = PAYLOADTYPE_COLLECTION;
+                    // Capter 10.14
+                    ret.typeName = inPharenthesis;
+
+                    type = lookupEntityType(ret.typeName, model);
+                    if ( type !== null) {
+                        ret.type = type;
+                        continue;
+                    }
+                    type = lookupComplexType(ret.typeName, model);
+                    if ( type !== null) {
+                        ret.type = type;
+                        continue;
+                    }
+
+                    ret.type = null;//in case of #Collection(Edm.String) only lastTypeName is filled
+                    continue;
+                } else {
+                    // projection: Capter 10.7, 10.8 and 10.9
+                    ret.projection = inPharenthesis;
+                }
+            }
+
+
+            if (jsonIsPrimitiveType(fragment)) {
+                ret.typeName = fragment;
+                ret.type = null;
+                ret.detectedPayloadKind = PAYLOADTYPE_VALUE;
+                continue;
+            }
+
+            var container = lookupDefaultEntityContainer(model);
+
+            //check for entity
+            var entitySet = lookupEntitySet(container.entitySet, fragment);
+            if ( entitySet !== null) {
+                ret.typeName = entitySet.entityType;
+                ret.type = lookupEntityType( ret.typeName, model);
+                ret.name = fragment;
+                ret.detectedPayloadKind = PAYLOADTYPE_FEED;
+                // Capter 10.2
+                continue;
+            }
+
+            //check for singleton
+            var singleton = lookupSingleton(container.singleton, fragment);
+            if ( singleton !== null) {
+                ret.typeName = singleton.entityType;
+                ret.type = lookupEntityType( ret.typeName, model);
+                ret.name = fragment;
+                ret.detectedPayloadKind =  PAYLOADTYPE_ENTRY;
+                // Capter 10.4
+                continue;
+            }
+
+
+
+            //TODO throw ERROR
+        } else {
+            //check for $entity
+            if (utils.endsWith(fragment, '$entity') && (ret.detectedPayloadKind === PAYLOADTYPE_FEED)) {
+                //TODO ret.name = fragment;
+                ret.detectedPayloadKind = PAYLOADTYPE_ENTRY;
+                // Capter 10.3 and 10.6
+                continue;
+            }
+
+            //check for derived types
+            if (fragment.indexOf('.') !== -1) {
+                // Capter 10.6
+                ret.typeName = fragment;
+                type = lookupEntityType(ret.typeName, model);
+                if ( type !== null) {
+                    ret.type = type;
+                    continue;
+                }
+                type = lookupComplexType(ret.typeName, model);
+                if ( type !== null) {
+                    ret.type = type;
+                    continue;
+                }
+
+                //TODO throw ERROR invalid type
+            }
+
+            //check for property value
+            if ( ret.detectedPayloadKind === PAYLOADTYPE_FEED || ret.detectedPayloadKind === PAYLOADTYPE_ENTRY) {
+                var property = lookupProperty(ret.type.property, fragment);
+                if (property !== null) {
+                    //PAYLOADTYPE_COLLECTION
+                    ret.typeName = property.type;
+
+
+                    if (utils.startsWith(property.type, 'Collection')) {
+                        ret.detectedPayloadKind = PAYLOADTYPE_COLLECTION;
+                        var tmp12 =  property.type.substring(10+1,property.type.length - 1);
+                        ret.typeName = tmp12;
+                        ret.type = lookupComplexType(tmp12, model);
+                        ret.detectedPayloadKind = PAYLOADTYPE_COLLECTION;
+                    } else {
+                        ret.type = lookupComplexType(property.type, model);
+                        ret.detectedPayloadKind = PAYLOADTYPE_PROPERTY;
+                    }
+
+                    ret.name = fragment;
+                    // Capter 10.15
+                }
+                continue;
+            }
+
+            if (fragment === '$delta') {
+                ret.deltaKind = DELTATYPE_FEED;
+                continue;
+            } else if (utils.endsWith(fragment, '/$deletedEntity')) {
+                ret.deltaKind = DELTATYPE_DELETED_ENTRY;
+                continue;
+            } else if (utils.endsWith(fragment, '/$link')) {
+                ret.deltaKind = DELTATYPE_LINK;
+                continue;
+            } else if (utils.endsWith(fragment, '/$deletedLink')) {
+                ret.deltaKind = DELTATYPE_DELETED_LINK;
+                continue;
+            }
+            //TODO throw ERROr
+        }
+    }
+
+    return ret;
+}
+
+
+/** Infers the information describing the JSON payload from its metadata annotation, structure, and data model.
+ * @param {Object} data - Json response payload object.
+ * @param {Object} model - Object describing an OData conceptual schema.
+ * 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 payload.
+ * @return Object with kind and type fields. Null if there is no metadata annotation or the payload info cannot be obtained..
+ */
+function createPayloadInfo(data, model) {
+    var metadataUri = data[contextUrlAnnotation];
+    if (!metadataUri || typeof metadataUri !== "string") {
+        return null;
+    }
+
+    var fragmentStart = metadataUri.lastIndexOf("#");
+    if (fragmentStart === -1) {
+        return jsonMakePayloadInfo(PAYLOADTYPE_SVCDOC);
+    }
+
+    var fragment = metadataUri.substring(fragmentStart + 1);
+    return parseContextUriFragment(fragment,model);
+}
+/** Gets the key of an entry.
+ * @param {Object} data - JSON entry.
+ * @param {Object} data - EDM entity model for key loockup.
+ * @returns {string} Entry instance key.
+ */
+function jsonGetEntryKey(data, entityModel) {
+
+    var entityInstanceKey;
+    var entityKeys = entityModel.key[0].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;
+}
+/** Determines whether a type name is a primitive type in a JSON payload.
+ * @param {String} typeName - Type name to test.
+ * @returns {Boolean} True if the type name an EDM primitive type or an OData spatial type; false otherwise.
+ */
+function jsonIsPrimitiveType(typeName) {
+    return isPrimitiveEdmType(typeName) || isGeographyEdmType(typeName) || isGeometryEdmType(typeName);
+}
+
+
+var jsonHandler = oDataHandler.handler(jsonParser, jsonSerializer, jsonMediaType, MAX_DATA_SERVICE_VERSION);
+jsonHandler.recognizeDates = false;
+
+exports.createPayloadInfo = createPayloadInfo;
+exports.jsonHandler = jsonHandler;
+exports.jsonParser = jsonParser;
+exports.jsonSerializer = jsonSerializer;
+exports.parseJsonDateString = parseJsonDateString;
\ No newline at end of file


[8/8] olingo-odata4-js git commit: [OLINGO-442] Cleanup bevore release II and beta-name removal

Posted by ko...@apache.org.
[OLINGO-442] Cleanup bevore release II and beta-name removal


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/commit/27f830e6
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/tree/27f830e6
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/diff/27f830e6

Branch: refs/heads/master
Commit: 27f830e61e5f3af6e53fcc2fea412543c32b2d71
Parents: 4621d41
Author: Sven Kobler <sv...@sap.com>
Authored: Mon Mar 23 14:53:52 2015 +0100
Committer: Sven Kobler <sv...@sap.com>
Committed: Mon Mar 23 14:53:52 2015 +0100

----------------------------------------------------------------------
 .gitignore                        |    2 +-
 Gruntfile.js                      |    8 +-
 README.md                         |    4 +-
 grunt-config/custom-tasks/sign.js |    8 +-
 grunt-config/nugetpack.nuspec     |    2 +-
 grunt-config/rat-config.js        |    6 +-
 grunt-config/release-config.js    |    4 +-
 grunt-config/sign-config.js       |    6 +-
 index-browser.js                  |   36 +
 index.js                          |   47 ++
 lib/cache.js                      | 1445 ++++++++++++++++++++++++++++++++
 lib/cache/source.js               |  206 +++++
 lib/deferred.js                   |  190 +++++
 lib/odata.js                      |  180 ++++
 lib/odata/batch.js                |  377 +++++++++
 lib/odata/handler.js              |  284 +++++++
 lib/odata/json.js                 | 1008 ++++++++++++++++++++++
 lib/odata/metadata.js             |  523 ++++++++++++
 lib/odata/net-browser.js          |  344 ++++++++
 lib/odata/net.js                  |  195 +++++
 lib/odata/odatautils.js           | 1273 ++++++++++++++++++++++++++++
 lib/store.js                      |   67 ++
 lib/store/dom.js                  |  332 ++++++++
 lib/store/indexeddb.js            |  447 ++++++++++
 lib/store/memory.js               |  247 ++++++
 lib/utils.js                      |  581 +++++++++++++
 lib/xml.js                        |  824 ++++++++++++++++++
 package.json                      |    2 +-
 src/index-browser.js              |   36 -
 src/index-node.js                 |   47 --
 src/index.js                      |   47 --
 src/lib/cache.js                  | 1445 --------------------------------
 src/lib/cache/source.js           |  206 -----
 src/lib/deferred.js               |  190 -----
 src/lib/odata.js                  |  180 ----
 src/lib/odata/batch.js            |  377 ---------
 src/lib/odata/handler.js          |  284 -------
 src/lib/odata/json.js             | 1008 ----------------------
 src/lib/odata/metadata.js         |  523 ------------
 src/lib/odata/net-browser.js      |  344 --------
 src/lib/odata/net.js              |  195 -----
 src/lib/odata/odatautils.js       | 1273 ----------------------------
 src/lib/store.js                  |   67 --
 src/lib/store/dom.js              |  332 --------
 src/lib/store/indexeddb.js        |  447 ----------
 src/lib/store/memory.js           |  247 ------
 src/lib/utils.js                  |  581 -------------
 src/lib/xml.js                    |  824 ------------------
 test/test-demo-scenario.js        |    2 +-
 test/test-odata-json.js           |    2 +-
 test/test-utils.js                |    2 +-
 tests/node-test-setup.js          |    2 +-
 52 files changed, 8631 insertions(+), 8678 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 7ff281f..02c5d17 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,7 @@ _*
 localgrunt.config
 
 # testing copies
-../demo/scripts/odatajs-4.0.0-beta-01*
+../demo/scripts/odatajs-4.0.0-*
 
 # build artefacts
 #build/

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/Gruntfile.js
----------------------------------------------------------------------
diff --git a/Gruntfile.js b/Gruntfile.js
index 6bf2290..faff8d0 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -36,8 +36,8 @@ module.exports = function(grunt) {
 
     "toBrowser" : {
       "release" : {
-          options: { index : "src/index-browser.js" },
-          src: ["src/lib/**/*.js", '!**/*-node.*'], 
+          options: { index : "index-browser.js" },
+          src: ["lib/**/*.js", '!**/*-node.*'],
           dest: "_build/lib/<%= artifactname %>.js"
       }
     },
@@ -55,7 +55,7 @@ module.exports = function(grunt) {
     },
     "jsdoc" : {
       "src" : {
-          src: ["src/**/*.js"], 
+          src: ["index.js","lib/**/*.js"],
           options: { destination: "_build/doc-src", verbose : true, debug : true, pedantic : true }
       }
     },
@@ -135,7 +135,7 @@ module.exports = function(grunt) {
   ]);
 
   
-  grunt.registerTask('release_sign','Sign the files which are released (run "grunt release" before"',[
+  grunt.registerTask('release-sign','Sign the files which are released (run "grunt release" before"',[
     'sign:release','sign:asc','sign:asc-verify'
   ]);
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 83d0f68..62ee639 100644
--- a/README.md
+++ b/README.md
@@ -19,13 +19,13 @@ under the License.
 ## Olingo OData Client for JavaScript
 The Olingo OData Client for JavaScript (odatajs) is a library written in JavaScript that enables browser based frontend applications to easily use the OData protocol for communication with application servers.
 
-This library "odatajs-4.0.0-beta-01.min.js" supports only the OData V4 protocol.
+This library "odatajs-4.0.0.min.js" supports only the OData V4 protocol.
 
 For using the OData protocols V1-V3 please refer to the [datajs library](http://datajs.codeplex.com/)
 
 The odatajs library can be included in any html page with the script tag (for example)
 ```
-<script type="text/javascript" src="./sources/odatajs-4.0.0-beta-01.min.js"></script>
+<script type="text/javascript" src="./sources/odatajs-4.0.0.min.js"></script>
 ```
 and its features can be used through the `odatajs` namespace (or `window.odatajs`). The odatajs library can be used together with the datajs library which uses the `window.OData` namespace.
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/grunt-config/custom-tasks/sign.js
----------------------------------------------------------------------
diff --git a/grunt-config/custom-tasks/sign.js b/grunt-config/custom-tasks/sign.js
index 7f6319c..3db3f73 100644
--- a/grunt-config/custom-tasks/sign.js
+++ b/grunt-config/custom-tasks/sign.js
@@ -59,7 +59,7 @@ module.exports = function(grunt) {
                 pipeTo = workItem.src+'.md5';
 
                 grunt.log.writeln(chalk.yellow('Signing ('+workItem.type+') ' + fileName + " ..."));
-                //openssl dgst -md5 odatajs.4.0.0-beta01.nupkg
+                //openssl dgst -md5 odatajs.4.0.0.nupkg
                 taskOptions = { 
                     cmd : 'openssl', 
                     args: ['dgst','-md5',fileName],
@@ -70,7 +70,7 @@ module.exports = function(grunt) {
 
                 grunt.log.writeln(chalk.yellow('Signing ('+workItem.type+') ' + fileName + " ..."));
 
-                //gpg --print-md SHA512 odatajs-4.0.0-beta-01-RC02-doc.zip
+                //gpg --print-md SHA512 odatajs-4.0.0-doc.zip
                 taskOptions = { 
                     cmd : 'gpg', 
                     args: ['--print-md','SHA512',fileName],
@@ -81,7 +81,7 @@ module.exports = function(grunt) {
 
                 grunt.log.writeln(chalk.yellow('Signing ('+workItem.type+') ' + fileName + " ..."));
                 
-                //gpg --armor --detach-sign odatajs-4.0.0-beta-01-RC02-sources.zip
+                //gpg --armor --detach-sign odatajs-4.0.0-sources.zip
                 taskOptions = { 
                     cmd : 'gpg', 
                     args: ['--armor','--detach-sign',fileName],
@@ -93,7 +93,7 @@ module.exports = function(grunt) {
 
                 grunt.log.writeln(chalk.yellow('Verify ('+workItem.type+') ' +fileName+ '.asc' + " ..."));
                 
-                //gpg --verify --detach-sign odatajs-4.0.0-beta-01-RC02-sources.zip.asc 
+                //gpg --verify --detach-sign odatajs-4.0.0-sources.zip.asc
                 taskOptions = { 
                     cmd : 'gpg', 
                     args: ['--verify', fileName+'.asc'],

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/grunt-config/nugetpack.nuspec
----------------------------------------------------------------------
diff --git a/grunt-config/nugetpack.nuspec b/grunt-config/nugetpack.nuspec
index 120cd7d..a0c7861 100644
--- a/grunt-config/nugetpack.nuspec
+++ b/grunt-config/nugetpack.nuspec
@@ -4,7 +4,7 @@
     <title>Olingo OData Client for JavaScript</title>
     <id>odatajs</id>
     <tags>restful api open protocol odata client javascript</tags>
-    <version>4.0.0-beta01</version>
+    <version>4.0.0</version>
     <authors>Apache Olingo (Challen He, Kobler-Morris Sven)</authors>
     <owners>Apache Olingo</owners>
     <licenseUrl>http://www.apache.org/licenses/LICENSE-2.0</licenseUrl>

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/grunt-config/rat-config.js
----------------------------------------------------------------------
diff --git a/grunt-config/rat-config.js b/grunt-config/rat-config.js
index 23871ae..2ee5b77 100644
--- a/grunt-config/rat-config.js
+++ b/grunt-config/rat-config.js
@@ -1,4 +1,3 @@
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -17,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 module.exports = function(grunt) {
   
   
@@ -31,7 +31,7 @@ module.exports = function(grunt) {
         ] },
       files: [
         /*{ src: ['./../_dist/<%= artifactname %>/doc'], options:{ tag:"dist-doc"}},generated*/
-        { src: ['./src'], options:{ tag:"src"}},
+        { src: ['./lib'], options:{ tag:"lib"}},
         { src: ['./tests'], options:{ tag:"tests"}},
         { src: ['./demo'], options:{ tag:"demo"}},
         { src: ['./grunt-config'], options:{ tag:"grunt-config" }},
@@ -48,7 +48,7 @@ module.exports = function(grunt) {
           "JSLib.sln","package.json", "mocha.opts","info.txt"
         ] },
       files: [
-        { src: ['./src'], options:{ tag:"src"}},
+        { src: ['./lib'], options:{ tag:"lib"}},
         { src: ['./tests'], options:{ tag:"tests"}},
         { src: ['./demo'], options:{ tag:"demo"}},
         { src: ['./grunt-config'], options:{ tag:"grunt-config" }},

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/grunt-config/release-config.js
----------------------------------------------------------------------
diff --git a/grunt-config/release-config.js b/grunt-config/release-config.js
index 6865bb1..3df970e 100644
--- a/grunt-config/release-config.js
+++ b/grunt-config/release-config.js
@@ -48,7 +48,7 @@ module.exports = function(grunt) {
   grunt.config.merge( { 
     'jsdoc' : { // generate documentation
       "release-doc-src" : {
-        src: ['src/**/*.js'], 
+        src: ['**/*.js'],
         options: {
           destination: './_dist/<%= artifactname %>/doc',
           verbose : false 
@@ -71,7 +71,7 @@ module.exports = function(grunt) {
       },
       "release-nuget": {
           files: [
-              { expand: true, cwd: '_build', src: ['odatajs.4.0.0-beta01.nupkg'], dest: './_dist/<%= artifactname %>', filter: 'isFile' },
+              { expand: true, cwd: '_build', src: ['odatajs.4.0.0.nupkg'], dest: './_dist/<%= artifactname %>', filter: 'isFile' },
           ]
       },
       "release-doc" : {

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/grunt-config/sign-config.js
----------------------------------------------------------------------
diff --git a/grunt-config/sign-config.js b/grunt-config/sign-config.js
index a0ff676..6c827e3 100644
--- a/grunt-config/sign-config.js
+++ b/grunt-config/sign-config.js
@@ -28,7 +28,7 @@ module.exports = function(grunt) {
         cwd : './_dist/<%= artifactname %>/',
         src : [ 
           '<%= artifactname %>-lib.zip',
-          'odatajs.4.0.0-beta01.nupkg',
+          'odatajs.4.0.0.nupkg',
           '<%= artifactname %>-doc.zip',
           '<%= artifactname %>-sources.zip'
         ]
@@ -39,7 +39,7 @@ module.exports = function(grunt) {
         cwd : './_dist/<%= artifactname %>/',
         src : [ 
           '<%= artifactname %>-lib.zip',
-          'odatajs.4.0.0-beta01.nupkg',
+          'odatajs.4.0.0.nupkg',
           '<%= artifactname %>-doc.zip',
           '<%= artifactname %>-sources.zip'
         ]
@@ -50,7 +50,7 @@ module.exports = function(grunt) {
         cwd : './_dist/<%= artifactname %>/',
         src : [ 
           '<%= artifactname %>-lib.zip',
-          'odatajs.4.0.0-beta01.nupkg',
+          'odatajs.4.0.0.nupkg',
           '<%= artifactname %>-doc.zip',
           '<%= artifactname %>-sources.zip'
         ]

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/index-browser.js
----------------------------------------------------------------------
diff --git a/index-browser.js b/index-browser.js
new file mode 100644
index 0000000..0524487
--- /dev/null
+++ b/index-browser.js
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// version information 
+exports.version = { major: 4, minor: 0, build: 0 };
+
+// core stuff, always needed
+exports.deferred = require('./lib/deferred.js');
+exports.utils = require('./lib/utils.js');
+
+// only needed for xml metadata 
+exports.xml = require('./lib/xml.js');
+
+// only need in browser case
+exports.oData = require('./lib/odata.js');
+exports.store = require('./lib/store.js');
+exports.cache = require('./lib/cache.js');
+
+
+

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/index.js
----------------------------------------------------------------------
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..85aea5b
--- /dev/null
+++ b/index.js
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var odatajs = {};
+
+odatajs.version = {
+    major: 4,
+    minor: 0,
+    build: 0
+};
+
+// core stuff, alway needed
+odatajs.deferred = require('./lib/deferred.js');
+odatajs.utils = require('./lib/utils.js');
+
+// only neede for xml metadata
+odatajs.xml = require('./lib/xml.js');
+
+// only need in browser case
+odatajs.oData = require('./lib/odata.js');
+odatajs.store = require('./lib/store.js');
+odatajs.cache = require('./lib/cache.js');
+
+if (typeof window !== 'undefined') {
+    //expose to browsers window object
+    window.odatajs = odatajs;
+} else {
+    //expose in commonjs style
+    odatajs.node = "node";
+    module.exports = odatajs;
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/cache.js
----------------------------------------------------------------------
diff --git a/lib/cache.js b/lib/cache.js
new file mode 100644
index 0000000..dce74b6
--- /dev/null
+++ b/lib/cache.js
@@ -0,0 +1,1445 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+ /** @module cache */
+
+//var odatajs = require('./odatajs/utils.js');
+var utils =  require('./utils.js');
+var deferred = require('./deferred.js');
+var storeReq = require('./store.js');
+var cacheSource = require('./cache/source.js');
+
+
+var assigned = utils.assigned;
+var delay = utils.delay;
+var extend = utils.extend;
+var djsassert = utils.djsassert;
+var isArray = utils.isArray;
+var normalizeURI = utils.normalizeURI;
+var parseInt10 = utils.parseInt10;
+var undefinedDefault = utils.undefinedDefault;
+
+var createDeferred = deferred.createDeferred;
+var DjsDeferred = deferred.DjsDeferred;
+
+
+var getJsonValueArraryLength = utils.getJsonValueArraryLength;
+var sliceJsonValueArray = utils.sliceJsonValueArray;
+var concatJsonValueArray = utils.concatJsonValueArray;
+
+
+
+/** Appends a page's data to the operation data.
+ * @param {Object} operation - Operation with  (i)ndex, (c)ount and (d)ata.
+ * @param {Object} page - Page with (i)ndex, (c)ount and (d)ata.
+ */
+function appendPage(operation, page) {
+
+    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));
+}
+
+/** Returns the {(i)ndex, (c)ount} range for the intersection of x and y.
+ * @param {Object} x - Range with (i)ndex and (c)ount members.
+ * @param {Object} y - Range with (i)ndex and (c)ount members.
+ * @returns {Object} The intersection (i)ndex and (c)ount; undefined if there is no intersection.
+ */
+function intersectRanges(x, y) {
+
+    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;
+}
+
+/** Checks whether val is a defined number with value zero or greater.
+ * @param {Number} val - Value to check.
+ * @param {String} name - Parameter name to use in exception.
+ * @throws Throws an exception if the check fails
+ */
+function checkZeroGreater(val, name) {
+
+    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." };
+    }
+}
+
+/** Checks whether val is undefined or a number with value greater than zero.
+ * @param {Number} val - Value to check.
+ * @param {String} name - Parameter name to use in exception.
+ * @throws Throws an exception if the check fails
+ */
+function checkUndefinedGreaterThanZero(val, name) {
+
+    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." };
+        }
+    }
+}
+
+/** Checks whether val is undefined or a number
+ * @param {Number} val - Value to check.
+ * @param {String} name - Parameter name to use in exception.
+ * @throws Throws an exception if the check fails
+ */
+function checkUndefinedOrNumber(val, name) {
+    if (val !== undefined && (typeof val !== "number" || isNaN(val) || !isFinite(val))) {
+        throw { message: "'" + name + "' must be a number." };
+    }
+}
+
+/** Performs a linear search on the specified array and removes the first instance of 'item'.
+ * @param {Array} arr - Array to search.
+ * @param {*} item - Item being sought.
+ * @returns {Boolean} true if the item was removed otherwise false
+ */
+function removeFromArray(arr, item) {
+
+    var i, len;
+    for (i = 0, len = arr.length; i < len; i++) {
+        if (arr[i] === item) {
+            arr.splice(i, 1);
+            return true;
+        }
+    }
+
+    return false;
+}
+
+/** Estimates the size of an object in bytes.
+ * Object trees are traversed recursively
+ * @param {Object} object - Object to determine the size of.
+ * @returns {Number} Estimated size of the object in bytes.
+ */
+function estimateSize(object) {
+    var size = 0;
+    var type = typeof object;
+
+    if (type === "object" && object) {
+        for (var name in object) {
+            size += name.length * 2 + estimateSize(object[name]);
+        }
+    } else if (type === "string") {
+        size = object.length * 2;
+    } else {
+        size = 8;
+    }
+    return size;
+}
+
+/** Snaps low and high indices into page sizes and returns a range.
+ * @param {Number} lowIndex - Low index to snap to a lower value.
+ * @param {Number} highIndex - High index to snap to a higher value.
+ * @param {Number} pageSize - Page size to snap to.
+ * @returns {Object} A range with (i)ndex and (c)ount of elements.
+ */
+function snapToPageBoundaries(lowIndex, highIndex, pageSize) {
+    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.
+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";
+
+/** Creates a new operation object.
+ * @class DataCacheOperation
+ * @param {Function} stateMachine - State machine that describes the specific behavior of the operation.
+ * @param {DjsDeferred} promise - Promise for requested values.
+ * @param {Boolean} isCancelable - Whether this operation can be canceled or not.
+ * @param {Number} index - Index of first item requested.
+ * @param {Number} count - Count of items requested.
+ * @param {Array} data - Array with the items requested by the operation.
+ * @param {Number} pending - Total number of pending prefetch records.
+ * @returns {DataCacheOperation} A new data cache operation instance.
+ */
+function DataCacheOperation(stateMachine, promise, isCancelable, index, count, data, pending) {
+
+   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;
+
+    /** Transitions this operation to the cancel state and sets the canceled flag to true.
+     * The function is a no-op if the operation is non-cancelable.
+     * @method DataCacheOperation#cancel
+     */
+    that.cancel = function cancel() {
+
+        if (!isCancelable) {
+            return;
+        }
+
+        var state = that.s;
+        if (state !== OPERATION_STATE_ERROR && state !== OPERATION_STATE_END && state !== OPERATION_STATE_CANCEL) {
+            that.canceled = true;
+            that.transition(OPERATION_STATE_CANCEL, stateData);
+        }
+    };
+
+    /** Transitions this operation to the end state.
+     * @method DataCacheOperation#complete
+     */
+    that.complete = function () {
+
+        djsassert(that.s !== OPERATION_STATE_END, "DataCacheOperation.complete() - operation is in the end state", that);
+        that.transition(OPERATION_STATE_END, stateData);
+    };
+
+    /** Transitions this operation to the error state.
+     * @method DataCacheOperation#error
+     */
+    that.error = function (err) {
+        if (!that.canceled) {
+            djsassert(that.s !== OPERATION_STATE_END, "DataCacheOperation.error() - operation is in the end state", that);
+            djsassert(that.s !== OPERATION_STATE_ERROR, "DataCacheOperation.error() - operation is in the error state", that);
+            that.transition(OPERATION_STATE_ERROR, err);
+        }
+    };
+
+    /** Executes the operation's current state in the context of a new cache state.
+     * @method DataCacheOperation#run
+     * @param {Object} state - New cache state.
+     */
+    that.run = function (state) {
+
+        cacheState = state;
+        that.transition(that.s, stateData);
+    };
+
+    /** Transitions this operation to the wait state.
+     * @method DataCacheOperation#wait
+     */
+    that.wait = function (data) {
+
+        djsassert(that.s !== OPERATION_STATE_END, "DataCacheOperation.wait() - operation is in the end state", that);
+        that.transition(OPERATION_STATE_WAIT, data);
+    };
+
+    /** State machine that describes all operations common behavior.
+     * @method DataCacheOperation#operationStateMachine
+     * @param {Object} opTargetState - Operation state to transition to.
+     * @param {Object} cacheState - Current cache state.
+     * @param {Object} [data] - Additional data passed to the state.
+     */
+    var operationStateMachine = function (opTargetState, cacheState, data) {
+
+        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();
+                that.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);
+                that.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.
+
+                if (true) {
+                    // Check that the state machine actually handled the sate.
+                    var handled = stateMachine(that, opTargetState, cacheState, data);
+                    djsassert(handled, "Bad operation state: " + opTargetState + " cacheState: " + cacheState, this);
+                } else {
+
+                    stateMachine(that, opTargetState, cacheState, data);
+
+                }
+
+                break;
+        }
+    };
+
+
+
+    /** Transitions this operation to a new state.
+     * @method DataCacheOperation#transition
+     * @param {Object} state - State to transition the operation to.
+     * @param {Object} [data] - 
+     */
+    that.transition = function (state, data) {
+        that.s = state;
+        stateData = data;
+        operationStateMachine(state, cacheState, data);
+    };
+    
+    return that;
+}
+
+/** Fires a resolved notification as necessary.
+ * @method DataCacheOperation#fireResolved
+ */
+DataCacheOperation.prototype.fireResolved = function () {
+
+    // Fire the resolve just once.
+    var p = this.p;
+    if (p) {
+        this.p = null;
+        p.resolve(this.d);
+    }
+};
+
+/** Fires a rejected notification as necessary.
+ * @method DataCacheOperation#fireRejected
+ */
+DataCacheOperation.prototype.fireRejected = function (reason) {
+
+    // Fire the rejection just once.
+    var p = this.p;
+    if (p) {
+        this.p = null;
+        p.reject(reason);
+    }
+};
+
+/** Fires a canceled notification as necessary.
+ * @method DataCacheOperation#fireCanceled
+ */
+DataCacheOperation.prototype.fireCanceled = function () {
+
+    this.fireRejected({ canceled: true, message: "Operation canceled" });
+};
+
+
+/** Creates a data cache for a collection that is efficiently loaded on-demand.
+ * @class DataCache
+ * @param options - Options for the data cache, including name, source, pageSize,
+ * prefetchSize, cacheSize, storage mechanism, and initial prefetch and local-data handler.
+ * @returns {DataCache} A new data cache instance.
+ */
+function DataCache(options) {
+
+    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 cacheSource.ODataCacheSource(options);
+    }
+    source.options = options;
+
+    // Create a cache local store.
+    var store = storeReq.createStore(options.name, options.mechanism);
+
+    var that = this;
+
+    that.onidle = options.idle;
+    that.stats = stats;
+
+    /** Counts the number of items in the collection.
+     * @method DataCache#count
+     * @returns {Object} A promise with the number of items.
+     */
+    that.count = function () {
+
+        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(), {
+
+             /** Aborts the count operation (used within promise callback)
+              * @method DataCache#cancelCount
+              */
+            cancel: function () {
+               
+                if (request) {
+                    canceled = true;
+                    request.abort();
+                    request = null;
+                }
+            }
+        });
+    };
+
+    /** Cancels all running operations and clears all local data associated with this cache.
+     * 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.
+     * @method DataCache#clear
+     * @returns {Object} A promise that has no value and can't be canceled.
+     */
+    that.clear = function () {
+
+        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;
+    };
+
+    /** Filters the cache data based a predicate.
+     * Specifying a negative count value will yield all the items in the cache that satisfy the predicate.
+     * @method DataCache#filterForward
+     * @param {Number} index - The index of the item to start filtering forward from.
+     * @param {Number} count - Maximum number of items to include in the result.
+     * @param {Function} predicate - Callback function returning a boolean that determines whether an item should be included in the result or not.
+     * @returns {DjsDeferred} A promise for an array of results.
+     */
+    that.filterForward = function (index, count, predicate) {
+        return filter(index, count, predicate, false);
+    };
+
+    /** Filters the cache data based a predicate.
+     * Specifying a negative count value will yield all the items in the cache that satisfy the predicate.
+     * @method DataCache#filterBack
+     * @param {Number} index - The index of the item to start filtering backward from.
+     * @param {Number} count - Maximum number of items to include in the result.
+     * @param {Function} predicate - Callback function returning a boolean that determines whether an item should be included in the result or not.
+     * @returns {DjsDeferred} A promise for an array of results.
+     */
+    that.filterBack = function (index, count, predicate) {
+        return filter(index, count, predicate, true);
+    };
+
+    /** Reads a range of adjacent records.
+     * 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.
+     * @method DataCache#readRange
+     * @param {Number} index - Zero-based index of record range to read.
+     * @param {Number} count - Number of records in the range.
+     * @returns {DjsDeferred} A promise for an array of records; less records may be returned if the
+     * end of the collection is found.
+     */
+    that.readRange = function (index, count) {
+
+        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 () {
+                /** Aborts the readRange operation  (used within promise callback)
+                 * @method DataCache#cancelReadRange
+                 */
+                op.cancel();
+            }
+        });
+    };
+
+    /** Creates an Observable object that enumerates all the cache contents.
+     * @method DataCache#toObservable
+     * @returns A new Observable object that enumerates all the cache contents.
+     */
+    that.ToObservable = that.toObservable = function () {
+        if ( !utils.inBrowser()) {
+            throw { message: "Only in broser supported" };
+        }
+
+        if (!window.Rx || !window.Rx.Observable) {
+            throw { message: "Rx library not available - include rx.js" };
+        }
+
+        if (cacheFailure) {
+            throw cacheFailure;
+        }
+
+        //return window.Rx.Observable.create(function (obs) {
+        return new window.Rx.Observable(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.next(data.value[i]);
+                        obs.onNext(data.value[i]);
+                    }
+
+                    if (data.value.length < pageSize) {
+                        //obs.completed();
+                        obs.onCompleted();
+                    } else {
+                        index += pageSize;
+                        that.readRange(index, pageSize).then(successCallback, errorCallback);
+                    }
+                }
+            };
+
+            that.readRange(index, pageSize).then(successCallback, errorCallback);
+
+            return { Dispose: function () { 
+                obs.dispose(); // otherwise the check isStopped obs.onNext(data.value[i]);
+                disposed = true; 
+                } };
+        });
+    };
+
+    /** Creates a function that handles a callback by setting the cache into failure mode.
+     * @method DataCache~cacheFailureCallback
+     * @param {String} message - Message text.
+     * @returns {Function} Function to use as error callback.
+     * This function will specifically handle problems with critical store resources
+     * during cache initialization.
+     */
+    var cacheFailureCallback = function (message) {
+        
+
+        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.
+            djsassert(prefetchOperations.length === 0, "prefetchOperations.length === 0");
+            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;
+        };
+    };
+
+    /** Updates the cache's state and signals all pending operations of the change.
+     * @method DataCache~changeState
+     * @param {Object} newState - New cache state.
+     * This method is a no-op if the cache's current state and the new state are the same.
+     */
+    var changeState = function (newState) {
+
+        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);
+            }
+        }
+    };
+
+    /** Removes all the data stored in the cache.
+     * @method DataCache~clearStore
+     * @returns {DjsDeferred} A promise with no value.
+     */
+    var clearStore = function () {
+        djsassert(state === CACHE_STATE_DESTROY || state === CACHE_STATE_INIT, "DataCache.clearStore() - cache is not on the destroy or initialize state, current sate = " + state);
+
+        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;
+    };
+
+    /** Removes an operation from the caches queues and changes the cache state to idle.
+     * @method DataCache~dequeueOperation
+     * @param {DataCacheOperation} operation - Operation to dequeue.
+     * This method is used as a handler for the operation's oncomplete event.
+    */
+    var dequeueOperation = function (operation) {
+
+        var removed = removeFromArray(clearOperations, operation);
+        if (!removed) {
+            removed = removeFromArray(readOperations, operation);
+            if (!removed) {
+                removeFromArray(prefetchOperations, operation);
+            }
+        }
+
+        pendingOperations--;
+        changeState(CACHE_STATE_IDLE);
+    };
+
+    /** Requests data from the cache source.
+     * @method DataCache~fetchPage
+     * @param {Number} start - Zero-based index of items to request.
+     * @returns {DjsDeferred} A promise for a page object with (i)ndex, (c)ount, (d)ata.
+     */
+    var fetchPage = function (start) {
+
+        djsassert(state !== CACHE_STATE_DESTROY, "DataCache.fetchPage() - cache is on the destroy state");
+        djsassert(state !== CACHE_STATE_IDLE, "DataCache.fetchPage() - cache is on the idle state");
+
+        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;
+                }
+            }
+        });
+    };
+
+    /** Filters the cache data based a predicate.
+     * @method DataCache~filter
+     * @param {Number} index - The index of the item to start filtering from.
+     * @param {Number} count - Maximum number of items to include in the result.
+     * @param {Function} predicate - Callback function returning a boolean that determines whether an item should be included in the result or not.
+     * @param {Boolean} backwards - True if the filtering should move backward from the specified index, falsey otherwise.
+     * Specifying a negative count value will yield all the items in the cache that satisfy the predicate.
+     * @returns {DjsDeferred} A promise for an array of results.
+     */
+    var filter = function (index, count, predicate, backwards) {
+
+        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(), {
+            /** Aborts the filter operation (used within promise callback)
+            * @method DataCache#cancelFilter
+             */
+            cancel: function () {
+
+                if (pendingReadRange) {
+                    pendingReadRange.cancel();
+                }
+                canceled = true;
+            }
+        });
+    };
+
+    /** Fires an onidle event if any functions are assigned.
+     * @method DataCache~fireOnIdle
+    */
+    var fireOnIdle = function () {
+
+        if (that.onidle && pendingOperations === 0) {
+            that.onidle();
+        }
+    };
+
+    /** Creates and starts a new prefetch operation.
+     * @method DataCache~prefetch
+     * @param {Number} start - Zero-based index of the items to prefetch.
+     * 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).
+    */
+    var prefetch = function (start) {
+        
+
+        if (allDataLocal || prefetchSize === 0 || overflowed) {
+            return;
+        }
+
+        djsassert(state === CACHE_STATE_READ, "DataCache.prefetch() - cache is not on the read state, current state: " + state);
+
+        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);
+        }
+    };
+
+    /** Queues an operation and runs it.
+     * @param {DataCacheOperation} op - Operation to queue.
+     * @param {Array} queue - Array that will store the operation.
+     */
+    var queueAndStart = function (op, queue) {
+
+        op.oncomplete = dequeueOperation;
+        queue.push(op);
+        pendingOperations++;
+        op.run(state);
+    };
+
+    /** Requests a page from the cache local store.
+     * @method DataCache~readPage    
+     * @param {Number} key - Zero-based index of the reuqested page.
+     * @returns {DjsDeferred} A promise for a found flag and page object with (i)ndex, (c)ount, (d)ata, and (t)icks.
+     */
+    var readPage = function (key) {
+
+        djsassert(state !== CACHE_STATE_DESTROY, "DataCache.readPage() - cache is on the destroy state");
+
+        var canceled = false;
+        var deferred = extend(new DjsDeferred(), {
+            /** Aborts the readPage operation. (used within promise callback)
+             * @method DataCache#cancelReadPage
+             */
+            cancel: function () {
+                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;
+    };
+
+    /** Saves a page to the cache local store.
+     * @method DataCache~savePage    
+     * @param {Number} key - Zero-based index of the requested page.
+     * @param {Object} page - Object with (i)ndex, (c)ount, (d)ata, and (t)icks.
+     * @returns {DjsDeferred} A promise with no value.
+     */
+    var savePage = function (key, page) {
+
+        djsassert(state !== CACHE_STATE_DESTROY, "DataCache.savePage() - cache is on the destroy state");
+        djsassert(state !== CACHE_STATE_IDLE, "DataCache.savePage() - cache is on the idle state");
+
+        var canceled = false;
+
+        var deferred = extend(new DjsDeferred(), {
+            /** Aborts the savePage operation. (used within promise callback)
+             * @method DataCache#cancelReadPage
+             */
+            cancel: function () {
+                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;
+    };
+
+    /** Saves the cache's current settings to the local store.
+     * @method DataCache~saveSettings    
+     * @param {Function} success - Success callback.
+     * @param {Function} error - Errror callback.
+     */
+    var saveSettings = function (success, error) {
+
+        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);
+    };
+
+    /** Creates a function that handles a store error.
+     * @method DataCache~storeFailureCallback    
+     * @param {DjsDeferred} deferred - Deferred object to resolve.
+     * @returns {Function} Function to use as error callback.
+    
+     * This function will specifically handle problems when interacting with the store.
+     */
+    var storeFailureCallback = function (deferred/*, message*/) {
+        
+
+        return function (/*error*/) {
+            // var console = windo1w.console;
+            // if (console && console.log) {
+            //    console.log(message);
+            //    console.dir(error);
+            // }
+            deferred.resolve(false);
+        };
+    };
+
+    /** Updates the cache's settings based on a page object.
+     * @method DataCache~updateSettings    
+     * @param {Object} page - Object with (i)ndex, (c)ount, (d)ata.
+     * @param {Number} pageBytes - Size of the page in bytes.
+     */
+    var updateSettings = function (page, pageBytes) {
+
+        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;
+        }
+    };
+
+    /** State machine describing the behavior for cancelling a read or prefetch operation.
+     * @method DataCache~cancelStateMachine    
+     * @param {DataCacheOperation} operation - Operation being run.
+     * @param {Object} opTargetState - Operation state to transition to.
+     * @param {Object} cacheState - Current cache state.
+     * @param {Object} [data] - 
+     * This state machine contains behavior common to read and prefetch operations.
+     */
+    var cancelStateMachine = function (operation, opTargetState, cacheState, data) {
+        
+
+        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;
+    };
+
+    /** State machine describing the behavior of a clear operation.
+     * @method DataCache~destroyStateMachine    
+     * @param {DataCacheOperation} operation - Operation being run.
+     * @param {Object} opTargetState - Operation state to transition to.
+     * @param {Object} cacheState - Current cache state.
+    
+     * Clear operations have the highest priority and can't be interrupted by other operations; however,
+     * they will preempt any other operation currently executing.
+     */
+    var destroyStateMachine = function (operation, opTargetState, cacheState) {
+        
+
+        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;
+    };
+
+    /** State machine describing the behavior of a prefetch operation.
+     * @method DataCache~prefetchStateMachine    
+     * @param {DataCacheOperation} operation - Operation being run.
+     * @param {Object} opTargetState - Operation state to transition to.
+     * @param {Object} cacheState - Current cache state.
+     * @param {Object} [data] - 
+    
+     *  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.
+     */
+    var prefetchStateMachine = function (operation, opTargetState, cacheState, data) {
+        
+
+        // 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;
+    };
+
+    /** State machine describing the behavior of a read operation.
+     * @method DataCache~readStateMachine    
+     * @param {DataCacheOperation} operation - Operation being run.
+     * @param {Object} opTargetState - Operation state to transition to.
+     * @param {Object} cacheState - Current cache state.
+     * @param {Object} [data] - 
+    
+     * 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.
+     */
+    var readStateMachine = function (operation, opTargetState, cacheState, data) {
+        
+
+        // 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.
+                    djsassert(state == CACHE_STATE_IDLE || state === CACHE_STATE_PREFETCH, "DataCache.readStateMachine() - cache is not on the read or idle state.");
+                    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;
+    };
+
+    /** State machine describing the behavior for reading and saving data into the cache.
+     * @method DataCache~readSaveStateMachine    
+     * @param {DataCacheOperation} operation - Operation being run.
+     * @param {Object} opTargetState - Operation state to transition to.
+     * @param {Object} cacheState - Current cache state.
+     * @param {Object} [data] - 
+     * @param {Boolean} isPrefetch - Flag indicating whether a read (false) or prefetch (true) operation is running.
+     * This state machine contains behavior common to read and prefetch operations.
+    */
+    var readSaveStateMachine = function (operation, opTargetState, cacheState, data, isPrefetch) {
+
+        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;
+}
+
+/** Creates a data cache for a collection that is efficiently loaded on-demand.
+ * @param options 
+ * Options for the data cache, including name, source, pageSize, TODO check doku
+ * prefetchSize, cacheSize, storage mechanism, and initial prefetch and local-data handler.
+ * @returns {DataCache} A new data cache instance.
+ */
+function createDataCache (options) {
+    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);
+}
+
+
+/** estimateSize (see {@link estimateSize}) */
+exports.estimateSize = estimateSize;
+
+/** createDataCache */  
+exports.createDataCache = createDataCache;
+
+
+

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/cache/source.js
----------------------------------------------------------------------
diff --git a/lib/cache/source.js b/lib/cache/source.js
new file mode 100644
index 0000000..08dea0a
--- /dev/null
+++ b/lib/cache/source.js
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+ /** @module cache/source */
+ 
+var utils = require("./../utils.js");
+var odataRequest = require("./../odata.js");
+
+var parseInt10 = utils.parseInt10;
+var normalizeURICase = utils.normalizeURICase;
+
+
+
+
+/** Appends the specified escaped query option to the specified URI.
+ * @param {String} uri - URI to append option to.
+ * @param {String} queryOption - Escaped query option to append.
+ */
+function appendQueryOption(uri, queryOption) {
+    var separator = (uri.indexOf("?") >= 0) ? "&" : "?";
+    return uri + separator + queryOption;
+}
+
+/** Appends the specified segment to the given URI.
+ * @param {String} uri - URI to append a segment to.
+ * @param {String} segment - Segment to append.
+ * @returns {String} The original URI with a new segment appended.
+ */
+function appendSegment(uri, segment) {
+    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;
+}
+
+/** Builds a request object to GET the specified URI.
+ * @param {String} uri - URI for request.
+ * @param {Object} options - Additional options.
+ */
+function buildODataRequest(uri, options) {
+    return {
+        method: "GET",
+        requestUri: uri,
+        user: options.user,
+        password: options.password,
+        enableJsonpCallback: options.enableJsonpCallback,
+        callbackParameterName: options.callbackParameterName,
+        formatQueryString: options.formatQueryString
+    };
+}
+
+/** Finds the index where the value of a query option starts.
+ * @param {String} uri - URI to search in.
+ * @param {String} name - Name to look for.
+ * @returns {Number} The index where the query option starts.
+ */
+function findQueryOptionStart(uri, name) {
+    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;
+}
+
+/** Gets data from an OData service.
+ * @param {String} uri - URI to the OData service.
+ * @param {Object} options - Object with additional well-known request options.
+ * @param {Function} success - Success callback.
+ * @param {Function} error - Error callback.
+ * @returns {Object} Object with an abort method.
+ */
+function queryForData (uri, options, success, error) {
+    return queryForDataInternal(uri, options, {}, success, error);
+}
+
+/** Gets data from an OData service taking into consideration server side paging.
+ * @param {String} uri - URI to the OData service.
+ * @param {Object} options - Object with additional well-known request options.
+ * @param {Array} data - Array that stores the data provided by the OData service.
+ * @param {Function} success - Success callback.
+ * @param {Function} error - Error callback.
+ * @returns {Object} Object with an abort method.
+ */
+function queryForDataInternal(uri, options, data, success, error) {
+
+    var request = buildODataRequest(uri, options);
+    var currentRequest = odataRequest.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();
+        }
+    };
+}
+
+/** Creates a data cache source object for requesting data from an OData service.
+ * @class ODataCacheSource
+ * @param options - Options for the cache data source.
+ * @returns {ODataCacheSource} A new data cache source instance.
+ */
+function ODataCacheSource (options) {
+    var that = this;
+    var uri = options.source;
+    
+    that.identifier = normalizeURICase(encodeURI(decodeURI(uri)));
+    that.options = options;
+
+    /** Gets the number of items in the collection.
+     * @method ODataCacheSource#count
+     * @param {Function} success - Success callback with the item count.
+     * @param {Function} error - Error callback.
+     * @returns {Object} Request object with an abort method.
+     */
+    that.count = function (success, error) {
+        var options = that.options;
+        return odataRequest.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
+        );
+    };
+    
+    /** Gets a number of consecutive items from the collection.
+     * @method ODataCacheSource#read
+     * @param {Number} index - Zero-based index of the items to retrieve.
+     * @param {Number} count - Number of items to retrieve.
+     * @param {Function} success - Success callback with the requested items.
+     * @param {Function} error - Error callback.
+     * @returns {Object} Request object with an abort method.
+    */
+    that.read = function (index, count, success, error) {
+
+        var queryOptions = "$skip=" + index + "&$top=" + count;
+        return queryForData(appendQueryOption(uri, queryOptions), that.options, success, error);
+    };
+
+    return that;
+}
+
+
+
+/** ODataCacheSource (see {@link ODataCacheSource}) */
+exports.ODataCacheSource = ODataCacheSource;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/lib/deferred.js
----------------------------------------------------------------------
diff --git a/lib/deferred.js b/lib/deferred.js
new file mode 100644
index 0000000..520a857
--- /dev/null
+++ b/lib/deferred.js
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+/** @module odatajs/deferred */
+
+
+
+/** Creates a new function to forward a call.
+ * @param {Object} thisValue - Value to use as the 'this' object.
+ * @param {String} name - Name of function to forward to.
+ * @param {Object} returnValue - Return value for the forward call (helps keep identity when chaining calls).
+ * @returns {Function} A new function that will forward a call.
+ */
+function forwardCall(thisValue, name, returnValue) {
+    return function () {
+        thisValue[name].apply(thisValue, arguments);
+        return returnValue;
+    };
+}
+
+/** Initializes a new DjsDeferred object.
+ * <ul>
+ * <li> Compability Note A - Ordering of callbacks through chained 'then' invocations <br>
+ *
+ * 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.
+ * </li>
+ * <li>Compability Note B - Fulfillment value <br>
+ *
+ * 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.
+ * </li></ul>
+ * @class DjsDeferred 
+ */
+ function DjsDeferred() {
+    this._arguments = undefined;
+    this._done = undefined;
+    this._fail = undefined;
+    this._resolved = false;
+    this._rejected = false;
+}
+
+
+DjsDeferred.prototype = {
+
+    /** Adds success and error callbacks for this deferred object.
+     * See Compatibility Note A.
+     * @method DjsDeferred#then
+     * @param {function} [fulfilledHandler] - Success callback ( may be null)
+     * @param {function} [errorHandler] - Error callback ( may be null)
+     */
+    then: function (fulfilledHandler, errorHandler) {
+
+        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;
+    },
+
+    /** Invokes success callbacks for this deferred object.
+     * All arguments are forwarded to success callbacks.
+     * @method DjsDeferred#resolve
+     */
+    resolve: function (/* args */) {
+        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;
+        }
+    },
+
+    /** Invokes error callbacks for this deferred object.
+     * All arguments are forwarded to error callbacks.
+     * @method DjsDeferred#reject
+     */
+    reject: function (/* args */) {
+        
+        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;
+        }
+    },
+
+    /** Returns a version of this object that has only the read-only methods available.
+     * @method DjsDeferred#promise
+     * @returns An object with only the promise object.
+     */
+
+    promise: function () {
+        var result = {};
+        result.then = forwardCall(this, "then", result);
+        return result;
+    }
+};
+
+/** Creates a deferred object.
+ * @returns {DjsDeferred} A new deferred object. If jQuery is installed, then a jQueryDeferred object is returned, which provides a superset of features.
+*/
+function createDeferred() {
+    if (window.jQuery && window.jQuery.Deferred) {
+        return new window.jQuery.Deferred();
+    } else {
+        return new DjsDeferred();
+    }
+}
+
+
+
+
+/** createDeferred (see {@link module:datajs/deferred~createDeferred}) */
+exports.createDeferred = createDeferred;
+
+/** DjsDeferred (see {@link DjsDeferred}) */
+exports.DjsDeferred = DjsDeferred;
\ No newline at end of file


[3/8] olingo-odata4-js git commit: [OLINGO-442] Cleanup bevore release II and beta-name removal

Posted by ko...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/odata/batch.js
----------------------------------------------------------------------
diff --git a/src/lib/odata/batch.js b/src/lib/odata/batch.js
deleted file mode 100644
index d33ac53..0000000
--- a/src/lib/odata/batch.js
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-/** @module odata/batch */
-
-var utils    = require('./../utils.js');
-var odataUtils    = require('./odatautils.js');
-var odataHandler = require('./handler.js');
-
-var extend = utils.extend;
-var isArray = utils.isArray;
-var trimString = utils.trimString;
-
-var contentType = odataHandler.contentType;
-var handler = odataHandler.handler;
-var isBatch = odataUtils.isBatch;
-var MAX_DATA_SERVICE_VERSION = odataHandler.MAX_DATA_SERVICE_VERSION;
-var normalizeHeaders = odataUtils.normalizeHeaders;
-//TODO var payloadTypeOf = odata.payloadTypeOf;
-var prepareRequest = odataUtils.prepareRequest;
-
-
-// Imports
-
-// CONTENT START
-var batchMediaType = "multipart/mixed";
-var responseStatusRegex = /^HTTP\/1\.\d (\d{3}) (.*)$/i;
-var responseHeaderRegex = /^([^()<>@,;:\\"\/[\]?={} \t]+)\s?:\s?(.*)/;
-
-/** Calculates a random 16 bit number and returns it in hexadecimal format.
- * @returns {String} A 16-bit number in hex format.
- */
-function hex16() {
-
-    return Math.floor((1 + Math.random()) * 0x10000).toString(16).substr(1);
-}
-
-/** Creates a string that can be used as a multipart request boundary.
- * @param {String} [prefix] - 
- * @returns {String} Boundary string of the format: <prefix><hex16>-<hex16>-<hex16>
- */
-function createBoundary(prefix) {
-
-    return prefix + hex16() + "-" + hex16() + "-" + hex16();
-}
-
-/** Gets the handler for data serialization of individual requests / responses in a batch.
- * @param context - Context used for data serialization.
- * @returns Handler object
- */
-function partHandler(context) {
-
-    return context.handler.partHandler;
-}
-
-/** Gets the current boundary used for parsing the body of a multipart response.
- * @param context - Context used for parsing a multipart response.
- * @returns {String} Boundary string.
- */
-function currentBoundary(context) {
-    var boundaries = context.boundaries;
-    return boundaries[boundaries.length - 1];
-}
-
-/** Parses a batch response.
- * @param handler - This handler.
- * @param {String} text - Batch text.
- * @param {Object} context - Object with parsing context.
- * @return An object representation of the batch.
- */
-function batchParser(handler, text, context) {
-
-    var boundary = context.contentType.properties["boundary"];
-    return { __batchResponses: readBatch(text, { boundaries: [boundary], handlerContext: context }) };
-}
-
-/** Serializes a batch object representation into text.
- * @param handler - This handler.
- * @param {Object} data - Representation of a batch.
- * @param {Object} context - Object with parsing context.
- * @return An text representation of the batch object; undefined if not applicable.#
- */
-function batchSerializer(handler, data, context) {
-
-    var cType = context.contentType = context.contentType || contentType(batchMediaType);
-    if (cType.mediaType === batchMediaType) {
-        return writeBatch(data, context);
-    }
-}
-
-/** Parses a multipart/mixed response body from from the position defined by the context.
- * @param {String}  text - Body of the multipart/mixed response.
- * @param context - Context used for parsing.
- * @return Array of objects representing the individual responses.
- */
-function readBatch(text, context) {
-    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 = null;
-
-    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;
-}
-
-/** Parses the http headers in the text from the position defined by the context.
- * @param {String} text - Text containing an http response's headers
- * @param context - Context used for parsing.
- * @returns Object containing the headers as key value pairs.
- * This function doesn't support split headers and it will stop reading when it hits two consecutive line breaks.
-*/
-function readHeaders(text, context) {
-    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;
-}
-
-/** Parses an HTTP response.
- * @param {String} text -Text representing the http response.
- * @param context optional - Context used for parsing.
- * @param {String} delimiter -String used as delimiter of the multipart response parts.
- * @return Object representing the http response.
- */
-function readResponse(text, context, delimiter) {
-    // 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)
-    };
-}
-
-/** Returns a substring from the position defined by the context up to the next line break (CRLF).
- * @param {String} text - Input string.
- * @param context - Context used for reading the input string.
- * @returns {String} Substring to the first ocurrence of a line break or null if none can be found. 
- */
-function readLine(text, context) {
-
-    return readTo(text, context, "\r\n");
-}
-
-/** 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.
- * @param {String} text - Input string.
- * @param context - Context used for reading the input string.
- * @param {String} [str] - Substring to read up to.
- * @returns {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.
- */
-function readTo(text, context, str) {
-    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);
-}
-
-/** Serializes a batch request object to a string.
- * @param data - Batch request object in payload representation format
- * @param context - Context used for the serialization
- * @returns {String} String representing the batch request
- */
-function writeBatch(data, context) {
-    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;
-}
-
-/** Creates the delimiter that indicates that start or end of an individual request.
- * @param {String} boundary Boundary string used to indicate the start of the request
- * @param {Boolean} close - Flag indicating that a close delimiter string should be generated
- * @returns {String} Delimiter string
- */
-function writeBatchPartDelimiter(boundary, close) {
-    var result = "\r\n--" + boundary;
-    if (close) {
-        result += "--";
-    }
-
-    return result + "\r\n";
-}
-
-/** 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.
- * @param part - Request or change set object in payload representation format
- * @param context - Object containing context information used for the serialization
- * @param {boolean} [nested] - 
- * @returns {String} String representing the serialized part
- * A change set is an array of request objects and they cannot be nested inside other change sets.
- */
-function writeBatchPart(part, context, nested) {
-    
-
-    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;
-}
-
-/** Serializes a request object to a string.
- * @param request - Request object to serialize
- * @returns {String} String representing the serialized request
- */
-function writeRequest(request) {
-    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;
-}
-
-
-
-/** batchHandler (see {@link module:odata/batch~batchParser}) */
-exports.batchHandler = handler(batchParser, batchSerializer, batchMediaType, MAX_DATA_SERVICE_VERSION);
-
-/** batchSerializer (see {@link module:odata/batch~batchSerializer}) */
-exports.batchSerializer = batchSerializer;
-
-/** writeRequest (see {@link module:odata/batch~writeRequest}) */
-exports.writeRequest = writeRequest;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/odata/handler.js
----------------------------------------------------------------------
diff --git a/src/lib/odata/handler.js b/src/lib/odata/handler.js
deleted file mode 100644
index 4c7260a..0000000
--- a/src/lib/odata/handler.js
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-/** @module odata/handler */
-
-
-var utils    = require('./../utils.js');
-var oDataUtils    = require('./odatautils.js');
-
-// Imports.
-var assigned = utils.assigned;
-var extend = utils.extend;
-var trimString = utils.trimString;
-var maxVersion = oDataUtils.maxVersion;
-var MAX_DATA_SERVICE_VERSION = "4.0";
-
-/** Parses a string into an object with media type and properties.
- * @param {String} str - String with media type to parse.
- * @return null if the string is empty; an object with 'mediaType' and a 'properties' dictionary otherwise.
- */
-function contentType(str) {
-
-    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 };
-}
-
-/** Serializes an object with media type and properties dictionary into a string.
- * @param contentType - Object with media type and properties dictionary to serialize.
- * @return String representation of the media type object; undefined if contentType is null or undefined.
- */
-function contentTypeToString(contentType) {
-    if (!contentType) {
-        return undefined;
-    }
-
-    var result = contentType.mediaType;
-    var property;
-    for (property in contentType.properties) {
-        result += ";" + property + "=" + contentType.properties[property];
-    }
-    return result;
-}
-
-/** Creates an object that is going to be used as the context for the handler's parser and serializer.
- * @param contentType - Object with media type and properties dictionary.
- * @param {String} dataServiceVersion - String indicating the version of the protocol to use.
- * @param context - Operation context.
- * @param handler - Handler object that is processing a resquest or response.
- * @return Context object.
- */
-function createReadWriteContext(contentType, dataServiceVersion, context, handler) {
-
-    var rwContext = {};
-    extend(rwContext, context);
-    extend(rwContext, {
-        contentType: contentType,
-        dataServiceVersion: dataServiceVersion,
-        handler: handler
-    });
-
-    return rwContext;
-}
-
-/** 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.
- * @param request - Request object on which the header will be set.
- * @param {String} name - Header name.
- * @param {String} value - Header value.
- */
-function fixRequestHeader(request, name, value) {
-    if (!request) {
-        return;
-    }
-
-    var headers = request.headers;
-    if (!headers[name]) {
-        headers[name] = value;
-    }
-}
-
-/** Sets the DataServiceVersion header of the request if its value is not yet defined or of a lower version.
- * @param request - Request object on which the header will be set.
- * @param {String} version - Version value.
- *  If the request has already a version value higher than the one supplied the this function does nothing.
- */
-function fixDataServiceVersionHeader(request, version) {   
-
-    if (request) {
-        var headers = request.headers;
-        var dsv = headers["OData-Version"];
-        headers["OData-Version"] = dsv ? maxVersion(dsv, version) : version;
-    }
-}
-
-/** Gets the value of a request or response header.
- * @param requestOrResponse - Object representing a request or a response.
- * @param {String} name - Name of the header to retrieve.
- * @returns {String} String value of the header; undefined if the header cannot be found.
- */
-function getRequestOrResponseHeader(requestOrResponse, name) {
-
-    var headers = requestOrResponse.headers;
-    return (headers && headers[name]) || undefined;
-}
-
-/** Gets the value of the Content-Type header from a request or response.
- * @param requestOrResponse - Object representing a request or a response.
- * @returns {Object} Object with 'mediaType' and a 'properties' dictionary; null in case that the header is not found or doesn't have a value.
- */
-function getContentType(requestOrResponse) {
-
-    return contentType(getRequestOrResponseHeader(requestOrResponse, "Content-Type"));
-}
-
-var versionRE = /^\s?(\d+\.\d+);?.*$/;
-/** Gets the value of the DataServiceVersion header from a request or response.
- * @param requestOrResponse - Object representing a request or a response.
- * @returns {String} Data service version; undefined if the header cannot be found.
- */
-function getDataServiceVersion(requestOrResponse) {
-
-    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.
-}
-
-/** Checks that a handler can process a particular mime type.
- * @param handler - Handler object that is processing a resquest or response.
- * @param cType - Object with 'mediaType' and a 'properties' dictionary.
- * @returns {Boolean} True if the handler can process the mime type; false otherwise.
- *
- * 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.
- */
-function handlerAccepts(handler, cType) {
-    return handler.accept.indexOf(cType.mediaType) >= 0;
-}
-
-/** Invokes the parser associated with a handler for reading the payload of a HTTP response.
- * @param handler - Handler object that is processing the response.
- * @param {Function} parseCallback - Parser function that will process the response payload.
- * @param response - HTTP response whose payload is going to be processed.
- * @param context - Object used as the context for processing the response.
- * @returns {Boolean} True if the handler processed the response payload and the response.data property was set; false otherwise.
- */
-function handlerRead(handler, parseCallback, response, context) {
-
-    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;
-}
-
-/** Invokes the serializer associated with a handler for generating the payload of a HTTP request.
- * @param handler - Handler object that is processing the request.
- * @param {Function} serializeCallback - Serializer function that will generate the request payload.
- * @param request - HTTP request whose payload is going to be generated.
- * @param context - Object used as the context for serializing the request.
- * @returns {Boolean} True if the handler serialized the request payload and the request.body property was set; false otherwise.
- */
-function handlerWrite(handler, serializeCallback, request, context) {
-    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;
-}
-
-/** Creates a handler object for processing HTTP requests and responses.
- * @param {Function} parseCallback - Parser function that will process the response payload.
- * @param {Function} serializeCallback - Serializer function that will generate the request payload.
- * @param {String} accept - String containing a comma separated list of the mime types that this handler can work with.
- * @param {String} maxDataServiceVersion - String indicating the highest version of the protocol that this handler can work with.
- * @returns {Object} Handler object.
- */
-function handler(parseCallback, serializeCallback, accept, maxDataServiceVersion) {
-
-    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);
-        }
-    };
-}
-
-function textParse(handler, body /*, context */) {
-    return body;
-}
-
-function textSerialize(handler, data /*, context */) {
-    if (assigned(data)) {
-        return data.toString();
-    } else {
-        return undefined;
-    }
-}
-
-
-
-
-exports.textHandler = handler(textParse, textSerialize, "text/plain", MAX_DATA_SERVICE_VERSION);
-exports.contentType = contentType;
-exports.contentTypeToString = contentTypeToString;
-exports.handler = handler;
-exports.createReadWriteContext = createReadWriteContext;
-exports.fixRequestHeader = fixRequestHeader;
-exports.getRequestOrResponseHeader = getRequestOrResponseHeader;
-exports.getContentType = getContentType;
-exports.getDataServiceVersion = getDataServiceVersion;
-exports.MAX_DATA_SERVICE_VERSION = MAX_DATA_SERVICE_VERSION;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/odata/json.js
----------------------------------------------------------------------
diff --git a/src/lib/odata/json.js b/src/lib/odata/json.js
deleted file mode 100644
index f00b54c..0000000
--- a/src/lib/odata/json.js
+++ /dev/null
@@ -1,1008 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/** @module odata/json */
-
-
-
-var utils        = require('./../utils.js');
-var oDataUtils   = require('./odatautils.js');
-var oDataHandler = require('./handler.js');
-
-var odataNs = "odata";
-var odataAnnotationPrefix = odataNs + ".";
-var contextUrlAnnotation = "@" + odataAnnotationPrefix + "context";
-
-var assigned = utils.assigned;
-var defined = utils.defined;
-var isArray = utils.isArray;
-//var isDate = utils.isDate;
-var isObject = utils.isObject;
-//var normalizeURI = utils.normalizeURI;
-var parseInt10 = utils.parseInt10;
-var getFormatKind = utils.getFormatKind;
-var convertByteArrayToHexString = utils.convertByteArrayToHexString;
-
-
-var formatDateTimeOffset = oDataUtils.formatDateTimeOffset;
-var formatDuration = oDataUtils.formatDuration;
-var formatNumberWidth = oDataUtils.formatNumberWidth;
-var getCanonicalTimezone = oDataUtils.getCanonicalTimezone;
-var handler = oDataUtils.handler;
-var isComplex = oDataUtils.isComplex;
-var isPrimitive = oDataUtils.isPrimitive;
-var isCollectionType = oDataUtils.isCollectionType;
-var lookupComplexType = oDataUtils.lookupComplexType;
-var lookupEntityType = oDataUtils.lookupEntityType;
-var lookupSingleton = oDataUtils.lookupSingleton;
-var lookupEntitySet = oDataUtils.lookupEntitySet;
-var lookupDefaultEntityContainer = oDataUtils.lookupDefaultEntityContainer;
-var lookupProperty = oDataUtils.lookupProperty;
-var MAX_DATA_SERVICE_VERSION = oDataUtils.MAX_DATA_SERVICE_VERSION;
-var maxVersion = oDataUtils.maxVersion;
-
-var isPrimitiveEdmType = oDataUtils.isPrimitiveEdmType;
-var isGeographyEdmType = oDataUtils.isGeographyEdmType;
-var isGeometryEdmType = oDataUtils.isGeometryEdmType;
-
-var PAYLOADTYPE_FEED = "f";
-var PAYLOADTYPE_ENTRY = "e";
-var PAYLOADTYPE_PROPERTY = "p";
-var PAYLOADTYPE_COLLECTION = "c";
-var PAYLOADTYPE_ENUMERATION_PROPERTY = "enum";
-var PAYLOADTYPE_SVCDOC = "s";
-var PAYLOADTYPE_ENTITY_REF_LINK = "erl";
-var PAYLOADTYPE_ENTITY_REF_LINKS = "erls";
-
-var PAYLOADTYPE_VALUE = "v";
-
-var PAYLOADTYPE_DELTA = "d";
-var DELTATYPE_FEED = "f";
-var DELTATYPE_DELETED_ENTRY = "de";
-var DELTATYPE_LINK = "l";
-var DELTATYPE_DELETED_LINK = "dl";
-
-var jsonMediaType = "application/json";
-var jsonContentType = oDataHandler.contentType(jsonMediaType);
-
-var jsonSerializableMetadata = ["@odata.id", "@odata.type"];
-
-
-
-
-
-/** Extend JSON OData payload with metadata
- * @param handler - This handler.
- * @param text - Payload text (this parser also handles pre-parsed objects).
- * @param {Object} context - Object with parsing context.
- * @return An object representation of the OData payload.
- */
-function jsonParser(handler, text, context) {
-    var recognizeDates = defined(context.recognizeDates, handler.recognizeDates);
-    var model = context.metadata;
-    var json = (typeof text === "string") ? JSON.parse(text) : text;
-    var metadataContentType;
-    if (assigned(context.contentType) && assigned(context.contentType.properties)) {
-        metadataContentType = context.contentType.properties["odata.metadata"]; //TODO convert to lower before comparism
-    }
-
-    var payloadFormat = getFormatKind(metadataContentType, 1); // none: 0, minimal: 1, full: 2
-
-    // No errors should be throw out if we could not parse the json payload, instead we should just return the original json object.
-    if (payloadFormat === 0) {
-        return json;
-    }
-    else if (payloadFormat === 1) {
-        return addMinimalMetadataToJsonPayload(json, model, recognizeDates);
-    }
-    else if (payloadFormat === 2) {
-        // to do: using the EDM Model to get the type of each property instead of just guessing.
-        return addFullMetadataToJsonPayload(json, model, recognizeDates);
-    }
-    else {
-        return json;
-    }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-// 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+)?\)\/$/;
-
-
-// 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 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;
-    }
-};
-
-/** Serializes a ODataJs payload structure to the wire format which can be send to the server
- * @param handler - This handler.
- * @param data - Data to serialize.
- * @param {Object} context - Object with serialization context.
- * @returns {String} The string representation of data.
- */
-function jsonSerializer(handler, data, context) {
-
-    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 = formatJsonRequestPayload(data);
-        if (newdata) {
-            return JSON.stringify(newdata,jsonReplacer);
-        }
-    }
-    return undefined;
-}
-
-
-
-
-/** Convert OData objects for serialisation in to a new data structure
- * @param data - Data to serialize.
- * @returns {String} The string representation of data.
- */
-function formatJsonRequestPayload(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] = formatJsonRequestPayload(data[i]);
-        }
-
-        return newArrayData;
-    }
-
-    var newdata = {};
-    for (var property in data) {
-        if (isJsonSerializableProperty(property)) {
-            newdata[property] = formatJsonRequestPayload(data[property]);
-        }
-    }
-
-    return newdata;
-}
-
-/** Determine form the attribute name if the attribute is a serializable property
- * @param attribute
- * @returns {boolean}
- */
-function isJsonSerializableProperty(attribute) {
-    if (!attribute) {
-        return false;
-    }
-
-    if (attribute.indexOf("@odata.") == -1) {
-        return true;
-    }
-
-    var i, len;
-    for (i = 0, len = jsonSerializableMetadata.length; i < len; i++) {
-        var name = jsonSerializableMetadata[i];
-        if (attribute.indexOf(name) != -1) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-/** Creates an object containing information for the json payload.
- * @param {String} kind - JSON payload kind
- * @param {String} type - Type name of the JSON payload.
- * @returns {Object} Object with kind and type fields.
- */
-function jsonMakePayloadInfo(kind, type) {
-    return { kind: kind, type: type || null };
-}
-
-
-
-/** Add metadata to an JSON payload complex object containing full metadata
- * @param {Object} data - Data structure to be extended
- * @param {Object} model - Metadata model
- * @param {Boolean} recognizeDates - Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.
- */
-function addFullMetadataToJsonPayload(data, model, recognizeDates) {
-    var type;
-    if (utils.isObject(data)) {
-        for (var key in data) {
-            if (data.hasOwnProperty(key)) {
-                if (key.indexOf('@') === -1) {
-                    if (utils.isArray(data[key])) {
-                        for (var i = 0; i < data[key].length; ++i) {
-                            addFullMetadataToJsonPayload(data[key][i], model, recognizeDates);
-                        }
-                    } else if (utils.isObject(data[key])) {
-                        if (data[key] !== null) {
-                            //don't step into geo.. objects
-                            type = data[key+'@odata.type'];
-                            if (!type) {
-                                //type unknown
-                                addFullMetadataToJsonPayload(data[key], model, recognizeDates);
-                            } else {
-                                type = type.substring(1);
-                                if  (isGeographyEdmType(type) || isGeometryEdmType(type)) {
-                                    // don't add type info for geo* types
-                                } else {
-                                    addFullMetadataToJsonPayload(data[key], model, recognizeDates);
-                                }
-                            }
-                        }
-                    } else {
-                        type = data[key + '@odata.type'];
-
-                        // On .Net OData library, some basic EDM type is omitted, e.g. Edm.String, Edm.Int, and etc.
-                        // For the full metadata payload, we need to full fill the @data.type for each property if it is missing.
-                        // We do this is to help the OlingoJS consumers to easily get the type of each property.
-                        if (!assigned(type)) {
-                            // Guessing the "type" from the type of the value is not the right way here.
-                            // To do: we need to get the type from metadata instead of guessing.
-                            var typeFromObject = typeof data[key];
-                            if (typeFromObject === 'string') {
-                                addType(data, key, 'String');
-                            } else if (typeFromObject === 'boolean') {
-                                addType(data, key, 'Boolean');
-                            } else if (typeFromObject === 'number') {
-                                if (data[key] % 1 === 0) { // has fraction
-                                    addType(data, key, 'Int32'); // the biggst integer
-                                } else {
-                                    addType(data, key, 'Decimal'); // the biggst float single,doulbe,decimal
-                                }
-                            }
-                        }
-                        else {
-                            if (recognizeDates) {
-                                convertDatesNoEdm(data, key, type.substring(1));
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    return data;
-}
-
-/** Loop through the properties of an JSON payload object, look up the type info of the property and call
- * the appropriate add*MetadataToJsonPayloadObject function
- * @param {Object} data - Data structure to be extended
- * @param {String} objectInfoType - Information about the data (name,type,typename,...)
- * @param {String} baseURI - Base Url
- * @param {Object} model - Metadata model
- * @param {Boolean} recognizeDates - Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.
- */
-function checkProperties(data, objectInfoType, baseURI, model, recognizeDates) {
-    for (var name in data) {
-        if (name.indexOf("@") === -1) {
-            var curType = objectInfoType;
-            var propertyValue = data[name];
-            var property = lookupProperty(curType.property,name); //TODO SK add check for parent type
-
-            while (( property === null) && (curType.baseType !== undefined)) {
-                curType = lookupEntityType(curType.baseType, model);
-                property = lookupProperty(curType.property,name);
-            }
-
-            if ( isArray(propertyValue)) {
-                //data[name+'@odata.type'] = '#' + property.type;
-                if (isCollectionType(property.type)) {
-                    addTypeColNoEdm(data,name,property.type.substring(11,property.type.length-1));
-                } else {
-                    addTypeNoEdm(data,name,property.type);
-                }
-
-
-                for ( var i = 0; i < propertyValue.length; i++) {
-                    addMetadataToJsonMinimalPayloadComplex(propertyValue[i], property, baseURI, model, recognizeDates);
-                }
-            } else if (isObject(propertyValue) && (propertyValue !== null)) {
-                addMetadataToJsonMinimalPayloadComplex(propertyValue, property, baseURI, model, recognizeDates);
-            } else {
-                //data[name+'@odata.type'] = '#' + property.type;
-                addTypeNoEdm(data,name,property.type);
-                if (recognizeDates) {
-                    convertDates(data, name, property.type);
-                }
-            }
-        }
-    }
-}
-
-
-
-/** Add metadata to an JSON payload object containing minimal metadata
- * @param {Object} data - Json response payload object
- * @param {Object} model - Object describing an OData conceptual schema
- * @param {Boolean} recognizeDates - Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.
- * @returns {Object} Object in the library's representation.
- */
-function addMinimalMetadataToJsonPayload(data, model, recognizeDates) {
-
-    if (!assigned(model) || isArray(model)) {
-        return data;
-    }
-
-    var baseURI = data[contextUrlAnnotation];
-    var payloadInfo = createPayloadInfo(data, model);
-
-    switch (payloadInfo.detectedPayloadKind) {
-
-        case PAYLOADTYPE_VALUE:
-            if (payloadInfo.type !== null) {
-                return addMetadataToJsonMinimalPayloadEntity(data, payloadInfo, baseURI, model, recognizeDates);
-            } else {
-                return addTypeNoEdm(data,'value', payloadInfo.typeName);
-            }
-
-        case PAYLOADTYPE_FEED:
-            return addMetadataToJsonMinimalPayloadFeed(data, model, payloadInfo, baseURI, recognizeDates);
-
-        case PAYLOADTYPE_ENTRY:
-            return addMetadataToJsonMinimalPayloadEntity(data, payloadInfo, baseURI, model, recognizeDates);
-
-        case PAYLOADTYPE_COLLECTION:
-            return addMetadataToJsonMinimalPayloadCollection(data, model, payloadInfo, baseURI, recognizeDates);
-
-        case PAYLOADTYPE_PROPERTY:
-            if (payloadInfo.type !== null) {
-                return addMetadataToJsonMinimalPayloadEntity(data, payloadInfo, baseURI, model, recognizeDates);
-            } else {
-                return addTypeNoEdm(data,'value', payloadInfo.typeName);
-            }
-
-        case PAYLOADTYPE_SVCDOC:
-            return data;
-
-        case PAYLOADTYPE_LINKS:
-            return data;
-    }
-
-    return data;
-}
-
-/** Add metadata to an JSON payload feed object containing minimal metadata
- * @param {Object} data - Data structure to be extended
- * @param {Object} model - Metadata model
- * @param {String} feedInfo - Information about the data (name,type,typename,...)
- * @param {String} baseURI - Base Url
- * @param {Boolean} recognizeDates - Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.
- */
-function addMetadataToJsonMinimalPayloadFeed(data, model, feedInfo, baseURI, recognizeDates) {
-    var entries = [];
-    var items = data.value;
-    var i,len;
-    var entry;
-    for (i = 0, len = items.length; i < len; i++) {
-        var item = items[i];
-        if ( defined(item['@odata.type'])) { // in case of mixed feeds
-            var typeName = item['@odata.type'].substring(1);
-            var type = lookupEntityType( typeName, model);
-            var entryInfo = {
-                contentTypeOdata : feedInfo.contentTypeOdata,
-                detectedPayloadKind : feedInfo.detectedPayloadKind,
-                name : feedInfo.name,
-                type : type,
-                typeName : typeName
-            };
-
-            entry = addMetadataToJsonMinimalPayloadEntity(item, entryInfo, baseURI, model, recognizeDates);
-        } else {
-            entry = addMetadataToJsonMinimalPayloadEntity(item, feedInfo, baseURI, model, recognizeDates);
-        }
-
-        entries.push(entry);
-    }
-    data.value = entries;
-    return data;
-}
-
-
-/** Add metadata to an JSON payload entity object containing minimal metadata
- * @param {Object} data - Data structure to be extended
- * @param {String} objectInfo - Information about the data (name,type,typename,...)
- * @param {String} baseURI - Base Url
- * @param {Object} model - Metadata model
- * @param {Boolean} recognizeDates - Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.
- */
-function addMetadataToJsonMinimalPayloadEntity(data, objectInfo, baseURI, model, recognizeDates) {
-    addType(data,'',objectInfo.typeName);
-
-    var keyType = objectInfo.type;
-    while ((defined(keyType)) && ( keyType.key === undefined) && (keyType.baseType !== undefined)) {
-        keyType = lookupEntityType(keyType.baseType, model);
-    }
-
-    if (keyType.key !== undefined) {
-        var lastIdSegment = objectInfo.name + jsonGetEntryKey(data, keyType);
-        data['@odata.id'] = baseURI.substring(0, baseURI.lastIndexOf("$metadata")) + lastIdSegment;
-        data['@odata.editLink'] = lastIdSegment;
-    }
-
-    //var serviceURI = baseURI.substring(0, baseURI.lastIndexOf("$metadata"));
-
-    checkProperties(data, objectInfo.type, baseURI, model, recognizeDates);
-
-    return data;
-}
-
-/** Add metadata to an JSON payload complex object containing minimal metadata
- * @param {Object} data - Data structure to be extended
- * @param {String} property - Information about the data (name,type,typename,...)
- * @param {String} baseURI - Base Url
- * @param {Object} model - Metadata model
- * @param {Boolean} recognizeDates - Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.
- */
-function addMetadataToJsonMinimalPayloadComplex(data, property, baseURI, model, recognizeDates) {
-    var type = property.type;
-    if (isCollectionType(property.type)) {
-        type =property.type.substring(11,property.type.length-1);
-    }
-
-    addType(data,'',property.type);
-
-    var propertyType = lookupComplexType(type, model);
-    if (propertyType === null)  {
-        return; //TODO check what to do if the type is not known e.g. type #GeometryCollection
-    }
-
-    checkProperties(data, propertyType, baseURI, model, recognizeDates);
-}
-
-/** Add metadata to an JSON payload collection object containing minimal metadata
- * @param {Object} data - Data structure to be extended
- * @param {Object} model - Metadata model
- * @param {String} collectionInfo - Information about the data (name,type,typename,...)
- * @param {String} baseURI - Base Url
- * @param {Boolean} recognizeDates - Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.
- */
-function addMetadataToJsonMinimalPayloadCollection(data, model, collectionInfo, baseURI, recognizeDates) {
-
-    addTypeColNoEdm(data,'', collectionInfo.typeName);
-
-    if (collectionInfo.type !== null) {
-        var entries = [];
-
-        var items = data.value;
-        var i,len;
-        var entry;
-        for (i = 0, len = items.length; i < len; i++) {
-            var item = items[i];
-            if ( defined(item['@odata.type'])) { // in case of mixed collections
-                var typeName = item['@odata.type'].substring(1);
-                var type = lookupEntityType( typeName, model);
-                var entryInfo = {
-                    contentTypeOdata : collectionInfo.contentTypeOdata,
-                    detectedPayloadKind : collectionInfo.detectedPayloadKind,
-                    name : collectionInfo.name,
-                    type : type,
-                    typeName : typeName
-                };
-
-                entry = addMetadataToJsonMinimalPayloadEntity(item, entryInfo, baseURI, model, recognizeDates);
-            } else {
-                entry = addMetadataToJsonMinimalPayloadEntity(item, collectionInfo, baseURI, model, recognizeDates);
-            }
-
-            entries.push(entry);
-        }
-        data.value = entries;
-    }
-    return data;
-}
-
-/** Add an OData type tag to an JSON payload object
- * @param {Object} data - Data structure to be extended
- * @param {String} name - Name of the property whose type is set
- * @param {String} value - Type name
- */
-function addType(data, name, value ) {
-    var fullName = name + '@odata.type';
-
-    if ( data[fullName] === undefined) {
-        data[fullName] = '#' + value;
-    }
-}
-
-/** Add an OData type tag to an JSON payload object collection (without "Edm." namespace)
- * @param {Object} data - Data structure to be extended
- * @param {String} name - Name of the property whose type is set
- * @param {String} typeName - Type name
- */
-function addTypeColNoEdm(data, name, typeName ) {
-    var fullName = name + '@odata.type';
-
-    if ( data[fullName] === undefined) {
-        if ( typeName.substring(0,4)==='Edm.') {
-            data[fullName] = '#Collection('+typeName.substring(4)+ ')';
-        } else {
-            data[fullName] = '#Collection('+typeName+ ')';
-        }
-    }
-}
-
-
-/** Add an OData type tag to an JSON payload object (without "Edm." namespace)
- * @param {Object} data - Data structure to be extended
- * @param {String} name - Name of the property whose type is set
- * @param {String} value - Type name
- */
-function addTypeNoEdm(data, name, value ) {
-    var fullName = name + '@odata.type';
-
-    if ( data[fullName] === undefined) {
-        if ( value.substring(0,4)==='Edm.') {
-            data[fullName] = '#' + value.substring(4);
-        } else {
-            data[fullName] = '#' + value;
-        }
-    }
-    return data;
-}
-/** Convert the date/time format of an property from the JSON payload object (without "Edm." namespace)
- * @param {Object} data - Data structure to be extended
- * @param propertyName - Name of the property to be changed
- * @param type - Type
- */
-function convertDates(data, propertyName,type) {
-    if (type === 'Edm.Date') {
-        data[propertyName] = oDataUtils.parseDate(data[propertyName], true);
-    } else if (type === 'Edm.DateTimeOffset') {
-        data[propertyName] = oDataUtils.parseDateTimeOffset(data[propertyName], true);
-    } else if (type === 'Edm.Duration') {
-        data[propertyName] = oDataUtils.parseDuration(data[propertyName], true);
-    } else if (type === 'Edm.Time') {
-        data[propertyName] = oDataUtils.parseTime(data[propertyName], true);
-    }
-}
-
-/** Convert the date/time format of an property from the JSON payload object
- * @param {Object} data - Data structure to be extended
- * @param propertyName - Name of the property to be changed
- * @param type - Type
- */
-function convertDatesNoEdm(data, propertyName,type) {
-    if (type === 'Date') {
-        data[propertyName] = oDataUtils.parseDate(data[propertyName], true);
-    } else if (type === 'DateTimeOffset') {
-        data[propertyName] = oDataUtils.parseDateTimeOffset(data[propertyName], true);
-    } else if (type === 'Duration') {
-        data[propertyName] = oDataUtils.parseDuration(data[propertyName], true);
-    } else if (type === 'Time') {
-        data[propertyName] = oDataUtils.parseTime(data[propertyName], true);
-    }
-}
-
-/** Formats a value according to Uri literal format
- * @param value - Value to be formatted.
- * @param type - Edm type of the value
- * @returns {string} Value after formatting
- */
-function formatLiteral(value, type) {
-
-    value = "" + formatRawLiteral(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;
-    }
-}
-
-/** convert raw byteArray to hexString if the property is an binary property
- * @param value - Value to be formatted.
- * @param type - Edm type of the value
- * @returns {string} Value after formatting
- */
-function formatRawLiteral(value, type) {
-    switch (type) {
-        case "Edm.Binary":
-            return convertByteArrayToHexString(value);
-        default:
-            return value;
-    }
-}
-
-/** Formats the given minutes into (+/-)hh:mm format.
- * @param {Number} minutes - Number of minutes to format.
- * @returns {String} The minutes in (+/-)hh:mm format.
- */
-function minutesToOffset(minutes) {
-
-    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);
-}
-
-/** Parses the JSON Date representation into a Date object.
- * @param {String} value - String value.
- * @returns {Date} A Date object if the value matches one; falsy otherwise.
- */
-function parseJsonDateString(value) {
-
-    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.
-}
-
-/** Creates an object containing information for the context
- * @param {String} fragments - Uri fragment
- * @param {Object} model - Object describing an OData conceptual schema
- * @returns {Object} type(optional)  object containing type information for entity- and complex-types ( null if a typeName is a primitive)
- */
-function parseContextUriFragment( fragments, model ) {
-    var ret = {};
-
-    if (fragments.indexOf('/') === -1 ) {
-        if (fragments.length === 0) {
-            // Capter 10.1
-            ret.detectedPayloadKind = PAYLOADTYPE_SVCDOC;
-            return ret;
-        } else if (fragments === 'Edm.Null') {
-            // Capter 10.15
-            ret.detectedPayloadKind = PAYLOADTYPE_VALUE;
-            ret.isNullProperty = true;
-            return ret;
-        } else if (fragments === 'Collection($ref)') {
-            // Capter 10.11
-            ret.detectedPayloadKind = PAYLOADTYPE_ENTITY_REF_LINKS;
-            return ret;
-        } else if (fragments === '$ref') {
-            // Capter 10.12
-            ret.detectedPayloadKind = PAYLOADTYPE_ENTITY_REF_LINK;
-            return ret;
-        } else {
-            //TODO check for navigation resource
-        }
-    }
-
-    ret.type = undefined;
-    ret.typeName = undefined;
-
-    var fragmentParts = fragments.split("/");
-    var type;
-
-    for(var i = 0; i < fragmentParts.length; ++i) {
-        var fragment = fragmentParts[i];
-        if (ret.typeName === undefined) {
-            //preparation
-            if ( fragment.indexOf('(') !== -1 ) {
-                //remove the query function, cut fragment to matching '('
-                var index = fragment.length - 2 ;
-                for ( var rCount = 1; rCount > 0 && index > 0; --index) {
-                    if ( fragment.charAt(index)=='(') {
-                        rCount --;
-                    } else if ( fragment.charAt(index)==')') {
-                        rCount ++;
-                    }
-                }
-
-                if (index === 0) {
-                    //TODO throw error
-                }
-
-                //remove the projected entity from the fragment; TODO decide if we want to store the projected entity
-                var inPharenthesis = fragment.substring(index+2,fragment.length - 1);
-                fragment = fragment.substring(0,index+1);
-
-                if (utils.startsWith(fragment, 'Collection')) {
-                    ret.detectedPayloadKind = PAYLOADTYPE_COLLECTION;
-                    // Capter 10.14
-                    ret.typeName = inPharenthesis;
-
-                    type = lookupEntityType(ret.typeName, model);
-                    if ( type !== null) {
-                        ret.type = type;
-                        continue;
-                    }
-                    type = lookupComplexType(ret.typeName, model);
-                    if ( type !== null) {
-                        ret.type = type;
-                        continue;
-                    }
-
-                    ret.type = null;//in case of #Collection(Edm.String) only lastTypeName is filled
-                    continue;
-                } else {
-                    // projection: Capter 10.7, 10.8 and 10.9
-                    ret.projection = inPharenthesis;
-                }
-            }
-
-
-            if (jsonIsPrimitiveType(fragment)) {
-                ret.typeName = fragment;
-                ret.type = null;
-                ret.detectedPayloadKind = PAYLOADTYPE_VALUE;
-                continue;
-            }
-
-            var container = lookupDefaultEntityContainer(model);
-
-            //check for entity
-            var entitySet = lookupEntitySet(container.entitySet, fragment);
-            if ( entitySet !== null) {
-                ret.typeName = entitySet.entityType;
-                ret.type = lookupEntityType( ret.typeName, model);
-                ret.name = fragment;
-                ret.detectedPayloadKind = PAYLOADTYPE_FEED;
-                // Capter 10.2
-                continue;
-            }
-
-            //check for singleton
-            var singleton = lookupSingleton(container.singleton, fragment);
-            if ( singleton !== null) {
-                ret.typeName = singleton.entityType;
-                ret.type = lookupEntityType( ret.typeName, model);
-                ret.name = fragment;
-                ret.detectedPayloadKind =  PAYLOADTYPE_ENTRY;
-                // Capter 10.4
-                continue;
-            }
-
-
-
-            //TODO throw ERROR
-        } else {
-            //check for $entity
-            if (utils.endsWith(fragment, '$entity') && (ret.detectedPayloadKind === PAYLOADTYPE_FEED)) {
-                //TODO ret.name = fragment;
-                ret.detectedPayloadKind = PAYLOADTYPE_ENTRY;
-                // Capter 10.3 and 10.6
-                continue;
-            }
-
-            //check for derived types
-            if (fragment.indexOf('.') !== -1) {
-                // Capter 10.6
-                ret.typeName = fragment;
-                type = lookupEntityType(ret.typeName, model);
-                if ( type !== null) {
-                    ret.type = type;
-                    continue;
-                }
-                type = lookupComplexType(ret.typeName, model);
-                if ( type !== null) {
-                    ret.type = type;
-                    continue;
-                }
-
-                //TODO throw ERROR invalid type
-            }
-
-            //check for property value
-            if ( ret.detectedPayloadKind === PAYLOADTYPE_FEED || ret.detectedPayloadKind === PAYLOADTYPE_ENTRY) {
-                var property = lookupProperty(ret.type.property, fragment);
-                if (property !== null) {
-                    //PAYLOADTYPE_COLLECTION
-                    ret.typeName = property.type;
-
-
-                    if (utils.startsWith(property.type, 'Collection')) {
-                        ret.detectedPayloadKind = PAYLOADTYPE_COLLECTION;
-                        var tmp12 =  property.type.substring(10+1,property.type.length - 1);
-                        ret.typeName = tmp12;
-                        ret.type = lookupComplexType(tmp12, model);
-                        ret.detectedPayloadKind = PAYLOADTYPE_COLLECTION;
-                    } else {
-                        ret.type = lookupComplexType(property.type, model);
-                        ret.detectedPayloadKind = PAYLOADTYPE_PROPERTY;
-                    }
-
-                    ret.name = fragment;
-                    // Capter 10.15
-                }
-                continue;
-            }
-
-            if (fragment === '$delta') {
-                ret.deltaKind = DELTATYPE_FEED;
-                continue;
-            } else if (utils.endsWith(fragment, '/$deletedEntity')) {
-                ret.deltaKind = DELTATYPE_DELETED_ENTRY;
-                continue;
-            } else if (utils.endsWith(fragment, '/$link')) {
-                ret.deltaKind = DELTATYPE_LINK;
-                continue;
-            } else if (utils.endsWith(fragment, '/$deletedLink')) {
-                ret.deltaKind = DELTATYPE_DELETED_LINK;
-                continue;
-            }
-            //TODO throw ERROr
-        }
-    }
-
-    return ret;
-}
-
-
-/** Infers the information describing the JSON payload from its metadata annotation, structure, and data model.
- * @param {Object} data - Json response payload object.
- * @param {Object} model - Object describing an OData conceptual schema.
- * 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 payload.
- * @return Object with kind and type fields. Null if there is no metadata annotation or the payload info cannot be obtained..
- */
-function createPayloadInfo(data, model) {
-    var metadataUri = data[contextUrlAnnotation];
-    if (!metadataUri || typeof metadataUri !== "string") {
-        return null;
-    }
-
-    var fragmentStart = metadataUri.lastIndexOf("#");
-    if (fragmentStart === -1) {
-        return jsonMakePayloadInfo(PAYLOADTYPE_SVCDOC);
-    }
-
-    var fragment = metadataUri.substring(fragmentStart + 1);
-    return parseContextUriFragment(fragment,model);
-}
-/** Gets the key of an entry.
- * @param {Object} data - JSON entry.
- * @param {Object} data - EDM entity model for key loockup.
- * @returns {string} Entry instance key.
- */
-function jsonGetEntryKey(data, entityModel) {
-
-    var entityInstanceKey;
-    var entityKeys = entityModel.key[0].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;
-}
-/** Determines whether a type name is a primitive type in a JSON payload.
- * @param {String} typeName - Type name to test.
- * @returns {Boolean} True if the type name an EDM primitive type or an OData spatial type; false otherwise.
- */
-function jsonIsPrimitiveType(typeName) {
-    return isPrimitiveEdmType(typeName) || isGeographyEdmType(typeName) || isGeometryEdmType(typeName);
-}
-
-
-var jsonHandler = oDataHandler.handler(jsonParser, jsonSerializer, jsonMediaType, MAX_DATA_SERVICE_VERSION);
-jsonHandler.recognizeDates = false;
-
-exports.createPayloadInfo = createPayloadInfo;
-exports.jsonHandler = jsonHandler;
-exports.jsonParser = jsonParser;
-exports.jsonSerializer = jsonSerializer;
-exports.parseJsonDateString = parseJsonDateString;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/odata/metadata.js
----------------------------------------------------------------------
diff --git a/src/lib/odata/metadata.js b/src/lib/odata/metadata.js
deleted file mode 100644
index 9fdcdfd..0000000
--- a/src/lib/odata/metadata.js
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-/** @module odata/metadata */
-
-var utils    = require('./../utils.js');
-var oDSxml    = require('./../xml.js');
-var odataHandler    = require('./handler.js');
-
-
-
-// imports 
-var contains = utils.contains;
-var normalizeURI = utils.normalizeURI;
-var xmlAttributes = oDSxml.xmlAttributes;
-var xmlChildElements = oDSxml.xmlChildElements;
-var xmlFirstChildElement = oDSxml.xmlFirstChildElement;
-var xmlInnerText = oDSxml.xmlInnerText;
-var xmlLocalName = oDSxml.xmlLocalName;
-var xmlNamespaceURI = oDSxml.xmlNamespaceURI;
-var xmlNS = oDSxml.xmlNS;
-var xmlnsNS = oDSxml.xmlnsNS;
-var xmlParse = oDSxml.xmlParse;
-
-var ado = oDSxml.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 odataMetaXmlNs = adoDs + "/metadata";           // http://docs.oasis-open.org/odata/ns/metadata
-var MAX_DATA_SERVICE_VERSION = odataHandler.MAX_DATA_SERVICE_VERSION;
-
-var xmlMediaType = "application/xml";
-
-/** Creates an object that describes an element in an schema.
- * @param {Array} attributes - List containing the names of the attributes allowed for this element.
- * @param {Array} elements - List containing the names of the child elements allowed for this element.
- * @param {Boolean} text - Flag indicating if the element's text value is of interest or not.
- * @param {String} ns - Namespace to which the element belongs to.
- * If a child element name ends with * then it is understood by the schema that that child element can appear 0 or more times.
- * @returns {Object} Object with attributes, elements, text, and ns fields.
- */
-function schemaElement(attributes, elements, text, ns) {
-
-    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"]
-        )
-    }
-};
-
-
-/** Converts a Pascal-case identifier into a camel-case identifier.
- * @param {String} text - Text to convert.
- * @returns {String} Converted text.
- * If the text starts with multiple uppercase characters, it is left as-is.
- */
-function scriptCase(text) {
-
-    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();
-}
-
-/** Gets the schema node for the specified element.
- * @param {Object} parentSchema - Schema of the parent XML node of 'element'.
- * @param candidateName - XML element name to consider.
- * @returns {Object} The schema that describes the specified element; null if not found.
- */
-function getChildSchema(parentSchema, candidateName) {
-
-    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;
-}
-
-/** Checks whether the specifies namespace URI is one of the known CSDL namespace URIs.
- * @param {String} nsURI - Namespace URI to check.
- * @returns {Boolean} true if nsURI is a known CSDL namespace; false otherwise.
- */
-function isEdmNamespace(nsURI) {
-
-    return nsURI === edmNs1;
-}
-
-/** Parses a CSDL document.
- * @param element - DOM element to parse.
- * @returns {Object} An object describing the parsed element.
- */
-function parseConceptualModelElement(element) {
-
-    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;
-        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;
-}
-
-/** Parses a metadata document.
- * @param handler - This handler.
- * @param {String} text - Metadata text.
- * @returns An object representation of the conceptual model.
- */
-function metadataParser(handler, text) {
-
-    var doc = xmlParse(text);
-    var root = xmlFirstChildElement(doc);
-    return parseConceptualModelElement(root) || undefined;
-}
-
-
-
-exports.metadataHandler = odataHandler.handler(metadataParser, null, xmlMediaType, MAX_DATA_SERVICE_VERSION);
-
-exports.schema = schema;
-exports.scriptCase = scriptCase;
-exports.getChildSchema = getChildSchema;
-exports.parseConceptualModelElement = parseConceptualModelElement;
-exports.metadataParser = metadataParser;
\ No newline at end of file


[4/8] olingo-odata4-js git commit: [OLINGO-442] Cleanup bevore release II and beta-name removal

Posted by ko...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/index-browser.js
----------------------------------------------------------------------
diff --git a/src/index-browser.js b/src/index-browser.js
deleted file mode 100644
index 0524487..0000000
--- a/src/index-browser.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// version information 
-exports.version = { major: 4, minor: 0, build: 0 };
-
-// core stuff, always needed
-exports.deferred = require('./lib/deferred.js');
-exports.utils = require('./lib/utils.js');
-
-// only needed for xml metadata 
-exports.xml = require('./lib/xml.js');
-
-// only need in browser case
-exports.oData = require('./lib/odata.js');
-exports.store = require('./lib/store.js');
-exports.cache = require('./lib/cache.js');
-
-
-

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/index-node.js
----------------------------------------------------------------------
diff --git a/src/index-node.js b/src/index-node.js
deleted file mode 100644
index 85aea5b..0000000
--- a/src/index-node.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-var odatajs = {};
-
-odatajs.version = {
-    major: 4,
-    minor: 0,
-    build: 0
-};
-
-// core stuff, alway needed
-odatajs.deferred = require('./lib/deferred.js');
-odatajs.utils = require('./lib/utils.js');
-
-// only neede for xml metadata
-odatajs.xml = require('./lib/xml.js');
-
-// only need in browser case
-odatajs.oData = require('./lib/odata.js');
-odatajs.store = require('./lib/store.js');
-odatajs.cache = require('./lib/cache.js');
-
-if (typeof window !== 'undefined') {
-    //expose to browsers window object
-    window.odatajs = odatajs;
-} else {
-    //expose in commonjs style
-    odatajs.node = "node";
-    module.exports = odatajs;
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/index.js
----------------------------------------------------------------------
diff --git a/src/index.js b/src/index.js
deleted file mode 100644
index 28bf066..0000000
--- a/src/index.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-var odatajs = {};
-
-odatajs.version = {
-    major: 4,
-    minor: 0,
-    build: 0
-};
-
-// core stuff, alway needed
-odatajs.deferred = require('./lib/deferred.js');
-odatajs.utils = require('./lib/utils.js');
-
-// only neede for xml metadata
-odatajs.xml = require('./lib/ext/xml.js');
-
-// only need in browser case
-odatajs.oData = require('./lib/odata.js');
-odatajs.store = require('./lib/store.js');
-odatajs.cache = require('./lib/cache.js');
-
-if (typeof window !== 'undefined') {
-    //expose to browsers window object
-    window.odatajs = odatajs;
-} else {
-    //expose in commonjs style
-    odatajs.node = "node";
-    module.exports = odatajs;
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/cache.js
----------------------------------------------------------------------
diff --git a/src/lib/cache.js b/src/lib/cache.js
deleted file mode 100644
index dce74b6..0000000
--- a/src/lib/cache.js
+++ /dev/null
@@ -1,1445 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
- /** @module cache */
-
-//var odatajs = require('./odatajs/utils.js');
-var utils =  require('./utils.js');
-var deferred = require('./deferred.js');
-var storeReq = require('./store.js');
-var cacheSource = require('./cache/source.js');
-
-
-var assigned = utils.assigned;
-var delay = utils.delay;
-var extend = utils.extend;
-var djsassert = utils.djsassert;
-var isArray = utils.isArray;
-var normalizeURI = utils.normalizeURI;
-var parseInt10 = utils.parseInt10;
-var undefinedDefault = utils.undefinedDefault;
-
-var createDeferred = deferred.createDeferred;
-var DjsDeferred = deferred.DjsDeferred;
-
-
-var getJsonValueArraryLength = utils.getJsonValueArraryLength;
-var sliceJsonValueArray = utils.sliceJsonValueArray;
-var concatJsonValueArray = utils.concatJsonValueArray;
-
-
-
-/** Appends a page's data to the operation data.
- * @param {Object} operation - Operation with  (i)ndex, (c)ount and (d)ata.
- * @param {Object} page - Page with (i)ndex, (c)ount and (d)ata.
- */
-function appendPage(operation, page) {
-
-    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));
-}
-
-/** Returns the {(i)ndex, (c)ount} range for the intersection of x and y.
- * @param {Object} x - Range with (i)ndex and (c)ount members.
- * @param {Object} y - Range with (i)ndex and (c)ount members.
- * @returns {Object} The intersection (i)ndex and (c)ount; undefined if there is no intersection.
- */
-function intersectRanges(x, y) {
-
-    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;
-}
-
-/** Checks whether val is a defined number with value zero or greater.
- * @param {Number} val - Value to check.
- * @param {String} name - Parameter name to use in exception.
- * @throws Throws an exception if the check fails
- */
-function checkZeroGreater(val, name) {
-
-    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." };
-    }
-}
-
-/** Checks whether val is undefined or a number with value greater than zero.
- * @param {Number} val - Value to check.
- * @param {String} name - Parameter name to use in exception.
- * @throws Throws an exception if the check fails
- */
-function checkUndefinedGreaterThanZero(val, name) {
-
-    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." };
-        }
-    }
-}
-
-/** Checks whether val is undefined or a number
- * @param {Number} val - Value to check.
- * @param {String} name - Parameter name to use in exception.
- * @throws Throws an exception if the check fails
- */
-function checkUndefinedOrNumber(val, name) {
-    if (val !== undefined && (typeof val !== "number" || isNaN(val) || !isFinite(val))) {
-        throw { message: "'" + name + "' must be a number." };
-    }
-}
-
-/** Performs a linear search on the specified array and removes the first instance of 'item'.
- * @param {Array} arr - Array to search.
- * @param {*} item - Item being sought.
- * @returns {Boolean} true if the item was removed otherwise false
- */
-function removeFromArray(arr, item) {
-
-    var i, len;
-    for (i = 0, len = arr.length; i < len; i++) {
-        if (arr[i] === item) {
-            arr.splice(i, 1);
-            return true;
-        }
-    }
-
-    return false;
-}
-
-/** Estimates the size of an object in bytes.
- * Object trees are traversed recursively
- * @param {Object} object - Object to determine the size of.
- * @returns {Number} Estimated size of the object in bytes.
- */
-function estimateSize(object) {
-    var size = 0;
-    var type = typeof object;
-
-    if (type === "object" && object) {
-        for (var name in object) {
-            size += name.length * 2 + estimateSize(object[name]);
-        }
-    } else if (type === "string") {
-        size = object.length * 2;
-    } else {
-        size = 8;
-    }
-    return size;
-}
-
-/** Snaps low and high indices into page sizes and returns a range.
- * @param {Number} lowIndex - Low index to snap to a lower value.
- * @param {Number} highIndex - High index to snap to a higher value.
- * @param {Number} pageSize - Page size to snap to.
- * @returns {Object} A range with (i)ndex and (c)ount of elements.
- */
-function snapToPageBoundaries(lowIndex, highIndex, pageSize) {
-    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.
-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";
-
-/** Creates a new operation object.
- * @class DataCacheOperation
- * @param {Function} stateMachine - State machine that describes the specific behavior of the operation.
- * @param {DjsDeferred} promise - Promise for requested values.
- * @param {Boolean} isCancelable - Whether this operation can be canceled or not.
- * @param {Number} index - Index of first item requested.
- * @param {Number} count - Count of items requested.
- * @param {Array} data - Array with the items requested by the operation.
- * @param {Number} pending - Total number of pending prefetch records.
- * @returns {DataCacheOperation} A new data cache operation instance.
- */
-function DataCacheOperation(stateMachine, promise, isCancelable, index, count, data, pending) {
-
-   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;
-
-    /** Transitions this operation to the cancel state and sets the canceled flag to true.
-     * The function is a no-op if the operation is non-cancelable.
-     * @method DataCacheOperation#cancel
-     */
-    that.cancel = function cancel() {
-
-        if (!isCancelable) {
-            return;
-        }
-
-        var state = that.s;
-        if (state !== OPERATION_STATE_ERROR && state !== OPERATION_STATE_END && state !== OPERATION_STATE_CANCEL) {
-            that.canceled = true;
-            that.transition(OPERATION_STATE_CANCEL, stateData);
-        }
-    };
-
-    /** Transitions this operation to the end state.
-     * @method DataCacheOperation#complete
-     */
-    that.complete = function () {
-
-        djsassert(that.s !== OPERATION_STATE_END, "DataCacheOperation.complete() - operation is in the end state", that);
-        that.transition(OPERATION_STATE_END, stateData);
-    };
-
-    /** Transitions this operation to the error state.
-     * @method DataCacheOperation#error
-     */
-    that.error = function (err) {
-        if (!that.canceled) {
-            djsassert(that.s !== OPERATION_STATE_END, "DataCacheOperation.error() - operation is in the end state", that);
-            djsassert(that.s !== OPERATION_STATE_ERROR, "DataCacheOperation.error() - operation is in the error state", that);
-            that.transition(OPERATION_STATE_ERROR, err);
-        }
-    };
-
-    /** Executes the operation's current state in the context of a new cache state.
-     * @method DataCacheOperation#run
-     * @param {Object} state - New cache state.
-     */
-    that.run = function (state) {
-
-        cacheState = state;
-        that.transition(that.s, stateData);
-    };
-
-    /** Transitions this operation to the wait state.
-     * @method DataCacheOperation#wait
-     */
-    that.wait = function (data) {
-
-        djsassert(that.s !== OPERATION_STATE_END, "DataCacheOperation.wait() - operation is in the end state", that);
-        that.transition(OPERATION_STATE_WAIT, data);
-    };
-
-    /** State machine that describes all operations common behavior.
-     * @method DataCacheOperation#operationStateMachine
-     * @param {Object} opTargetState - Operation state to transition to.
-     * @param {Object} cacheState - Current cache state.
-     * @param {Object} [data] - Additional data passed to the state.
-     */
-    var operationStateMachine = function (opTargetState, cacheState, data) {
-
-        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();
-                that.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);
-                that.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.
-
-                if (true) {
-                    // Check that the state machine actually handled the sate.
-                    var handled = stateMachine(that, opTargetState, cacheState, data);
-                    djsassert(handled, "Bad operation state: " + opTargetState + " cacheState: " + cacheState, this);
-                } else {
-
-                    stateMachine(that, opTargetState, cacheState, data);
-
-                }
-
-                break;
-        }
-    };
-
-
-
-    /** Transitions this operation to a new state.
-     * @method DataCacheOperation#transition
-     * @param {Object} state - State to transition the operation to.
-     * @param {Object} [data] - 
-     */
-    that.transition = function (state, data) {
-        that.s = state;
-        stateData = data;
-        operationStateMachine(state, cacheState, data);
-    };
-    
-    return that;
-}
-
-/** Fires a resolved notification as necessary.
- * @method DataCacheOperation#fireResolved
- */
-DataCacheOperation.prototype.fireResolved = function () {
-
-    // Fire the resolve just once.
-    var p = this.p;
-    if (p) {
-        this.p = null;
-        p.resolve(this.d);
-    }
-};
-
-/** Fires a rejected notification as necessary.
- * @method DataCacheOperation#fireRejected
- */
-DataCacheOperation.prototype.fireRejected = function (reason) {
-
-    // Fire the rejection just once.
-    var p = this.p;
-    if (p) {
-        this.p = null;
-        p.reject(reason);
-    }
-};
-
-/** Fires a canceled notification as necessary.
- * @method DataCacheOperation#fireCanceled
- */
-DataCacheOperation.prototype.fireCanceled = function () {
-
-    this.fireRejected({ canceled: true, message: "Operation canceled" });
-};
-
-
-/** Creates a data cache for a collection that is efficiently loaded on-demand.
- * @class DataCache
- * @param options - Options for the data cache, including name, source, pageSize,
- * prefetchSize, cacheSize, storage mechanism, and initial prefetch and local-data handler.
- * @returns {DataCache} A new data cache instance.
- */
-function DataCache(options) {
-
-    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 cacheSource.ODataCacheSource(options);
-    }
-    source.options = options;
-
-    // Create a cache local store.
-    var store = storeReq.createStore(options.name, options.mechanism);
-
-    var that = this;
-
-    that.onidle = options.idle;
-    that.stats = stats;
-
-    /** Counts the number of items in the collection.
-     * @method DataCache#count
-     * @returns {Object} A promise with the number of items.
-     */
-    that.count = function () {
-
-        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(), {
-
-             /** Aborts the count operation (used within promise callback)
-              * @method DataCache#cancelCount
-              */
-            cancel: function () {
-               
-                if (request) {
-                    canceled = true;
-                    request.abort();
-                    request = null;
-                }
-            }
-        });
-    };
-
-    /** Cancels all running operations and clears all local data associated with this cache.
-     * 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.
-     * @method DataCache#clear
-     * @returns {Object} A promise that has no value and can't be canceled.
-     */
-    that.clear = function () {
-
-        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;
-    };
-
-    /** Filters the cache data based a predicate.
-     * Specifying a negative count value will yield all the items in the cache that satisfy the predicate.
-     * @method DataCache#filterForward
-     * @param {Number} index - The index of the item to start filtering forward from.
-     * @param {Number} count - Maximum number of items to include in the result.
-     * @param {Function} predicate - Callback function returning a boolean that determines whether an item should be included in the result or not.
-     * @returns {DjsDeferred} A promise for an array of results.
-     */
-    that.filterForward = function (index, count, predicate) {
-        return filter(index, count, predicate, false);
-    };
-
-    /** Filters the cache data based a predicate.
-     * Specifying a negative count value will yield all the items in the cache that satisfy the predicate.
-     * @method DataCache#filterBack
-     * @param {Number} index - The index of the item to start filtering backward from.
-     * @param {Number} count - Maximum number of items to include in the result.
-     * @param {Function} predicate - Callback function returning a boolean that determines whether an item should be included in the result or not.
-     * @returns {DjsDeferred} A promise for an array of results.
-     */
-    that.filterBack = function (index, count, predicate) {
-        return filter(index, count, predicate, true);
-    };
-
-    /** Reads a range of adjacent records.
-     * 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.
-     * @method DataCache#readRange
-     * @param {Number} index - Zero-based index of record range to read.
-     * @param {Number} count - Number of records in the range.
-     * @returns {DjsDeferred} A promise for an array of records; less records may be returned if the
-     * end of the collection is found.
-     */
-    that.readRange = function (index, count) {
-
-        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 () {
-                /** Aborts the readRange operation  (used within promise callback)
-                 * @method DataCache#cancelReadRange
-                 */
-                op.cancel();
-            }
-        });
-    };
-
-    /** Creates an Observable object that enumerates all the cache contents.
-     * @method DataCache#toObservable
-     * @returns A new Observable object that enumerates all the cache contents.
-     */
-    that.ToObservable = that.toObservable = function () {
-        if ( !utils.inBrowser()) {
-            throw { message: "Only in broser supported" };
-        }
-
-        if (!window.Rx || !window.Rx.Observable) {
-            throw { message: "Rx library not available - include rx.js" };
-        }
-
-        if (cacheFailure) {
-            throw cacheFailure;
-        }
-
-        //return window.Rx.Observable.create(function (obs) {
-        return new window.Rx.Observable(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.next(data.value[i]);
-                        obs.onNext(data.value[i]);
-                    }
-
-                    if (data.value.length < pageSize) {
-                        //obs.completed();
-                        obs.onCompleted();
-                    } else {
-                        index += pageSize;
-                        that.readRange(index, pageSize).then(successCallback, errorCallback);
-                    }
-                }
-            };
-
-            that.readRange(index, pageSize).then(successCallback, errorCallback);
-
-            return { Dispose: function () { 
-                obs.dispose(); // otherwise the check isStopped obs.onNext(data.value[i]);
-                disposed = true; 
-                } };
-        });
-    };
-
-    /** Creates a function that handles a callback by setting the cache into failure mode.
-     * @method DataCache~cacheFailureCallback
-     * @param {String} message - Message text.
-     * @returns {Function} Function to use as error callback.
-     * This function will specifically handle problems with critical store resources
-     * during cache initialization.
-     */
-    var cacheFailureCallback = function (message) {
-        
-
-        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.
-            djsassert(prefetchOperations.length === 0, "prefetchOperations.length === 0");
-            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;
-        };
-    };
-
-    /** Updates the cache's state and signals all pending operations of the change.
-     * @method DataCache~changeState
-     * @param {Object} newState - New cache state.
-     * This method is a no-op if the cache's current state and the new state are the same.
-     */
-    var changeState = function (newState) {
-
-        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);
-            }
-        }
-    };
-
-    /** Removes all the data stored in the cache.
-     * @method DataCache~clearStore
-     * @returns {DjsDeferred} A promise with no value.
-     */
-    var clearStore = function () {
-        djsassert(state === CACHE_STATE_DESTROY || state === CACHE_STATE_INIT, "DataCache.clearStore() - cache is not on the destroy or initialize state, current sate = " + state);
-
-        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;
-    };
-
-    /** Removes an operation from the caches queues and changes the cache state to idle.
-     * @method DataCache~dequeueOperation
-     * @param {DataCacheOperation} operation - Operation to dequeue.
-     * This method is used as a handler for the operation's oncomplete event.
-    */
-    var dequeueOperation = function (operation) {
-
-        var removed = removeFromArray(clearOperations, operation);
-        if (!removed) {
-            removed = removeFromArray(readOperations, operation);
-            if (!removed) {
-                removeFromArray(prefetchOperations, operation);
-            }
-        }
-
-        pendingOperations--;
-        changeState(CACHE_STATE_IDLE);
-    };
-
-    /** Requests data from the cache source.
-     * @method DataCache~fetchPage
-     * @param {Number} start - Zero-based index of items to request.
-     * @returns {DjsDeferred} A promise for a page object with (i)ndex, (c)ount, (d)ata.
-     */
-    var fetchPage = function (start) {
-
-        djsassert(state !== CACHE_STATE_DESTROY, "DataCache.fetchPage() - cache is on the destroy state");
-        djsassert(state !== CACHE_STATE_IDLE, "DataCache.fetchPage() - cache is on the idle state");
-
-        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;
-                }
-            }
-        });
-    };
-
-    /** Filters the cache data based a predicate.
-     * @method DataCache~filter
-     * @param {Number} index - The index of the item to start filtering from.
-     * @param {Number} count - Maximum number of items to include in the result.
-     * @param {Function} predicate - Callback function returning a boolean that determines whether an item should be included in the result or not.
-     * @param {Boolean} backwards - True if the filtering should move backward from the specified index, falsey otherwise.
-     * Specifying a negative count value will yield all the items in the cache that satisfy the predicate.
-     * @returns {DjsDeferred} A promise for an array of results.
-     */
-    var filter = function (index, count, predicate, backwards) {
-
-        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(), {
-            /** Aborts the filter operation (used within promise callback)
-            * @method DataCache#cancelFilter
-             */
-            cancel: function () {
-
-                if (pendingReadRange) {
-                    pendingReadRange.cancel();
-                }
-                canceled = true;
-            }
-        });
-    };
-
-    /** Fires an onidle event if any functions are assigned.
-     * @method DataCache~fireOnIdle
-    */
-    var fireOnIdle = function () {
-
-        if (that.onidle && pendingOperations === 0) {
-            that.onidle();
-        }
-    };
-
-    /** Creates and starts a new prefetch operation.
-     * @method DataCache~prefetch
-     * @param {Number} start - Zero-based index of the items to prefetch.
-     * 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).
-    */
-    var prefetch = function (start) {
-        
-
-        if (allDataLocal || prefetchSize === 0 || overflowed) {
-            return;
-        }
-
-        djsassert(state === CACHE_STATE_READ, "DataCache.prefetch() - cache is not on the read state, current state: " + state);
-
-        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);
-        }
-    };
-
-    /** Queues an operation and runs it.
-     * @param {DataCacheOperation} op - Operation to queue.
-     * @param {Array} queue - Array that will store the operation.
-     */
-    var queueAndStart = function (op, queue) {
-
-        op.oncomplete = dequeueOperation;
-        queue.push(op);
-        pendingOperations++;
-        op.run(state);
-    };
-
-    /** Requests a page from the cache local store.
-     * @method DataCache~readPage    
-     * @param {Number} key - Zero-based index of the reuqested page.
-     * @returns {DjsDeferred} A promise for a found flag and page object with (i)ndex, (c)ount, (d)ata, and (t)icks.
-     */
-    var readPage = function (key) {
-
-        djsassert(state !== CACHE_STATE_DESTROY, "DataCache.readPage() - cache is on the destroy state");
-
-        var canceled = false;
-        var deferred = extend(new DjsDeferred(), {
-            /** Aborts the readPage operation. (used within promise callback)
-             * @method DataCache#cancelReadPage
-             */
-            cancel: function () {
-                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;
-    };
-
-    /** Saves a page to the cache local store.
-     * @method DataCache~savePage    
-     * @param {Number} key - Zero-based index of the requested page.
-     * @param {Object} page - Object with (i)ndex, (c)ount, (d)ata, and (t)icks.
-     * @returns {DjsDeferred} A promise with no value.
-     */
-    var savePage = function (key, page) {
-
-        djsassert(state !== CACHE_STATE_DESTROY, "DataCache.savePage() - cache is on the destroy state");
-        djsassert(state !== CACHE_STATE_IDLE, "DataCache.savePage() - cache is on the idle state");
-
-        var canceled = false;
-
-        var deferred = extend(new DjsDeferred(), {
-            /** Aborts the savePage operation. (used within promise callback)
-             * @method DataCache#cancelReadPage
-             */
-            cancel: function () {
-                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;
-    };
-
-    /** Saves the cache's current settings to the local store.
-     * @method DataCache~saveSettings    
-     * @param {Function} success - Success callback.
-     * @param {Function} error - Errror callback.
-     */
-    var saveSettings = function (success, error) {
-
-        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);
-    };
-
-    /** Creates a function that handles a store error.
-     * @method DataCache~storeFailureCallback    
-     * @param {DjsDeferred} deferred - Deferred object to resolve.
-     * @returns {Function} Function to use as error callback.
-    
-     * This function will specifically handle problems when interacting with the store.
-     */
-    var storeFailureCallback = function (deferred/*, message*/) {
-        
-
-        return function (/*error*/) {
-            // var console = windo1w.console;
-            // if (console && console.log) {
-            //    console.log(message);
-            //    console.dir(error);
-            // }
-            deferred.resolve(false);
-        };
-    };
-
-    /** Updates the cache's settings based on a page object.
-     * @method DataCache~updateSettings    
-     * @param {Object} page - Object with (i)ndex, (c)ount, (d)ata.
-     * @param {Number} pageBytes - Size of the page in bytes.
-     */
-    var updateSettings = function (page, pageBytes) {
-
-        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;
-        }
-    };
-
-    /** State machine describing the behavior for cancelling a read or prefetch operation.
-     * @method DataCache~cancelStateMachine    
-     * @param {DataCacheOperation} operation - Operation being run.
-     * @param {Object} opTargetState - Operation state to transition to.
-     * @param {Object} cacheState - Current cache state.
-     * @param {Object} [data] - 
-     * This state machine contains behavior common to read and prefetch operations.
-     */
-    var cancelStateMachine = function (operation, opTargetState, cacheState, data) {
-        
-
-        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;
-    };
-
-    /** State machine describing the behavior of a clear operation.
-     * @method DataCache~destroyStateMachine    
-     * @param {DataCacheOperation} operation - Operation being run.
-     * @param {Object} opTargetState - Operation state to transition to.
-     * @param {Object} cacheState - Current cache state.
-    
-     * Clear operations have the highest priority and can't be interrupted by other operations; however,
-     * they will preempt any other operation currently executing.
-     */
-    var destroyStateMachine = function (operation, opTargetState, cacheState) {
-        
-
-        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;
-    };
-
-    /** State machine describing the behavior of a prefetch operation.
-     * @method DataCache~prefetchStateMachine    
-     * @param {DataCacheOperation} operation - Operation being run.
-     * @param {Object} opTargetState - Operation state to transition to.
-     * @param {Object} cacheState - Current cache state.
-     * @param {Object} [data] - 
-    
-     *  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.
-     */
-    var prefetchStateMachine = function (operation, opTargetState, cacheState, data) {
-        
-
-        // 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;
-    };
-
-    /** State machine describing the behavior of a read operation.
-     * @method DataCache~readStateMachine    
-     * @param {DataCacheOperation} operation - Operation being run.
-     * @param {Object} opTargetState - Operation state to transition to.
-     * @param {Object} cacheState - Current cache state.
-     * @param {Object} [data] - 
-    
-     * 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.
-     */
-    var readStateMachine = function (operation, opTargetState, cacheState, data) {
-        
-
-        // 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.
-                    djsassert(state == CACHE_STATE_IDLE || state === CACHE_STATE_PREFETCH, "DataCache.readStateMachine() - cache is not on the read or idle state.");
-                    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;
-    };
-
-    /** State machine describing the behavior for reading and saving data into the cache.
-     * @method DataCache~readSaveStateMachine    
-     * @param {DataCacheOperation} operation - Operation being run.
-     * @param {Object} opTargetState - Operation state to transition to.
-     * @param {Object} cacheState - Current cache state.
-     * @param {Object} [data] - 
-     * @param {Boolean} isPrefetch - Flag indicating whether a read (false) or prefetch (true) operation is running.
-     * This state machine contains behavior common to read and prefetch operations.
-    */
-    var readSaveStateMachine = function (operation, opTargetState, cacheState, data, isPrefetch) {
-
-        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;
-}
-
-/** Creates a data cache for a collection that is efficiently loaded on-demand.
- * @param options 
- * Options for the data cache, including name, source, pageSize, TODO check doku
- * prefetchSize, cacheSize, storage mechanism, and initial prefetch and local-data handler.
- * @returns {DataCache} A new data cache instance.
- */
-function createDataCache (options) {
-    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);
-}
-
-
-/** estimateSize (see {@link estimateSize}) */
-exports.estimateSize = estimateSize;
-
-/** createDataCache */  
-exports.createDataCache = createDataCache;
-
-
-

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/cache/source.js
----------------------------------------------------------------------
diff --git a/src/lib/cache/source.js b/src/lib/cache/source.js
deleted file mode 100644
index 08dea0a..0000000
--- a/src/lib/cache/source.js
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
- /** @module cache/source */
- 
-var utils = require("./../utils.js");
-var odataRequest = require("./../odata.js");
-
-var parseInt10 = utils.parseInt10;
-var normalizeURICase = utils.normalizeURICase;
-
-
-
-
-/** Appends the specified escaped query option to the specified URI.
- * @param {String} uri - URI to append option to.
- * @param {String} queryOption - Escaped query option to append.
- */
-function appendQueryOption(uri, queryOption) {
-    var separator = (uri.indexOf("?") >= 0) ? "&" : "?";
-    return uri + separator + queryOption;
-}
-
-/** Appends the specified segment to the given URI.
- * @param {String} uri - URI to append a segment to.
- * @param {String} segment - Segment to append.
- * @returns {String} The original URI with a new segment appended.
- */
-function appendSegment(uri, segment) {
-    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;
-}
-
-/** Builds a request object to GET the specified URI.
- * @param {String} uri - URI for request.
- * @param {Object} options - Additional options.
- */
-function buildODataRequest(uri, options) {
-    return {
-        method: "GET",
-        requestUri: uri,
-        user: options.user,
-        password: options.password,
-        enableJsonpCallback: options.enableJsonpCallback,
-        callbackParameterName: options.callbackParameterName,
-        formatQueryString: options.formatQueryString
-    };
-}
-
-/** Finds the index where the value of a query option starts.
- * @param {String} uri - URI to search in.
- * @param {String} name - Name to look for.
- * @returns {Number} The index where the query option starts.
- */
-function findQueryOptionStart(uri, name) {
-    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;
-}
-
-/** Gets data from an OData service.
- * @param {String} uri - URI to the OData service.
- * @param {Object} options - Object with additional well-known request options.
- * @param {Function} success - Success callback.
- * @param {Function} error - Error callback.
- * @returns {Object} Object with an abort method.
- */
-function queryForData (uri, options, success, error) {
-    return queryForDataInternal(uri, options, {}, success, error);
-}
-
-/** Gets data from an OData service taking into consideration server side paging.
- * @param {String} uri - URI to the OData service.
- * @param {Object} options - Object with additional well-known request options.
- * @param {Array} data - Array that stores the data provided by the OData service.
- * @param {Function} success - Success callback.
- * @param {Function} error - Error callback.
- * @returns {Object} Object with an abort method.
- */
-function queryForDataInternal(uri, options, data, success, error) {
-
-    var request = buildODataRequest(uri, options);
-    var currentRequest = odataRequest.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();
-        }
-    };
-}
-
-/** Creates a data cache source object for requesting data from an OData service.
- * @class ODataCacheSource
- * @param options - Options for the cache data source.
- * @returns {ODataCacheSource} A new data cache source instance.
- */
-function ODataCacheSource (options) {
-    var that = this;
-    var uri = options.source;
-    
-    that.identifier = normalizeURICase(encodeURI(decodeURI(uri)));
-    that.options = options;
-
-    /** Gets the number of items in the collection.
-     * @method ODataCacheSource#count
-     * @param {Function} success - Success callback with the item count.
-     * @param {Function} error - Error callback.
-     * @returns {Object} Request object with an abort method.
-     */
-    that.count = function (success, error) {
-        var options = that.options;
-        return odataRequest.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
-        );
-    };
-    
-    /** Gets a number of consecutive items from the collection.
-     * @method ODataCacheSource#read
-     * @param {Number} index - Zero-based index of the items to retrieve.
-     * @param {Number} count - Number of items to retrieve.
-     * @param {Function} success - Success callback with the requested items.
-     * @param {Function} error - Error callback.
-     * @returns {Object} Request object with an abort method.
-    */
-    that.read = function (index, count, success, error) {
-
-        var queryOptions = "$skip=" + index + "&$top=" + count;
-        return queryForData(appendQueryOption(uri, queryOptions), that.options, success, error);
-    };
-
-    return that;
-}
-
-
-
-/** ODataCacheSource (see {@link ODataCacheSource}) */
-exports.ODataCacheSource = ODataCacheSource;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/deferred.js
----------------------------------------------------------------------
diff --git a/src/lib/deferred.js b/src/lib/deferred.js
deleted file mode 100644
index 520a857..0000000
--- a/src/lib/deferred.js
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
-/** @module odatajs/deferred */
-
-
-
-/** Creates a new function to forward a call.
- * @param {Object} thisValue - Value to use as the 'this' object.
- * @param {String} name - Name of function to forward to.
- * @param {Object} returnValue - Return value for the forward call (helps keep identity when chaining calls).
- * @returns {Function} A new function that will forward a call.
- */
-function forwardCall(thisValue, name, returnValue) {
-    return function () {
-        thisValue[name].apply(thisValue, arguments);
-        return returnValue;
-    };
-}
-
-/** Initializes a new DjsDeferred object.
- * <ul>
- * <li> Compability Note A - Ordering of callbacks through chained 'then' invocations <br>
- *
- * 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.
- * </li>
- * <li>Compability Note B - Fulfillment value <br>
- *
- * 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.
- * </li></ul>
- * @class DjsDeferred 
- */
- function DjsDeferred() {
-    this._arguments = undefined;
-    this._done = undefined;
-    this._fail = undefined;
-    this._resolved = false;
-    this._rejected = false;
-}
-
-
-DjsDeferred.prototype = {
-
-    /** Adds success and error callbacks for this deferred object.
-     * See Compatibility Note A.
-     * @method DjsDeferred#then
-     * @param {function} [fulfilledHandler] - Success callback ( may be null)
-     * @param {function} [errorHandler] - Error callback ( may be null)
-     */
-    then: function (fulfilledHandler, errorHandler) {
-
-        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;
-    },
-
-    /** Invokes success callbacks for this deferred object.
-     * All arguments are forwarded to success callbacks.
-     * @method DjsDeferred#resolve
-     */
-    resolve: function (/* args */) {
-        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;
-        }
-    },
-
-    /** Invokes error callbacks for this deferred object.
-     * All arguments are forwarded to error callbacks.
-     * @method DjsDeferred#reject
-     */
-    reject: function (/* args */) {
-        
-        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;
-        }
-    },
-
-    /** Returns a version of this object that has only the read-only methods available.
-     * @method DjsDeferred#promise
-     * @returns An object with only the promise object.
-     */
-
-    promise: function () {
-        var result = {};
-        result.then = forwardCall(this, "then", result);
-        return result;
-    }
-};
-
-/** Creates a deferred object.
- * @returns {DjsDeferred} A new deferred object. If jQuery is installed, then a jQueryDeferred object is returned, which provides a superset of features.
-*/
-function createDeferred() {
-    if (window.jQuery && window.jQuery.Deferred) {
-        return new window.jQuery.Deferred();
-    } else {
-        return new DjsDeferred();
-    }
-}
-
-
-
-
-/** createDeferred (see {@link module:datajs/deferred~createDeferred}) */
-exports.createDeferred = createDeferred;
-
-/** DjsDeferred (see {@link DjsDeferred}) */
-exports.DjsDeferred = DjsDeferred;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/27f830e6/src/lib/odata.js
----------------------------------------------------------------------
diff --git a/src/lib/odata.js b/src/lib/odata.js
deleted file mode 100644
index 6f660f6..0000000
--- a/src/lib/odata.js
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-'use strict';
-
- /** @module odata */
-
-// Imports
-var odataUtils    = exports.utils     = require('./odata/odatautils.js');
-var odataHandler  = exports.handler   = require('./odata/handler.js');
-var odataMetadata = exports.metadata  = require('./odata/metadata.js');
-var odataNet      = exports.net       = require('./odata/net.js');
-var odataJson     = exports.json      = require('./odata/json.js');
-                    exports.batch     = require('./odata/batch.js');
-                    
-
-
-var utils = require('./utils.js');
-var assigned = utils.assigned;
-
-var defined = utils.defined;
-var throwErrorCallback = utils.throwErrorCallback;
-
-var invokeRequest = odataUtils.invokeRequest;
-var MAX_DATA_SERVICE_VERSION = odataHandler.MAX_DATA_SERVICE_VERSION;
-var prepareRequest = odataUtils.prepareRequest;
-var metadataParser = odataMetadata.metadataParser;
-
-// CONTENT START
-
-var handlers = [odataJson.jsonHandler, odataHandler.textHandler];
-
-/** Dispatches an operation to handlers.
- * @param {String} handlerMethod - Name of handler method to invoke.
- * @param {Object} requestOrResponse - request/response argument for delegated call.
- * @param {Object} context - context argument for delegated call.
- */
-function dispatchHandler(handlerMethod, requestOrResponse, context) {
-
-    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" };
-    }
-}
-
-/** Default success handler for OData.
- * @param data - Data to process.
- */
-exports.defaultSuccess = function (data) {
-
-    window.alert(window.JSON.stringify(data));
-};
-
-exports.defaultError = throwErrorCallback;
-
-exports.defaultHandler = {
-
-        /** Reads the body of the specified response by delegating to JSON handlers.
-        * @param response - Response object.
-        * @param context - Operation context.
-        */
-        read: function (response, context) {
-
-            if (response && assigned(response.body) && response.headers["Content-Type"]) {
-                dispatchHandler("read", response, context);
-            }
-        },
-
-        /** Write the body of the specified request by delegating to JSON handlers.
-        * @param request - Reques tobject.
-        * @param context - Operation context.
-        */
-        write: function (request, context) {
-
-            dispatchHandler("write", request, context);
-        },
-
-        maxDataServiceVersion: MAX_DATA_SERVICE_VERSION,
-        accept: "application/json;q=0.9, */*;q=0.1"
-    };
-
-exports.defaultMetadata = []; //TODO check why is the defaultMetadata an Array? and not an Object.
-
-/** Reads data from the specified URL.
- * @param urlOrRequest - URL to read data from.
- * @param {Function} [success] - 
- * @param {Function} [error] - 
- * @param {Object} [handler] - 
- * @param {Object} [httpClient] - 
- * @param {Object} [metadata] - 
- */
-exports.read = function (urlOrRequest, success, error, handler, httpClient, metadata) {
-
-    var request;
-    if (urlOrRequest instanceof String || typeof urlOrRequest === "string") {
-        request = { requestUri: urlOrRequest };
-    } else {
-        request = urlOrRequest;
-    }
-
-    return exports.request(request, success, error, handler, httpClient, metadata);
-};
-
-/** Sends a request containing OData payload to a server.
- * @param {Object} request - Object that represents the request to be sent.
- * @param {Function} [success] - 
- * @param {Function} [error] - 
- * @param {Object} [handler] - 
- * @param {Object} [httpClient] - 
- * @param {Object} [metadata] - 
- */
-exports.request = function (request, success, error, handler, httpClient, metadata) {
-
-    success = success || exports.defaultSuccess;
-    error = error || exports.defaultError;
-    handler = handler || exports.defaultHandler;
-    httpClient = httpClient || odataNet.defaultHttpClient;
-    metadata = metadata || exports.defaultMetadata;
-
-    // Augment the request with additional defaults.
-    request.recognizeDates = utils.defined(request.recognizeDates, odataJson.jsonHandler.recognizeDates);
-    request.callbackParameterName = utils.defined(request.callbackParameterName, odataNet.defaultHttpClient.callbackParameterName);
-    request.formatQueryString = utils.defined(request.formatQueryString, odataNet.defaultHttpClient.formatQueryString);
-    request.enableJsonpCallback = utils.defined(request.enableJsonpCallback, odataNet.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 {
-        odataUtils.prepareRequest(request, handler, context);
-        return odataUtils.invokeRequest(request, success, error, handler, httpClient, context);
-    } catch (err) {
-        // errors in success handler for sync requests are catched here and result in error handler calls. 
-        // So here we fix this and throw that error further.
-        if (err.bIsSuccessHandlerError) {
-            throw err;
-        } else {
-            error(err);
-        }
-    }
-
-};
-
-/** Parses the csdl metadata to ODataJS metatdata format. This method can be used when the metadata is retrieved using something other than odatajs
- * @param {string} csdlMetadataDocument - A string that represents the entire csdl metadata.
- * @returns {Object} An object that has the representation of the metadata in odatajs format.
- */
-exports.parseMetadata = function (csdlMetadataDocument) {
-
-    return metadataParser(null, csdlMetadataDocument);
-};
-
-// Configure the batch handler to use the default handler for the batch parts.
-exports.batch.batchHandler.partHandler = exports.defaultHandler;
-exports.metadataHandler =  odataMetadata.metadataHandler;
-exports.jsonHandler =  odataJson.jsonHandler;