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 2014/10/20 09:39:18 UTC

[5/5] git commit: [OLINGO-442] Create packaging tool and remove browserify

[OLINGO-442] Create packaging tool and remove browserify


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/87e35975
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/tree/87e35975
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/diff/87e35975

Branch: refs/heads/master
Commit: 87e35975d7c71819e69d591daba23f5c8c07b1f3
Parents: 5e973c8
Author: Sven Kobler <sv...@sap.com>
Authored: Mon Oct 20 09:26:58 2014 +0200
Committer: Sven Kobler <sv...@sap.com>
Committed: Mon Oct 20 09:38:52 2014 +0200

----------------------------------------------------------------------
 odatajs/Gruntfile.js                            |  121 +-
 .../stripheader/package.json                    |   42 -
 .../stripheader/stripheader.js                  |   42 -
 .../custom-tasks/rat/extern-tools/info.md       |    4 +-
 .../grunt-config/custom-tasks/rat/package.json  |   18 -
 odatajs/grunt-config/custom-tasks/toBrowser.js  |   23 +
 .../custom-tasks/toBrowser/toBrowser.js         |   78 ++
 .../custom-tasks/toBrowser/wrapper-tpl.js       |   43 +
 odatajs/grunt-config/release.js                 |   28 +-
 odatajs/grunt-config/sign.js                    |    1 -
 odatajs/package.json                            |    4 +-
 odatajs/src/browser-lib-tpl.js                  |   43 +
 odatajs/src/index-browser.js                    |   36 +
 odatajs/src/index-node.js                       |   47 +
 odatajs/src/index.js                            |   21 +-
 odatajs/src/lib/cache.js                        |   11 +-
 odatajs/src/lib/cache/source.js                 |    2 +-
 odatajs/src/lib/deferred.js                     |  189 +++
 odatajs/src/lib/odata.js                        |    4 +-
 odatajs/src/lib/odata/batch.js                  |    4 +-
 odatajs/src/lib/odata/handler.js                |    4 +-
 odatajs/src/lib/odata/json.js                   |    4 +-
 odatajs/src/lib/odata/metadata.js               |    4 +-
 odatajs/src/lib/odata/net.js                    |    2 +-
 odatajs/src/lib/odata/odatautils.js             | 1265 ++++++++++++++++++
 odatajs/src/lib/odata/utils.js                  | 1265 ------------------
 odatajs/src/lib/odatajs/deferred.js             |  189 ---
 odatajs/src/lib/odatajs/utils.js                |  582 --------
 odatajs/src/lib/odatajs/xml.js                  |  816 -----------
 odatajs/src/lib/store/dom.js                    |    2 +-
 odatajs/src/lib/store/indexeddb.js              |    2 +-
 odatajs/src/lib/store/memory.js                 |    2 +-
 odatajs/src/lib/utils.js                        |  582 ++++++++
 odatajs/src/lib/xml.js                          |  816 +++++++++++
 odatajs/test-node/test.html                     |   29 +
 odatajs/test-node/test.js                       |   22 +
 odatajs/tests/odata-qunit-tests.htm             |    2 +-
 olingojs-4.0.0-beta-01.exports.json             |  917 +++++++++++++
 38 files changed, 4194 insertions(+), 3072 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/Gruntfile.js
----------------------------------------------------------------------
diff --git a/odatajs/Gruntfile.js b/odatajs/Gruntfile.js
index 5b66d60..435584d 100644
--- a/odatajs/Gruntfile.js
+++ b/odatajs/Gruntfile.js
@@ -26,56 +26,53 @@ module.exports = function(grunt) {
      (pkg.postfix.length > 0 ? "-" : "") + pkg.postfix +
      (pkg.releaseCandidate.length > 0 ? "-" : "") + pkg.releaseCandidate;
 
+  //options
   var init = {
     pkg: pkg,
     banner: grunt.file.read('src/banner.txt'),
     artifactname : artifactname,
 
-    "browserify": { // convert code from nodejs style to browser style
-      src: {
-        files: { 'build/lib/<%= artifactname %>.js': ['src/index.js'] },
-        options: { // remove apache license headers before contatenating
-          transform: ['./grunt-config/browserify_transforms/stripheader/stripheader.js'], 
-        }
+    "toBrowser" : {
+      "release" : {
+        options: { index : "src/index-browser.js" },
+        files: [{ 
+            src: ["src/lib/**/*.js"], 
+            dest: "build/lib/<%= artifactname %>.js",
+        }]
       }
     },
     "uglify": { // uglify and minify the lib
       options: {
         sourceMap : true,
-        sourceMapName : 'build/lib/<%= artifactname %>.map',
+        sourceMapName : "build/lib/<%= artifactname %>.map",
         sourceMapIncludeSources : true,
       },
       build: {
-        src: 'build/lib/<%= artifactname %>.js',
-        dest: 'build/lib/<%= artifactname %>.min.js'
+        src: "build/lib/<%= artifactname %>.js",
+        dest: "build/lib/<%= artifactname %>.min.js"
       }
     },
     "concat" : { // add the apache license headers
       options : {
-        banner : '<%= banner %>'
+        banner : "<%= banner %>"
       },
       licence: {
-        src: 'build/lib/<%= artifactname %>.js',
-        dest: 'build/lib/<%= artifactname %>.js',
+        src: "build/lib/<%= artifactname %>.js",
+        dest: "build/lib/<%= artifactname %>.js",
       },
       licence_min: {
-        src: 'build/lib/<%= artifactname %>.min.js',
-        dest: 'build/lib/<%= artifactname %>.min.js',
-      },
-      src: {
-        src: ['src/**/*.js'], 
-        dest: 'build/lib/<%= artifactname %>.js',
+        src: "build/lib/<%= artifactname %>.min.js",
+        dest: "build/lib/<%= artifactname %>.min.js",
       },
-
     },
-    "jsdoc" : { // generate documentation
+    "jsdoc" : {
         src : {
-            src: ['src/**/*.js'], 
-            options: { destination: 'build/doc-src', verbose : false }
+            src: ["src/**/*.js"], 
+            options: { destination: "build/doc-src", verbose : false }
         },
         test : {
-            src: ['tests/**/*.js'], 
-            options: { destination: 'build/doc-test', verbose : false }
+            src: ["tests/**/*.js"], 
+            options: { destination: "build/doc-test", verbose : false }
         }
     },
     "nugetpack" : { // create nuget pagckage
@@ -84,57 +81,43 @@ module.exports = function(grunt) {
             dest: 'build/'
         }
     },
-    'copy' : {
-      'to-latest' : {
+    "copy" : {
+      "to-latest" : {
         files: [
           { 
-            src :'build/lib/<%= artifactname %>.js',
-            dest: 'build/lib/odatajs-latest.js' },
-          ]
-        }
-      
+            src :"build/lib/<%= artifactname %>.js",
+            dest: "build/lib/odatajs-latest.js" },
+        ]
+      }
     },
     "npm-clean": {
       options: {force: true},
       "build": {
-        src: [ "build"],
-      },
-      "lib": {
-        src: [ "build/lib"]
-      },
-      "tmp": {
-        src: [ "build/tmp"]
-      },
-      "doc": {
-        src: ["build/doc"],
-      },
-      "doc-test": {
-        src: ["build/doc-test"],
+        src: [ "build"]
       },
     },
     "curl": {
-      'license': {
+      "license": {
         src: {
-          url: 'http://apache.org/licenses/LICENSE-2.0.txt',
-          proxy: 'http://proxy:8080'
+          url: "http://apache.org/licenses/LICENSE-2.0.txt",
+          proxy: "http://proxy:8080"
         },
-        dest: 'LICENSE'
+        dest: "LICENSE"
       }
-    } 
+    }
   };
   
-  /*** Join local configuration for proxies and local test servers ***/
+  //    Join local configuration for proxies and local test servers
   if (grunt.file.exists('localgrunt.config')) {
     console.log("merge localgrunt.config");
     var localGrundConfig = grunt.file.read('localgrunt.config');
     init.connect['test-browser'].proxies = init.connect['test-browser'].proxies.concat(JSON.parse(localGrundConfig).proxies);
   }
 
-  /*** Init ***/
+  //    Init config
   grunt.initConfig(init);
 
-  /*** Load tasks from npm modules ***/
-  grunt.loadNpmTasks('grunt-browserify');
+  //    Load tasks from npm modules ***/
   grunt.loadNpmTasks('grunt-contrib-uglify');
   grunt.loadNpmTasks("grunt-contrib-copy");
   grunt.loadNpmTasks("grunt-contrib-concat");
@@ -143,10 +126,8 @@ module.exports = function(grunt) {
   grunt.loadNpmTasks("grunt-jsdoc");
   grunt.loadNpmTasks("grunt-nuget");
 
-  //    Start Qunit tests direcly in node js, internally qunit (npm qunit) 
-  //    is used, no phantomjs instance required
-  //grunt.loadNpmTasks('grunt-node-qunit'); 
-  //grunt.loadNpmTasks('grunt-contrib-clean');
+  //    Load the custom-* tasks from the grunt-config directory
+  grunt.loadTasks('grunt-config/custom-tasks');
 
   //    Load the custom-* tasks from the grunt-config directory
   grunt.loadTasks('grunt-config');
@@ -158,9 +139,9 @@ module.exports = function(grunt) {
     process.env['JAVA_TOOL_OPTIONS'] = ''; 
   });
 
-  /*** E N D U S E R   T A S K S ***/
+  //    E N D U S E R   T A S K S 
 
-  grunt.registerTask('clean', ['npm-clean']);
+  grunt.registerTask('clean', ['npm-clean:build']);
 
   //    Runs the license header check to verify the any source file contains a license header
   grunt.registerTask('license-check', ['rat:manual']);
@@ -170,14 +151,32 @@ module.exports = function(grunt) {
   grunt.registerTask('doc-test', ['clearEnv', 'jsdoc:test']);
 
   //    Build the odatajs library
-  grunt.registerTask('build', ['clean:lib','browserify:src', 'uglify:build', 'concat:licence','concat:licence_min','copy:to-latest','nugetpack']);
-  grunt.registerTask('build2', ['clean:lib','concat:src', 'uglify:build', 'concat:licence','concat:licence_min','nugetpack']);
+
 
   grunt.registerTask('test-browser', ['configureProxies:test-browser', 'connect:test-browser']);
   grunt.registerTask('test-node', ['node-qunit:default-tests']);
   //grunt.registerTask('release', ['build','doc','compress']);
   //grunt.registerTask('update-legal', ['curl:license']);
 
+
+  grunt.registerTask('build', ['clean:lib','toBrowser:release', 'uglify:build', 'concat:licence_min','copy:to-latest','nugetpack']);
+
+  grunt.registerTask('get-licence', ['curl:license']);
+
+  //    R E L E A S E    T A S K S 
+  grunt.registerTask('release',[
+    'npm-clean:release-dist',
+    'build',
+    'doc',
+    'copy:release-lib','copy:release-doc','copy:release-sources',
+    'rat:dist', // check the license headers
+    'compress:release-lib','compress:release-doc','compress:release-sources',
+    ]);
+
   
+  grunt.registerTask('release:sign',[
+    'sign:release','sign:asc','sign:asc-verify'
+    ]);
+
 };
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/grunt-config/browserify_transforms/stripheader/package.json
----------------------------------------------------------------------
diff --git a/odatajs/grunt-config/browserify_transforms/stripheader/package.json b/odatajs/grunt-config/browserify_transforms/stripheader/package.json
deleted file mode 100644
index a86cfca..0000000
--- a/odatajs/grunt-config/browserify_transforms/stripheader/package.json
+++ /dev/null
@@ -1,42 +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.
- */
-{
-  "name": "grunt-rat",
-  "version": "0.0.1",
-  "description": "Transform vor removing license headers",
-  "license": "Apache",
-  "author": {
-    "name": "Sven Kobler-Morris",
-    "email": "koblers@apache.org"
-  },
-  "files": [
-    "tasks"
-  ],
-  "dependencies": {
-    "through": "^2.3.4"
-  },
-  "devDependencies": {
-  },
-  "peerDependencies": {
-    "grunt": "~0.4.0"
-  },
-  "engines": {
-    "node": ">=0.8.0"
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/grunt-config/browserify_transforms/stripheader/stripheader.js
----------------------------------------------------------------------
diff --git a/odatajs/grunt-config/browserify_transforms/stripheader/stripheader.js b/odatajs/grunt-config/browserify_transforms/stripheader/stripheader.js
deleted file mode 100644
index b4f6f35..0000000
--- a/odatajs/grunt-config/browserify_transforms/stripheader/stripheader.js
+++ /dev/null
@@ -1,42 +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 through = require('through');
-
-module.exports = function (file) {
-  //if (/\.json$/.test(file)) return through();
-  //console.log('strip header from ' + file);
-  var data = "";
-
-
-  return through(
-    function (buf) { data += buf;    },
-    function () {
-      try {
-        //console.log('\nin--------------\na'+data.substring(0,1000));
-        var out = data.replace(/(\/\*(.|\n|\r)*?\*\/)/i,"");
-        //console.log('\nout--------------\n'+out.substring(0,300));
-        this.queue(out);
-      } catch (er) {
-        this.emit("error", new Error(er.toString().replace("Error: ", "") + " (" + file + ")"));
-      }
-      this.queue(null);
-    }
-  );
-};
-

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/grunt-config/custom-tasks/rat/extern-tools/info.md
----------------------------------------------------------------------
diff --git a/odatajs/grunt-config/custom-tasks/rat/extern-tools/info.md b/odatajs/grunt-config/custom-tasks/rat/extern-tools/info.md
index f925cb2..f48049e 100644
--- a/odatajs/grunt-config/custom-tasks/rat/extern-tools/info.md
+++ b/odatajs/grunt-config/custom-tasks/rat/extern-tools/info.md
@@ -16,5 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-Place apache-rat-0.11.jar in ./apache-rat-0.11/apache-rat-0.11.jar.
+Place apache-rat-0.11.jar from http://creadur.apache.org/rat/download_rat.cgi
+in ./apache-rat-0.11/apache-rat-0.11.jar.
+
 See ./../readme.md for details
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/grunt-config/custom-tasks/rat/package.json
----------------------------------------------------------------------
diff --git a/odatajs/grunt-config/custom-tasks/rat/package.json b/odatajs/grunt-config/custom-tasks/rat/package.json
index f5fa8bb..0c374c7 100644
--- a/odatajs/grunt-config/custom-tasks/rat/package.json
+++ b/odatajs/grunt-config/custom-tasks/rat/package.json
@@ -1,21 +1,3 @@
-/*
- * 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.
- */
 {
   "name": "grunt-rat",
   "version": "0.0.1",

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/grunt-config/custom-tasks/toBrowser.js
----------------------------------------------------------------------
diff --git a/odatajs/grunt-config/custom-tasks/toBrowser.js b/odatajs/grunt-config/custom-tasks/toBrowser.js
new file mode 100644
index 0000000..4712a87
--- /dev/null
+++ b/odatajs/grunt-config/custom-tasks/toBrowser.js
@@ -0,0 +1,23 @@
+/*
+ * 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.exports = function(grunt) {
+  require('./toBrowser/toBrowser.js')(grunt);
+};

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/grunt-config/custom-tasks/toBrowser/toBrowser.js
----------------------------------------------------------------------
diff --git a/odatajs/grunt-config/custom-tasks/toBrowser/toBrowser.js b/odatajs/grunt-config/custom-tasks/toBrowser/toBrowser.js
new file mode 100644
index 0000000..eccaf35
--- /dev/null
+++ b/odatajs/grunt-config/custom-tasks/toBrowser/toBrowser.js
@@ -0,0 +1,78 @@
+/*
+ * 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.exports = function(grunt) {
+
+  var stripHeader = function(input) { 
+    return input.replace(/(\/\*(.|\n|\r)*?\*\/)/i,"");
+  };
+
+  grunt.registerMultiTask('toBrowser', function() {
+      var self = this;
+
+      var path = require('path');
+      var fs = require( 'fs' );
+      
+      var globalDone = this.async();
+      
+      var options = this.options({ });
+      
+      var workLoad = [];
+      var writeToLogOk = function(data) { grunt.log.ok(data.toString()); };
+
+      
+      // fill workLoad
+      for(var i = 0; i < this.files.length; i++) {
+        for(var ii = 0; ii < this.files[i].src.length; ii++) {
+          var srcFile = this.files[i].src[ii];
+          workLoad.push({
+                  srcFile : srcFile,
+                  name : srcFile.substring(srcFile.lastIndexOf('/')+1,srcFile.length-3)
+              });
+        }
+      
+        var concat = '{';
+        for(var x = 0; x < workLoad.length; x++) {
+          var src = grunt.file.read(workLoad[x].srcFile);
+          // remove the first comment
+          src = stripHeader(src);
+        
+          if (x > 0) {
+            concat+= ', ';
+          }
+
+          concat+= '"' + workLoad[x].name + '" : ';
+          concat+= 'function(exports, module, require) {';
+          concat+= src +'}';
+        }
+        concat+= '}';
+
+        var tpl = grunt.file.read('./grunt-config/custom-tasks/toBrowser/wrapper-tpl.js');
+        var init = stripHeader(grunt.file.read(options.index));
+
+        tpl = tpl.replace('\'<% initFunction %>\'',init);
+        tpl = tpl.replace('\'<% filesAsFunctionList %>\'',concat);
+
+        grunt.file.write(this.files[i].dest, tpl);
+      }
+
+      globalDone();
+  });
+};
+

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/grunt-config/custom-tasks/toBrowser/wrapper-tpl.js
----------------------------------------------------------------------
diff --git a/odatajs/grunt-config/custom-tasks/toBrowser/wrapper-tpl.js b/odatajs/grunt-config/custom-tasks/toBrowser/wrapper-tpl.js
new file mode 100644
index 0000000..9c335db
--- /dev/null
+++ b/odatajs/grunt-config/custom-tasks/toBrowser/wrapper-tpl.js
@@ -0,0 +1,43 @@
+/*
+ * 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 init = function(exports, module, require) {
+  '<% initFunction %>'
+};
+
+var datas = '<% filesAsFunctionList %>';
+
+var modules = {};
+
+var require = function(path) {
+    var name = path.substring(path.lastIndexOf('/')+1,path.length-3);
+    if (modules[name]) { return modules[name].exports; }
+
+    modules[name] = { exports : {}};
+    console.log(name);
+    if (name === 'sou') {
+      var i = 0;
+    }
+    datas[name].call(this,modules[name].exports,modules[name],require);
+    return modules[name].exports;
+  };
+
+window.odatajs = {};
+init.call(this,window.odatajs,window.odatajs,require);
+
+

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/grunt-config/release.js
----------------------------------------------------------------------
diff --git a/odatajs/grunt-config/release.js b/odatajs/grunt-config/release.js
index 99edb19..f163ca0 100644
--- a/odatajs/grunt-config/release.js
+++ b/odatajs/grunt-config/release.js
@@ -166,34 +166,8 @@ module.exports = function(grunt) {
     },
   });
 
-  
-  
-  /*
-  //sign
-  grunt.config.merge( { 
-    sign : {
-      'release-lib': { // just the lib
-        options: {archive: './../dist/<%= artifactname %>/<%= artifactname %>-lib.zip'},
-        files: [{expand: true, cwd: './../dist/<%= artifactname %>/lib', src: ['**'],  dest: '/'}]
-      },
-    }
-  });
-*/
 
   grunt.loadNpmTasks('grunt-contrib-compress');
-
-  //tasks
-  grunt.registerTask('release',[
-    'npm-clean:release-dist',
-    'build',
-    'doc',
-    'copy:release-lib','copy:release-doc','copy:release-sources',
-    'rat:dist', // check the license headers
-    'compress:release-lib','compress:release-doc','compress:release-sources',
-    ]);
-  grunt.registerTask('release:sign',[
-    'sign:release','sign:asc','sign:asc-verify'
-    ]);
-
+ 
 };
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/grunt-config/sign.js
----------------------------------------------------------------------
diff --git a/odatajs/grunt-config/sign.js b/odatajs/grunt-config/sign.js
index 188d019..5a676ab 100644
--- a/odatajs/grunt-config/sign.js
+++ b/odatajs/grunt-config/sign.js
@@ -19,7 +19,6 @@
 module.exports = function(grunt) {
 
   
-  
   //sign
   grunt.config.merge( { 
     'sign' : {

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/package.json
----------------------------------------------------------------------
diff --git a/odatajs/package.json b/odatajs/package.json
index 8f1e577..ea387d9 100644
--- a/odatajs/package.json
+++ b/odatajs/package.json
@@ -7,7 +7,8 @@
   "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.",
   "homepage": "http://olingo.apache.org",
-  "main": "index.js",
+  "main": "index-node.js",
+  "main-browser": "index.js",
   "repository": {
     "type": "git",
     "url": "http://git-wip-us.apache.org/repos/asf/olingo-odata4-js.git"
@@ -31,7 +32,6 @@
   ],
   "scripts": {},
   "devDependencies": {
-    "browserify": "^4.1.5",
     "grunt": "^0.4.5",
     "grunt-browserify": "^2.1.0",
     "grunt-connect-proxy": "^0.1.10",

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/src/browser-lib-tpl.js
----------------------------------------------------------------------
diff --git a/odatajs/src/browser-lib-tpl.js b/odatajs/src/browser-lib-tpl.js
new file mode 100644
index 0000000..9c335db
--- /dev/null
+++ b/odatajs/src/browser-lib-tpl.js
@@ -0,0 +1,43 @@
+/*
+ * 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 init = function(exports, module, require) {
+  '<% initFunction %>'
+};
+
+var datas = '<% filesAsFunctionList %>';
+
+var modules = {};
+
+var require = function(path) {
+    var name = path.substring(path.lastIndexOf('/')+1,path.length-3);
+    if (modules[name]) { return modules[name].exports; }
+
+    modules[name] = { exports : {}};
+    console.log(name);
+    if (name === 'sou') {
+      var i = 0;
+    }
+    datas[name].call(this,modules[name].exports,modules[name],require);
+    return modules[name].exports;
+  };
+
+window.odatajs = {};
+init.call(this,window.odatajs,window.odatajs,require);
+
+

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/src/index-browser.js
----------------------------------------------------------------------
diff --git a/odatajs/src/index-browser.js b/odatajs/src/index-browser.js
new file mode 100644
index 0000000..1f52e6b
--- /dev/null
+++ b/odatajs/src/index-browser.js
@@ -0,0 +1,36 @@
+/*1
+ * 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/ext/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/87e35975/odatajs/src/index-node.js
----------------------------------------------------------------------
diff --git a/odatajs/src/index-node.js b/odatajs/src/index-node.js
new file mode 100644
index 0000000..28bf066
--- /dev/null
+++ b/odatajs/src/index-node.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/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/87e35975/odatajs/src/index.js
----------------------------------------------------------------------
diff --git a/odatajs/src/index.js b/odatajs/src/index.js
index 42615d3..d939da2 100644
--- a/odatajs/src/index.js
+++ b/odatajs/src/index.js
@@ -17,18 +17,27 @@
  * under the License.
  */
 
+//console.log('main starting');
+//var a = require('./a.js');
+//var b = require('./b.js');
+//console.log('in main, a.done=%j, b.done=%j', a.done, b.done);
+
 var odatajs = {};
 
 odatajs.version = {
-    major: 1,
-    minor: 1,
-    build: 1
+    major: 4,
+    minor: 0,
+    build: 0
 };
 
-odatajs.deferred = require('./lib/odatajs/deferred.js');
-odatajs.utils = require('./lib/odatajs/utils.js');
-odatajs.xml = require('./lib/odatajs/xml.js');
+// 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');

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/src/lib/cache.js
----------------------------------------------------------------------
diff --git a/odatajs/src/lib/cache.js b/odatajs/src/lib/cache.js
index 92a740d..9912865 100644
--- a/odatajs/src/lib/cache.js
+++ b/odatajs/src/lib/cache.js
@@ -20,10 +20,10 @@
  /** @module cache */
 
 //var odatajs = require('./odatajs/utils.js');
-var utils =  require('./odatajs/utils.js');
-var deferred = require('./odatajs/deferred.js');
+var utils =  require('./utils.js');
+var deferred = require('./deferred.js');
 var storeReq = require('./store.js');
-var cacheSource = require('./cache/source');
+var cacheSource = require('./cache/source.js');
 
 
 var assigned = utils.assigned;
@@ -1447,4 +1447,7 @@ function createDataCache (options) {
 exports.estimateSize = estimateSize;
 
 /** createDataCache */  
-exports.createDataCache = createDataCache;
\ No newline at end of file
+exports.createDataCache = createDataCache;
+
+
+

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/src/lib/cache/source.js
----------------------------------------------------------------------
diff --git a/odatajs/src/lib/cache/source.js b/odatajs/src/lib/cache/source.js
index eccf5d9..af878c6 100644
--- a/odatajs/src/lib/cache/source.js
+++ b/odatajs/src/lib/cache/source.js
@@ -19,7 +19,7 @@
 
  /** @module cache/source */
  
-var utils = require("./../odatajs/utils.js");
+var utils = require("./../utils.js");
 var odataRequest = require("./../odata.js");
 
 var parseInt10 = utils.parseInt10;

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/src/lib/deferred.js
----------------------------------------------------------------------
diff --git a/odatajs/src/lib/deferred.js b/odatajs/src/lib/deferred.js
new file mode 100644
index 0000000..7d5fd68
--- /dev/null
+++ b/odatajs/src/lib/deferred.js
@@ -0,0 +1,189 @@
+/*
+ * 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 datajs/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/87e35975/odatajs/src/lib/odata.js
----------------------------------------------------------------------
diff --git a/odatajs/src/lib/odata.js b/odatajs/src/lib/odata.js
index 8999bb2..7ea728b 100644
--- a/odatajs/src/lib/odata.js
+++ b/odatajs/src/lib/odata.js
@@ -20,7 +20,7 @@
  /** @module odata */
 
 // Imports
-var odataUtils    = exports.utils     = require('./odata/utils.js');
+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');
@@ -29,7 +29,7 @@ var odataJson     = exports.json      = require('./odata/json.js');
                     
 
 
-var utils = require('./odatajs/utils.js');
+var utils = require('./utils.js');
 var assigned = utils.assigned;
 
 var defined = utils.defined;

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/src/lib/odata/batch.js
----------------------------------------------------------------------
diff --git a/odatajs/src/lib/odata/batch.js b/odatajs/src/lib/odata/batch.js
index 59fb1f8..c71fc31 100644
--- a/odatajs/src/lib/odata/batch.js
+++ b/odatajs/src/lib/odata/batch.js
@@ -19,8 +19,8 @@
 
 /** @module odata/batch */
 
-var utils    = require('./../odatajs/utils.js');
-var odataUtils    = require('./utils.js');
+var utils    = require('./../utils.js');
+var odataUtils    = require('./odatautils.js');
 var odataHandler = require('./handler.js');
 
 var extend = utils.extend;

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/src/lib/odata/handler.js
----------------------------------------------------------------------
diff --git a/odatajs/src/lib/odata/handler.js b/odatajs/src/lib/odata/handler.js
index d2b62d4..cbd09c6 100644
--- a/odatajs/src/lib/odata/handler.js
+++ b/odatajs/src/lib/odata/handler.js
@@ -20,8 +20,8 @@
 /** @module odata/handler */
 
 
-var utils    = require('./../odatajs/utils.js');
-var oDataUtils    = require('./utils.js');
+var utils    = require('./../utils.js');
+var oDataUtils    = require('./odatautils.js');
 
 // Imports.
 var assigned = utils.assigned;

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/src/lib/odata/json.js
----------------------------------------------------------------------
diff --git a/odatajs/src/lib/odata/json.js b/odatajs/src/lib/odata/json.js
index d003e2b..6955cbe 100644
--- a/odatajs/src/lib/odata/json.js
+++ b/odatajs/src/lib/odata/json.js
@@ -21,8 +21,8 @@
 
 
 
-var utils        = require('./../odatajs/utils.js');
-var oDataUtils   = require('./utils.js');
+var utils        = require('./../utils.js');
+var oDataUtils   = require('./odatautils.js');
 var oDataHandler = require('./handler.js');
 
 var odataNs = "odata";

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/src/lib/odata/metadata.js
----------------------------------------------------------------------
diff --git a/odatajs/src/lib/odata/metadata.js b/odatajs/src/lib/odata/metadata.js
index fb34286..e37161f 100644
--- a/odatajs/src/lib/odata/metadata.js
+++ b/odatajs/src/lib/odata/metadata.js
@@ -19,8 +19,8 @@
 
 /** @module odata/metadata */
 
-var utils    = require('./../odatajs/utils.js');
-var oDSxml    = require('./../odatajs/xml.js');
+var utils    = require('./../utils.js');
+var oDSxml    = require('./../xml.js');
 var odataHandler    = require('./handler.js');
 
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/src/lib/odata/net.js
----------------------------------------------------------------------
diff --git a/odatajs/src/lib/odata/net.js b/odatajs/src/lib/odata/net.js
index 0dbbce0..6e0f6c8 100644
--- a/odatajs/src/lib/odata/net.js
+++ b/odatajs/src/lib/odata/net.js
@@ -21,7 +21,7 @@
 
 
 
-var utils    = require('./../odatajs/utils.js');
+var utils    = require('./../utils.js');
 // Imports.
 
 var defined = utils.defined;

http://git-wip-us.apache.org/repos/asf/olingo-odata4-js/blob/87e35975/odatajs/src/lib/odata/odatautils.js
----------------------------------------------------------------------
diff --git a/odatajs/src/lib/odata/odatautils.js b/odatajs/src/lib/odata/odatautils.js
new file mode 100644
index 0000000..a44fa05
--- /dev/null
+++ b/odatajs/src/lib/odata/odatautils.js
@@ -0,0 +1,1265 @@
+/*
+ * 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/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 {Numaber} ms - Number of milliseconds to format.</param>
+ * @param {Numaber} ns - Number of nanoseconds to format.</param>
+ * @returns {String} Formatted text.
+ * If the value is already as string it's returned as-is.</remarks>
+ */
+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 {Sting} 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 {Sting} 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
+    var ret = contains(geographyEdmTypes, typeName) || 
+        (typeName.indexOf('.') === -1 && contains(geographyTypes, typeName));
+    return ret; 
+        
+}
+
+/** 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) {
+
+    var ret = contains(geometryEdmTypes, typeName) ||
+        (typeName.indexOf('.') === -1 && contains(geometryTypes, typeName));
+    return ret; 
+}
+
+/** 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} properties - 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} properties - 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.</returns>
+ */
+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.</returns>
+ */
+function lookupEntityType(name, metadata) {
+
+    return lookupInMetadata(name, metadata, "entityType");
+}
+
+
+/** Looks up an
+ * @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.</returns>
+ */
+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.</returns>
+ */
+function lookupEntityContainer(name, metadata) {
+
+    return lookupInMetadata(name, metadata, "entityContainer");
+}
+
+/** Looks up a function import by name.
+ * @param {Array} properties - 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} 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} navigationProperty - 
+ * @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.</returns>
+ */
+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.
+ * @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.
+ * @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+))?)?$/;
+
+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.
+ * @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 {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.</remarks>
+*/
+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.</remarks>
+*/
+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;
+