diff --git a/datajs/Gruntfile.js b/datajs/Gruntfile.js
index f228d60..0dcd62c 100644
--- a/datajs/Gruntfile.js
+++ b/datajs/Gruntfile.js
@@ -110,12 +110,14 @@
     },
   };
   
+  //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);
   }
 
+
   grunt.initConfig(init);
 
   // These plugins provide necessary tasks.
@@ -124,12 +126,21 @@
   grunt.loadNpmTasks("grunt-connect-proxy");
   grunt.loadNpmTasks("grunt-contrib-connect");
   grunt.loadNpmTasks("grunt-contrib-copy");
-  grunt.loadNpmTasks('grunt-node-qunit');
+  grunt.loadNpmTasks('grunt-node-qunit');/*TODO replace by grunt contrib-qunit*/
+
+  //load the task from the grunt-config directory
+  //these are rat, 
+  grunt.loadTasks('grunt-config');
   
 
-  // Default task.
+
   grunt.registerTask('build', ['browserify:datajs', 'uglify:build', 'copy:forDemo']);
   grunt.registerTask('test-browser', ['configureProxies:test-browser', 'connect:test-browser']);
   grunt.registerTask('test-node', ['node-qunit:default-tests']);
+
+
+  //This task runs the Apache Relase Autit Tool (RAT)
+  //grunt.registerTask('rat', ['shell:rat'/*,'rat-check:rat'*/]);
+  
 };
 
diff --git a/datajs/grunt-config/custom-tasks/rat/package.json b/datajs/grunt-config/custom-tasks/rat/package.json
new file mode 100644
index 0000000..6753173
--- /dev/null
+++ b/datajs/grunt-config/custom-tasks/rat/package.json
@@ -0,0 +1,26 @@
+{
+  "name": "grunt-rat",
+  "version": "0.0.1",
+  "description": "Run Apache Rat(release audit tool)",
+  "license": "Apache",
+  "author": {
+    "name": "Sven Kobler-Morris",
+    "email": "koblers@apache.org"
+  },
+  "files": [
+    "tasks"
+  ],
+  "dependencies": {
+    "chalk": "~0.4.0"
+  },
+  "devDependencies": {
+    "grunt": "~0.4.0",
+    "xml2js": "^0.4.4"
+  },
+  "peerDependencies": {
+    "grunt": "~0.4.0"
+  },
+  "engines": {
+    "node": ">=0.8.0"
+  }
+}
diff --git a/datajs/grunt-config/custom-tasks/rat/readme.md b/datajs/grunt-config/custom-tasks/rat/readme.md
new file mode 100644
index 0000000..2921499
--- /dev/null
+++ b/datajs/grunt-config/custom-tasks/rat/readme.md
@@ -0,0 +1,2 @@
+require http://creadur.apache.org/rat/download_rat.cgi --> apache-rat-0.10-bin.zip
+to be upacked to /tools/apache-rat-0.10-bin
\ No newline at end of file
diff --git a/datajs/grunt-config/custom-tasks/rat/tasks/rat.js b/datajs/grunt-config/custom-tasks/rat/tasks/rat.js
new file mode 100644
index 0000000..a8c61eb
--- /dev/null
+++ b/datajs/grunt-config/custom-tasks/rat/tasks/rat.js
@@ -0,0 +1,87 @@
+'use strict';
+module.exports = function (grunt) {
+  grunt.registerMultiTask('rat', 'Run Apache Rat', function () {
+    var path = require('path');
+    var chalk = require('chalk');
+    var childProcess = require('child_process');
+    var xml2js = require('xml2js');
+
+    var cb = this.async();
+
+    var options = this.options({ xml : true, tmpdir : './build/tmp'});
+    var dir = this.data.dir;
+    var out = options.tmpdir + '/' + (options.xml ? 'rat.xml' : 'rat.txt');
+
+    
+    var pathToRat =  path.resolve(__dirname,'./../tools/apache-rat-0.10/apache-rat-0.10.jar');
+    
+    //sample command java -jar apache-rat-0.10.jar -x -d ./src > ./build/tmp/rat.txt
+    var cmd = 'java -jar ' + pathToRat;
+    cmd += options.xml ? ' -x' : '';
+
+    cmd += ' -d ' + dir;
+    cmd += ' > ' + out;
+
+    var cp = childProcess.exec(cmd, options.execOptions, function (err, stdout, stderr) {
+      if (err) {
+        grunt.fail.warn('rat --> ' + err, 1); //abort Grunt immediately with error code 1
+      }
+      grunt.verbose.writeln('Rat['+dir+']:');
+      if (!options.xml) {
+        grunt.fail.warn('rat --> ' + 'No XML output: checkRatLogFile skipped!', 1); //abort Grunt immediately with error code 1
+      }
+      var xml = grunt.file.read(out);
+      var parser = new xml2js.Parser();
+      parser.parseString(xml, function (err, result) {
+          if (err) {
+            grunt.fail.warn('rat --> ' + err, 1); //abort Grunt immediately with error code 1
+          }
+          
+          //
+          if (checkRatLogFile(result)) {
+            grunt.fail.warn('rat --> ' + 'Missing or Invalied license header detected ( see "'+out+'")', 1);
+          }
+
+          //
+          cb();
+      });
+    }.bind(this));
+
+    var checkRatLogFile = function(result) {
+
+      var list = result['rat-report']['resource'];
+      for (var i = 0; i < list.length; i++ ){
+        var item = list[i];
+
+        var headerType = list[i]['header-type'];
+        var attr = headerType[0]['$'];
+        if (attr.name.trim() !== 'AL') {
+          return true;
+        }
+      }
+      return false;
+    }
+
+    var captureOutput = function (child, output) {
+      if (grunt.option('color') === false) {
+        child.on('data', function (data) {
+          output.write(chalk.stripColor(data));
+        });
+      } else {
+        child.pipe(output);
+      }
+    };
+
+    grunt.verbose.writeln('Command:', chalk.yellow(cmd));
+
+    captureOutput(cp.stdout, process.stdout);
+      captureOutput(cp.stderr, process.stderr);
+
+    if (options.stdin) {
+      process.stdin.resume();
+      process.stdin.setEncoding('utf8');
+      process.stdin.pipe(cp.stdin);
+    }
+  });
+};
+
diff --git a/datajs/grunt-config/rat-config.js b/datajs/grunt-config/rat-config.js
new file mode 100644
index 0000000..b9dd78c
--- /dev/null
+++ b/datajs/grunt-config/rat-config.js
@@ -0,0 +1,19 @@
+module.exports = function(grunt) {
+  grunt.config('rat', {
+    options: { xml : true, tmpDir : './build/tmp' },
+    src: {                      
+      dir: './src',
+    },
+    test: {                      
+      dir: './tests'
+    },
+    all: {
+      all: ['./src','./tests']
+    }
+  });
+
+  
+  //grunt.loadNpmTasks('custom-tasks/rat');
+  grunt.loadTasks('grunt-config/custom-tasks/rat/tasks');
+  grunt.registerTask('ra',['rat:src']);
+};
\ No newline at end of file
diff --git a/datajs/src/index.js b/datajs/src/index.js
index 82fc374..dbe1e64 100644
--- a/datajs/src/index.js
+++ b/datajs/src/index.js
@@ -27,6 +27,7 @@
 window.datajs.V4.store = require('./lib/store.js');
 window.datajs.V4.cache = require('./lib/cache.js');
 
+/*
 function extend(target) {
     var sources = [].slice.call(arguments, 1);
     sources.forEach(function (source) {
@@ -35,6 +36,6 @@
         }
     });
     return target;
-}
+}*/
 
 
diff --git a/datajs/src/lib/odata.js b/datajs/src/lib/odata.js
index 55f4a4e..fa993e8 100644
--- a/datajs/src/lib/odata.js
+++ b/datajs/src/lib/odata.js
@@ -1,19 +1,26 @@
+/*
+ * 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.
+ */
+
 /* {
     oldname:'odata.js',
     updated:'20140514 12:59'
 }*/
-// Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
-// files (the "Software"), to deal  in the Software without restriction, including without limitation the rights  to use, copy,
-// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-// WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 // odata.js
 
diff --git a/datajs/src/lib/odata/json-light.js b/datajs/src/lib/odata/json-light.js
deleted file mode 100644
index 620ae63..0000000
--- a/datajs/src/lib/odata/json-light.js
+++ /dev/null
@@ -1,1448 +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.
- */
-
-/* {
-    oldname:'odata-json-light.js',
-    updated:'20140514 12:59'
-}*/
-
-
-var utils    = require('./../datajs.js').utils;
-var oDataUtils    = require('./utils.js');
-
-var assigned = utils.assigned;
-var djsassert = utils.djsassert;
-var extend = utils.extend;
-var getURIInfo = utils.getURIInfo;
-var isArray = utils.isArray;
-var isDate = utils.isDate;
-var isObject = utils.isObject;
-var normalizeURI = utils.normalizeURI;
-var renameProperty = utils.renameProperty;
-var undefinedDefault = utils.undefinedDefault;
-var convertByteArrayToHexString = utils.convertByteArrayToHexString;
-
-var dataItemTypeName = oDataUtils.dataItemTypeName;
-var EDM_DATETIME = oDataUtils.EDM_DATETIME;
-var EDM_DATETIMEOFFSET = oDataUtils.EDM_DATETIMEOFFSET;
-var EDM_TIME = oDataUtils.EDM_TIME;
-var getCollectionType = oDataUtils.getCollectionType;
-var isCollection = oDataUtils.isCollection;
-var isCollectionType = oDataUtils.isCollectionType;
-var isComplex = oDataUtils.isComplex;
-var isDeferred = oDataUtils.isDeferred;
-var isFeed = oDataUtils.isFeed;
-var isEntry = oDataUtils.isEntry;
-var isGeographyEdmType = oDataUtils.isGeographyEdmType;
-var isGeometryEdmType = oDataUtils.isGeometryEdmType;
-var isPrimitiveEdmType = oDataUtils.isPrimitiveEdmType;
-var isPrimitive = oDataUtils.isPrimitive;
-var lookupComplexType = oDataUtils.lookupComplexType;
-var lookupDefaultEntityContainer = oDataUtils.lookupDefaultEntityContainer;
-var lookupEntityContainer = oDataUtils.lookupEntityContainer;
-var lookupEntitySet = oDataUtils.lookupEntitySet;
-var lookupSingleton = oDataUtils.lookupSingleton;
-var lookupEntityType = oDataUtils.lookupEntityType;
-var lookupFunctionImport = oDataUtils.lookupFunctionImport;
-var lookupNavigationPropertyType = oDataUtils.lookupNavigationPropertyType;
-var getEntitySetInfo = oDataUtils.getEntitySetInfo;
-var lookupNavigationPropertyEntitySet = oDataUtils.lookupNavigationPropertyEntitySet;
-var lookupProperty = oDataUtils.lookupProperty;
-var parseBool = oDataUtils.parseBool;
-var parseDateTime = oDataUtils.parseDateTime;
-var parseDateTimeOffset = oDataUtils.parseDateTimeOffset;
-var parseDuration = oDataUtils.parseDuration;
-// CONTENT START
-
-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 odataNs = "odata";
-var odataAnnotationPrefix = odataNs + ".";
-
-var contextUrlAnnotation = "@" + odataAnnotationPrefix + "context";
-
-var bindAnnotation = "@" + odataAnnotationPrefix + "bind";
-var navUrlAnnotation = odataAnnotationPrefix + "navigationLinkUrl";
-var typeAnnotation = odataAnnotationPrefix + "type";
-
-var jsonLightNameMap = {
-    readLink: "self",
-    editLink: "edit",
-    nextLink: "__next",
-    mediaReadLink: "media_src",
-    mediaEditLink: "edit_media",
-    mediaContentType: "content_type",
-    mediaETag: "media_etag",
-    count: "__count",
-    media_src: "mediaReadLink",
-    edit_media: "mediaEditLink",
-    content_type: "mediaContentType",
-    media_etag: "mediaETag",
-    url: "uri"
-};
-
-var jsonLightAnnotations = {
-    metadata: "odata.metadata",
-    count: "odata.count",
-    next: "odata.nextLink",
-    id: "odata.id",
-    etag: "odata.etag",
-    read: "odata.readLink",
-    edit: "odata.editLink",
-    mediaRead: "odata.mediaReadLink",
-    mediaEdit: "odata.mediaEditLink",
-    mediaEtag: "odata.mediaETag",
-    mediaContentType: "odata.mediaContentType",
-    actions: "odata.actions",
-    functions: "odata.functions",
-    navigationUrl: "odata.navigationLinkUrl",
-    associationUrl: "odata.associationLinkUrl",
-    type: "odata.type"
-};
-
-var jsonLightAnnotationInfo = function (annotation) {
-    /// <summary>Gets the name and target of an annotation in a JSON light payload.</summary>
-    /// <param name="annotation" type="String">JSON light payload annotation.</param>
-    /// <returns type="Object">Object containing the annotation name and the target property name.</param>
-
-    if (annotation.indexOf(".") > 0) {
-        var targetEnd = annotation.indexOf("@");
-        var target = targetEnd > -1 ? annotation.substring(0, targetEnd) : null;
-        var name = annotation.substring(targetEnd + 1);
-
-        return {
-            target: target,
-            name: name,
-            isOData: name.indexOf(odataAnnotationPrefix) === 0
-        };
-    }
-    return null;
-};
-
-var jsonLightDataItemType = function (name, value, container, dataItemModel, model) {
-    /// <summary>Gets the type name of a JSON light data item that belongs to a feed, an entry, a complex type property, or a collection property.</summary>
-    /// <param name="name" type="String">Name of the data item for which the type name is going to be retrieved.</param>
-    /// <param name="value">Value of the data item.</param>
-    /// <param name="container" type="Object">JSON light object that owns the data item.</param>
-    /// <param name="dataItemModel" type="Object" optional="true">Object describing the data item in an OData conceptual schema.</param>
-    /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
-    /// <remarks>
-    ///    This function will first try to get the type name from the data item's value itself if it is a JSON light object; otherwise
-    ///    it will try to get it from the odata.type annotation applied to the data item in the container. Then, it will fallback to the data item model.
-    ///    If all attempts fail, it will return null.
-    /// </remarks>
-    /// <returns type="String">Data item type name; null if the type name cannot be found.</returns>
-
-    return (isComplex(value) && value[typeAnnotation]) ||
-        (container && container[name + "@" + typeAnnotation]) ||
-        (dataItemModel && dataItemModel.type) ||
-        (lookupNavigationPropertyType(dataItemModel, model)) ||
-        null;
-};
-
-var jsonLightDataItemModel = function (name, containerModel) {
-    /// <summary>Gets an object describing a data item in an OData conceptual schema.</summary>
-    /// <param name="name" type="String">Name of the data item for which the model is going to be retrieved.</param>
-    /// <param name="containerModel" type="Object">Object describing the owner of the data item in an OData conceptual schema.</param>
-    /// <returns type="Object">Object describing the data item; null if it cannot be found.</returns>
-
-    if (containerModel) {
-        return lookupProperty(containerModel.property, name) ||
-            lookupProperty(containerModel.navigationProperty, name);
-    }
-    return null;
-};
-
-var jsonLightIsEntry = function (data) {
-    /// <summary>Determines whether data represents a JSON light entry object.</summary>
-    /// <param name="data" type="Object">JSON light object to test.</param>
-    /// <returns type="Boolean">True if the data is JSON light entry object; false otherwise.</returns>
-
-    return isComplex(data) && ((odataAnnotationPrefix + "id") in data);
-};
-
-/*
-var jsonLightIsNavigationProperty = function (name, data, dataItemModel) {
-    /// <summary>Determines whether a data item in a JSON light object is a navigation property.</summary>
-    /// <param name="name" type="String">Name of the data item to test.</param>
-    /// <param name="data" type="Object">JSON light object that owns the data item.</param>
-    /// <param name="dataItemModel" type="Object">Object describing the data item in an OData conceptual schema.</param>
-    /// <returns type="Boolean">True if the data item is a navigation property; false otherwise.</returns>
-
-    djsassert(isComplex(data), "jsonLightIsNavProp - data is not an object!!");
-    if (!!data[name + "@" + navUrlAnnotation] || (dataItemModel && dataItemModel.relationship)) {
-        return true;
-    }
-
-    // Sniff the property value.
-    var value = isArray(data[name]) ? data[name][0] : data[name];
-    return jsonLightIsEntry(value);
-};
-*/
-
-var jsonLightIsPrimitiveType = function (typeName) {
-    /// <summary>Determines whether a type name is a primitive type in a JSON light payload.</summary>
-    /// <param name="typeName" type="String">Type name to test.</param>
-    /// <returns type="Boolean">True if the type name an EDM primitive type or an OData spatial type; false otherwise.</returns>
-
-    return isPrimitiveEdmType(typeName) || isGeographyEdmType(typeName) || isGeometryEdmType(typeName);
-};
-
-var jsonLightReadDataAnnotations = function (data, obj, baseURI, dataModel, model) {
-    /// <summary>Converts annotations found in a JSON light payload object to either properties or metadata.</summary>
-    /// <param name="data" type="Object">JSON light payload object containing the annotations to convert.</param>
-    /// <param name="obj" type="Object">Object that will store the converted annotations.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-    /// <param name="dataModel" type="Object">Object describing the JSON light payload in an OData conceptual schema.</param>
-    /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
-    /// <returns>JSON light payload object with its annotations converted to either properties or metadata.</param>
-
-    for (var name in data) {
-        if (name.indexOf(".") > 0 && name.charAt(0) !== "#") {
-            var annotationInfo = jsonLightAnnotationInfo(name);
-            if (annotationInfo) {
-                var annotationName = annotationInfo.name;
-                var target = annotationInfo.target;
-                var targetModel = null;
-                var targetType = null;
-
-                if (target) {
-                    targetModel = jsonLightDataItemModel(target, dataModel);
-                    targetType = jsonLightDataItemType(target, data[target], data, targetModel, model);
-                }
-
-                if (annotationInfo.isOData) {
-                    jsonLightApplyPayloadODataAnnotation(annotationName, target, targetType, data[name], data, obj, baseURI);
-                } else {
-                    obj[name] = data[name];
-                }
-            }
-        }
-    }
-    return obj;
-};
-
-var jsonLightApplyPayloadODataAnnotation = function (name, target, targetType, value, data, obj, baseURI) {
-    /// <summary>
-    ///   Processes a JSON Light payload OData annotation producing either a property, payload metadata, or property metadata on its owner object.
-    /// </summary>
-    /// <param name="name" type="String">Annotation name.</param>
-    /// <param name="target" type="String">Name of the property that is being targeted by the annotation.</param>
-    /// <param name="targetType" type="String">Type name of the target property.</param>
-    /// <param name="data" type="Object">JSON light object containing the annotation.</param>
-    /// <param name="obj" type="Object">Object that will hold properties produced by the annotation.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-
-    var annotation = name.substring(odataAnnotationPrefix.length);
-
-    switch (annotation) {
-        case "navigationLinkUrl":
-            jsonLightApplyNavigationUrlAnnotation(annotation, target, targetType, value, data, obj, baseURI);
-            return;
-        case "nextLink":
-        case "count":
-            jsonLightApplyFeedAnnotation(annotation, target, value, obj, baseURI);
-            return;
-        case "mediaReadLink":
-        case "mediaEditLink":
-        case "mediaContentType":
-        case "mediaETag":
-            jsonLightApplyMediaAnnotation(annotation, target, targetType, value, obj, baseURI);
-            return;
-        default:
-            jsonLightApplyMetadataAnnotation(annotation, target, value, obj, baseURI);
-            return;
-    }
-};
-
-var jsonLightApplyMetadataAnnotation = function (name, target, value, obj, baseURI) {
-    /// <summary>
-    ///    Converts a JSON light annotation that applies to entry metadata only (i.e. odata.editLink or odata.readLink) and its value
-    ///    into their library's internal representation and saves it back to data.
-    /// </summary>
-    /// <param name="name" type="String">Annotation name.</param>
-    /// <param name="target" type="String">Name of the property on which the annotation should be applied.</param>
-    /// <param name="value" type="Object">Annotation value.</param>
-    /// <param name="obj" type="Object">Object that will hold properties produced by the annotation.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-
-    var metadata = obj.__metadata = obj.__metadata || {};
-    var mappedName = jsonLightNameMap[name] || name;
-
-    if (name === "editLink") {
-        metadata.uri = normalizeURI(value, baseURI);
-        metadata[mappedName] = metadata.uri;
-        return;
-    }
-
-    if (name === "readLink" || name === "associationLinkUrl") {
-        value = normalizeURI(value, baseURI);
-    }
-
-    if (target) {
-        var propertiesMetadata = metadata.properties = metadata.properties || {};
-        var propertyMetadata = propertiesMetadata[target] = propertiesMetadata[target] || {};
-
-        if (name === "type") {
-            propertyMetadata[mappedName] = propertyMetadata[mappedName] || value;
-            return;
-        }
-        propertyMetadata[mappedName] = value;
-        return;
-    }
-    metadata[mappedName] = value;
-};
-
-var jsonLightApplyFeedAnnotation = function (name, target, value, obj, baseURI) {
-    /// <summary>
-    ///    Converts a JSON light annotation that applies to feeds only (i.e. odata.count or odata.nextlink) and its value
-    ///    into their library's internal representation and saves it back to data.
-    /// </summary>
-    /// <param name="name" type="String">Annotation name.</param>
-    /// <param name="target" type="String">Name of the property on which the annotation should be applied.</param>
-    /// <param name="value" type="Object">Annotation value.</param>
-    /// <param name="obj" type="Object">Object that will hold properties produced by the annotation.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-
-    var mappedName = jsonLightNameMap[name];
-    var feed = target ? obj[target] : obj;
-    feed[mappedName] = (name === "nextLink") ? normalizeURI(value, baseURI) : value;
-};
-
-var jsonLightApplyMediaAnnotation = function (name, target, targetType, value, obj, baseURI) {
-    /// <summary>
-    ///    Converts a JSON light media annotation in and its value into their library's internal representation
-    ///    and saves it back to data or metadata.
-    /// </summary>
-    /// <param name="name" type="String">Annotation name.</param>
-    /// <param name="target" type="String">Name of the property on which the annotation should be applied.</param>
-    /// <param name="targetType" type="String">Type name of the target property.</param>
-    /// <param name="value" type="Object">Annotation value.</param>
-    /// <param name="obj" type="Object">Object that will hold properties produced by the annotation.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-
-    var metadata = obj.__metadata = obj.__metadata || {};
-    var mappedName = jsonLightNameMap[name];
-
-    if (name === "mediaReadLink" || name === "mediaEditLink") {
-        value = normalizeURI(value, baseURI);
-    }
-
-    if (target) {
-        var propertiesMetadata = metadata.properties = metadata.properties || {};
-        var propertyMetadata = propertiesMetadata[target] = propertiesMetadata[target] || {};
-        propertyMetadata.type = propertyMetadata.type || targetType;
-
-        obj.__metadata = metadata;
-        obj[target] = obj[target] || { __mediaresource: {} };
-        obj[target].__mediaresource[mappedName] = value;
-        return;
-    }
-
-    metadata[mappedName] = value;
-};
-
-var jsonLightApplyNavigationUrlAnnotation = function (name, target, targetType, value, data, obj, baseURI) {
-    /// <summary>
-    ///    Converts a JSON light navigation property annotation and its value into their library's internal representation
-    ///    and saves it back to data o metadata.
-    /// </summary>
-    /// <param name="name" type="String">Annotation name.</param>
-    /// <param name="target" type="String">Name of the property on which the annotation should be applied.</param>
-    /// <param name="targetType" type="String">Type name of the target property.</param>
-    /// <param name="value" type="Object">Annotation value.</param>
-    /// <param name="data" type="Object">JSON light object containing the annotation.</param>
-    /// <param name="obj" type="Object">Object that will hold properties produced by the annotation.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-
-    var metadata = obj.__metadata = obj.__metadata || {};
-    var propertiesMetadata = metadata.properties = metadata.properties || {};
-    var propertyMetadata = propertiesMetadata[target] = propertiesMetadata[target] || {};
-    var uri = normalizeURI(value, baseURI);
-
-    if (data.hasOwnProperty(target)) {
-        // The navigation property is inlined in the payload,
-        // so the navigation link url should be pushed to the object's
-        // property metadata instead.
-        propertyMetadata.navigationLinkUrl = uri;
-        return;
-    }
-    obj[target] = { __deferred: { uri: uri} };
-    propertyMetadata.type = propertyMetadata.type || targetType;
-};
-
-
-var jsonLightReadDataItemValue = function (value, typeName, dataItemMetadata, baseURI, dataItemModel, model, recognizeDates) {
-    /// <summary>Converts the value of a data item in a JSON light object to its library representation.</summary>
-    /// <param name="value">Data item value to convert.</param>
-    /// <param name="typeName" type="String">Type name of the data item.</param>
-    /// <param name="dataItemMetadata" type="Object">Object containing metadata about the data item.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-    /// <param name="dataItemModel" type="Object" optional="true">Object describing the data item in an OData conceptual schema.</param>
-    /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
-    /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
-    /// <returns>Data item value in its library representation.</param>
-
-    if (typeof value === "string") {
-        return jsonLightReadStringPropertyValue(value, typeName, recognizeDates);
-    }
-
-    if (!jsonLightIsPrimitiveType(typeName)) {
-        if (isArray(value)) {
-            return jsonLightReadCollectionPropertyValue(value, typeName, dataItemMetadata, baseURI, model, recognizeDates);
-        }
-
-        if (isComplex(value)) {
-            return jsonLightReadComplexPropertyValue(value, typeName, dataItemMetadata, baseURI, model, recognizeDates);
-        }
-    }
-    return value + typeName;
-};
-
-var jsonLightReadStringPropertyValue = function (value, propertyType, recognizeDates) {
-    /// <summary>Convertes the value of a string property in a JSON light object to its library representation.</summary>
-    /// <param name="value" type="String">String value to convert.</param>
-    /// <param name="propertyType" type="String">Type name of the property.</param>
-    /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
-    /// <returns>String property value in its library representation.</returns>
-
-    switch (propertyType) {
-        case EDM_TIME:
-            return parseDuration(value);
-        case EDM_DATETIME:
-            return parseDateTime(value, /*nullOnError*/false);
-        case EDM_DATETIMEOFFSET:
-            return parseDateTimeOffset(value, /*nullOnError*/false);
-    }
-
-    if (recognizeDates) {
-        return parseDateTime(value, /*nullOnError*/true) ||
-               parseDateTimeOffset(value, /*nullOnError*/true) ||
-               value;
-    }
-    return value;
-};
-
-var jsonLightReadCollectionPropertyValue = function (value, propertyType, propertyMetadata, baseURI, model, recognizeDates) {
-    /// <summary>Converts the value of a collection property in a JSON light object into its library representation.</summary>
-    /// <param name="value" type="Array">Collection property value to convert.</param>
-    /// <param name="propertyType" type="String">Property type name.</param>
-    /// <param name="propertyMetadata" type="Object">Object containing metadata about the collection property.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-    /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
-    /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
-    /// <returns type="Object">Collection property value in its library representation.</returns>
-
-    var collectionType = getCollectionType(propertyType);
-    var itemsMetadata = [];
-    var items = [];
-
-    var i, len;
-    for (i = 0, len = value.length; i < len; i++) {
-        var itemType = jsonLightDataItemType(null, value[i]) || collectionType;
-        var itemMetadata = { type: itemType };
-        var item = jsonLightReadDataItemValue(value[i], itemType, itemMetadata, baseURI, null, model, recognizeDates);
-
-        if (!jsonLightIsPrimitiveType(itemType) && !isPrimitive(value[i])) {
-            itemsMetadata.push(itemMetadata);
-        }
-        items.push(item);
-    }
-
-    if (itemsMetadata.length > 0) {
-        propertyMetadata.elements = itemsMetadata;
-    }
-
-    return { __metadata: { type: propertyType }, results: items };
-};
-
-var jsonLightReadComplexPropertyValue = function (value, propertyType, propertyMetadata, baseURI, model, recognizeDates) {
-    /// <summary>Converts the value of a comples property in a JSON light object into its library representation.</summary>
-    /// <param name="value" type="Object">Complex property value to convert.</param>
-    /// <param name="propertyType" type="String">Property type name.</param>
-    /// <param name="propertyMetadata" type="Object">Object containing metadata about the complx type property.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-    /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
-    /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
-    /// <returns type="Object">Complex property value in its library representation.</returns>
-
-    var complexValue = jsonLightReadObject(value, { type: propertyType }, baseURI, model, recognizeDates);
-    var complexMetadata = complexValue.__metadata;
-    var complexPropertiesMetadata = complexMetadata.properties;
-
-    if (complexPropertiesMetadata) {
-        propertyMetadata.properties = complexPropertiesMetadata;
-        delete complexMetadata.properties;
-    }
-    return complexValue;
-};
-
-var jsonLightReadNavigationPropertyValue = function (value, propertyInfo, baseURI, model, recognizeDates) {
-    /// <summary>Converts the value of a navigation property in a JSON light object into its library representation.</summary>
-    /// <param name="value">Navigation property property value to convert.</param>
-    /// <param name="propertyInfo" type="String">Information about the property whether it's an entry, feed or complex type.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-    /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
-    /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
-    /// <returns type="Object">Collection property value in its library representation.</returns>
-
-    if (isArray(value)) {
-        return jsonLightReadFeed(value, propertyInfo, baseURI, model, recognizeDates);
-    }
-
-    if (isComplex(value)) {
-        return jsonLightReadObject(value, propertyInfo, baseURI, model, recognizeDates);
-    }
-    return null;
-};
-
-var jsonLightReadComplexObjectNew = function (data, property, baseURI, model, demandedFormat, recognizeDates) {
-    var type = property.type;
-    if (isCollectionType(property.type)) {
-        type =property.type.substring(11,property.type.length-1);
-    }
-
-    data['@odata.type'] = '#'+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
-    }
-
-    var curType = propertyType;
-
-
-    for (var name in data) {
-        if (name.indexOf("@") === -1) {
-            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 (demandedFormat === 3)  {
-                if ( isArray(propertyValue)) {
-                    data[name+'@odata.type'] = '#' + property.type;
-                    for ( var i = 0; i < propertyValue.length; i++) {
-                        jsonLightReadComplexObjectNew(propertyValue[0], property,baseURI,model,demandedFormat, recognizeDates);
-                    }
-                } else if (isObject(propertyValue) && (propertyValue!= null)) {
-                    jsonLightReadComplexObjectNew(propertyValue, property,baseURI,model,demandedFormat, recognizeDates);
-                } else {
-                    data[name+'@odata.type'] = '#' + property.type;
-                }
-                
-            } else {
-
-            }
-        }
-    }
-}
-
-
-var jsonLightReadObjectNew = function (data, objectInfo, baseURI, model, demandedFormat, recognizeDates) {
-    //var obj = {};
-
-    data['@odata.type'] = '#'+objectInfo.typeName;
-
-    var keyType = objectInfo.type;
-    while (( keyType.key === undefined) && (keyType.baseType !== undefined)) {
-        keyType = lookupEntityType(keyType.baseType, model);
-    }
-
-    var lastIdSegment = objectInfo.name + jsonLightGetEntryKey(data, keyType);
-    data['@odata.id'] = baseURI.substring(0, baseURI.lastIndexOf("$metadata")) + lastIdSegment;
-    data['@odata.editLink'] = lastIdSegment;
-
-    var serviceURI = baseURI.substring(0, baseURI.lastIndexOf("$metadata"));
-    //jsonLightComputeUrisIfMissing(data, entryInfo, actualType, serviceURI, dataModel, baseTypeModel);
-
-    
-
-    for (var name in data) {
-        if (name.indexOf("@") === -1) {
-            var curType = objectInfo.type;
-            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 (demandedFormat === 3)  {
-                if ( isArray(propertyValue)) {
-                    data[name+'@odata.type'] = '#' + property.type;
-                    for ( var i = 0; i < propertyValue.length; i++) {
-                        jsonLightReadComplexObjectNew(propertyValue[0], property,baseURI,model,demandedFormat, recognizeDates);
-                    }
-                } else if (isObject(propertyValue) && (propertyValue!= null)) {
-                    jsonLightReadComplexObjectNew(propertyValue, property,baseURI,model,demandedFormat, recognizeDates);
-                } else {
-                    data[name+'@odata.type'] = '#' + property.type;
-                }
-                
-            } else {
-
-            }
-        }
-    }
-
-    return data;
-};
-
-var jsonLightReadObject = function (data, objectInfo, baseURI, model, recognizeDates) {
-    /// <summary>Converts a JSON light entry or complex type object into its library representation.</summary>
-    /// <param name="data" type="Object">JSON light entry or complex type object to convert.</param>
-    /// <param name="objectInfo" type="Object">Information about the entry or complex.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-    /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
-    /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
-    /// <returns type="Object">Entry or complex type object.</param>
-
-    objectInfo = objectInfo || {};
-    var actualType = data[typeAnnotation] || objectInfo.type || null;
-    var dataModel = lookupEntityType(actualType, model);
-    var isEntry = true;
-    if (!dataModel) {
-        isEntry = false;
-        dataModel = lookupComplexType(actualType, model);
-    }
-
-    var metadata = { type: actualType };
-    var obj = { __metadata: metadata };
-    var propertiesMetadata = {};
-    var baseTypeModel;
-    if (isEntry && dataModel && objectInfo.entitySet && objectInfo.contentTypeOdata === "minimalmetadata") {
-        var serviceURI = baseURI.substring(0, baseURI.lastIndexOf("$metadata"));
-        baseTypeModel = null; // check if the key model is in a parent type.
-        if (!dataModel.key) {
-            baseTypeModel = dataModel;
-        }
-        while (!!baseTypeModel && !baseTypeModel.key && baseTypeModel.baseType) {
-            baseTypeModel = lookupEntityType(baseTypeModel.baseType, model);
-        }
-
-        if (dataModel.key || (!!baseTypeModel && baseTypeModel.key)) {
-            var entryKey;
-            if (dataModel.key) {
-                entryKey = jsonLightGetEntryKey(data, dataModel);
-            } else {
-                entryKey = jsonLightGetEntryKey(data, baseTypeModel);
-            }
-            if (entryKey) {
-                var entryInfo = {
-                    key: entryKey,
-                    entitySet: objectInfo.entitySet,
-                    functionImport: objectInfo.functionImport,
-                    containerName: objectInfo.containerName
-                };
-                jsonLightComputeUrisIfMissing(data, entryInfo, actualType, serviceURI, dataModel, baseTypeModel);
-            }
-        }
-    }
-
-    for (var name in data) {
-        if (name.indexOf("#") === 0) {
-            // This is an advertised function or action.
-            jsonLightReadAdvertisedFunctionOrAction(name.substring(1), data[name], obj, baseURI, model);
-        } else {
-            // Is name NOT an annotation?
-            if (name.indexOf(".") === -1) {
-                if (!metadata.properties) {
-                    metadata.properties = propertiesMetadata;
-                }
-
-                var propertyValue = data[name];
-                var propertyModel = propertyModel = jsonLightDataItemModel(name, dataModel);
-                baseTypeModel = dataModel;
-                while (!!dataModel && propertyModel === null && baseTypeModel.baseType) {
-                    baseTypeModel = lookupEntityType(baseTypeModel.baseType, model);
-                    propertyModel = propertyModel = jsonLightDataItemModel(name, baseTypeModel);
-                }
-                var isNavigationProperty = jsonLightIsNavigationProperty(name, data, propertyModel);
-                var propertyType = jsonLightDataItemType(name, propertyValue, data, propertyModel, model);
-                var propertyMetadata = propertiesMetadata[name] = propertiesMetadata[name] || { type: propertyType };
-                if (isNavigationProperty) {
-                    var propertyInfo = {};
-                    if (objectInfo.entitySet !== undefined) {
-                        var navigationPropertyEntitySetName = lookupNavigationPropertyEntitySet(propertyModel, objectInfo.entitySet.name, model);
-                        propertyInfo = getEntitySetInfo(navigationPropertyEntitySetName, model);
-                    }
-                    propertyInfo.contentTypeOdata = objectInfo.contentTypeOdata;
-                    propertyInfo.kind = objectInfo.kind;
-                    propertyInfo.type = propertyType;
-                    obj[name] = jsonLightReadNavigationPropertyValue(propertyValue, propertyInfo, baseURI, model, recognizeDates);
-                } else {
-                    obj[name] = jsonLightReadDataItemValue(propertyValue, propertyType, propertyMetadata, baseURI, propertyModel, model, recognizeDates);
-                }
-            }
-        }
-    }
-
-    return jsonLightReadDataAnnotations(data, obj, baseURI, dataModel, model);
-};
-
-var jsonLightReadAdvertisedFunctionOrAction = function (name, value, obj, baseURI, model) {
-    /// <summary>Converts a JSON light advertised action or function object into its library representation.</summary>
-    /// <param name="name" type="String">Advertised action or function name.</param>
-    /// <param name="value">Advertised action or function value.</param>
-    /// <param name="obj" type="Object">Object that will the converted value of the advertised action or function.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing the action's or function's relative URIs.</param>
-    /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
-    /// <remarks>
-    ///     Actions and functions have the same representation in json light, so to disambiguate them the function uses
-    ///     the model object.  If available, the function will look for the functionImport object that describes the
-    ///     the action or the function.  If for whatever reason the functionImport can't be retrieved from the model (like
-    ///     there is no model available or there is no functionImport within the model), then the value is going to be treated
-    ///     as an advertised action and stored under obj.__metadata.actions.
-    /// </remarks>
-
-    if (!name || !isArray(value) && !isComplex(value)) {
-        return;
-    }
-
-    var isFunction = false;
-    var nsEnd = name.lastIndexOf(".");
-    var simpleName = name.substring(nsEnd + 1);
-    var containerName = (nsEnd > -1) ? name.substring(0, nsEnd) : "";
-
-    var container = (simpleName === name || containerName.indexOf(".") === -1) ?
-        lookupDefaultEntityContainer(model) :
-        lookupEntityContainer(containerName, model);
-
-    if (container) {
-        var functionImport = lookupFunctionImport(container.functionImport, simpleName);
-        if (functionImport && !!functionImport.isSideEffecting) {
-            isFunction = !parseBool(functionImport.isSideEffecting);
-        }
-    }
-
-    var metadata = obj.__metadata;
-    var targetName = isFunction ? "functions" : "actions";
-    var metadataURI = normalizeURI(name, baseURI);
-    var items = (isArray(value)) ? value : [value];
-
-    var i, len;
-    for (i = 0, len = items.length; i < len; i++) {
-        var item = items[i];
-        if (item) {
-            var targetCollection = metadata[targetName] = metadata[targetName] || [];
-            var actionOrFunction = { metadata: metadataURI, title: item.title, target: normalizeURI(item.target, baseURI) };
-            targetCollection.push(actionOrFunction);
-        }
-    }
-};
-
-var jsonLightReadFeedNew = function (data, feedInfo, baseURI, model, demandedFormat,recognizeDates) {
-    var entries = [];
-    var items = data.value;
-    for (i = 0, len = items.length; i < len; i++) {
-        //TODO SK check if items[i] has @odata.type and use this type instead of  feedinfo
-        
-        if ( items[i]['@odata.type'] !== undefined) {
-            var typeName = items[i]['@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 = jsonLightReadObjectNew(items[i], entryInfo, baseURI, model, demandedFormat,recognizeDates);
-        } else {
-            entry = jsonLightReadObjectNew(items[i], feedInfo, baseURI, model, demandedFormat,recognizeDates);
-        }
-        
-        entries.push(entry);
-    }
-    data.value = entries;
-    return data;
-};
-
-var jsonLightReadFeed = function (data, feedInfo, baseURI, model, recognizeDates) {
-    /// <summary>Converts a JSON light feed or top level collection property object into its library representation.</summary>
-    /// <param name="data" type="Object">JSON light feed object to convert.</param>
-    /// <param name="typeName" type="String">Type name of the feed or collection items.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-    /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
-    /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
-    /// <returns type="Object">Feed or top level collection object.</param>
-
-    var items = isArray(data) ? data : data.value;
-    var entries = [];
-    var i, len, entry;
-    for (i = 0, len = items.length; i < len; i++) {
-        entry = jsonLightReadObject(items[i], feedInfo, baseURI, model, recognizeDates);
-        entries.push(entry);
-    }
-
-    var feed = { results: entries };
-
-    if (isComplex(data)) {
-        for (var name in data) {
-            if (name.indexOf("#") === 0) {
-                // This is an advertised function or action.
-                feed.__metadata = feed.__metadata || {};
-                jsonLightReadAdvertisedFunctionOrAction(name.substring(1), data[name], feed, baseURI, model);
-            }
-        }
-        feed = jsonLightReadDataAnnotations(data, feed, baseURI);
-    }
-    return feed;
-};
-
-var jsonLightGetEntryKey = function (data, entityModel) {
-    /// <summary>Gets the key of an entry.</summary>
-    /// <param name="data" type="Object">JSON light entry.</param>
-    /// <param name="entityModel" type="String">Object describing the entry Model</param>
-    /// <returns type="string">Entry instance key.</returns>
-
-    var entityInstanceKey;
-    var entityKeys = entityModel.key[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;
-};
-
-
-var jsonLightComputeUrisIfMissing = function (data, entryInfo, actualType, serviceURI, entityModel, baseTypeModel) {
-    /// <summary>Compute the URI according to OData conventions if it doesn't exist</summary>
-    /// <param name="data" type="Object">JSON light entry.</param>
-    /// <param name="entryInfo" type="Object">Information about the entry includes type, key, entitySet and entityContainerName.</param>
-    /// <param name="actualType" type="String">Type of the entry</param>
-    /// <param name="serviceURI" type="String">Base URI the service.</param>
-    /// <param name="entityModel" type="Object">Object describing an OData conceptual schema of the entry.</param>
-    /// <param name="baseTypeModel" type="Object" optional="true">Object escribing an OData conceptual schema of the baseType if it exists.</param>
-
-    var lastIdSegment = data[jsonLightAnnotations.id] || data[jsonLightAnnotations.read] || data[jsonLightAnnotations.edit] || entryInfo.entitySet.name + entryInfo.key;
-    data[jsonLightAnnotations.id] = serviceURI + lastIdSegment;
-    if (!data[jsonLightAnnotations.edit]) {
-        data[jsonLightAnnotations.edit] = entryInfo.entitySet.name + entryInfo.key;
-        if (entryInfo.entitySet.entityType != actualType) {
-            data[jsonLightAnnotations.edit] += "/" + actualType;
-        }
-    }
-    data[jsonLightAnnotations.read] = data[jsonLightAnnotations.read] || data[jsonLightAnnotations.edit];
-    if (!data[jsonLightAnnotations.etag]) {
-        var etag = jsonLightComputeETag(data, entityModel, baseTypeModel);
-        if (!!etag) {
-            data[jsonLightAnnotations.etag] = etag;
-        }
-    }
-
-    jsonLightComputeStreamLinks(data, entityModel, baseTypeModel);
-    jsonLightComputeNavigationAndAssociationProperties(data, entityModel, baseTypeModel);
-    jsonLightComputeFunctionImports(data, entryInfo);
-};
-
-var jsonLightComputeETag = function (data, entityModel, baseTypeModel) {
-    /// <summary>Computes the etag of an entry</summary>
-    /// <param name="data" type="Object">JSON light entry.</param>
-    /// <param name="entryInfo" type="Object">Object describing the entry model.</param>
-    /// <param name="baseTypeModel" type="Object"  optional="true">Object describing an OData conceptual schema of the baseType if it exists.</param>
-    /// <returns type="string">Etag value</returns>
-    var etag = "";
-    var propertyModel;
-    for (var i = 0; entityModel.property && i < entityModel.property.length; i++) {
-        propertyModel = entityModel.property[i];
-        etag = jsonLightAppendValueToEtag(data, etag, propertyModel);
-
-    }
-    if (baseTypeModel) {
-        for (i = 0; baseTypeModel.property && i < baseTypeModel.property.length; i++) {
-            propertyModel = baseTypeModel.property[i];
-            etag = jsonLightAppendValueToEtag(data, etag, propertyModel);
-        }
-    }
-    if (etag.length > 0) {
-        return etag + "\"";
-    }
-    return null;
-};
-
-var jsonLightAppendValueToEtag = function (data, etag, propertyModel) {
-    /// <summary>Adds a propery value to the etag after formatting.</summary>
-    /// <param name="data" type="Object">JSON light entry.</param>
-    /// <param name="etag" type="Object">value of the etag.</param>
-    /// <param name="propertyModel" type="Object">Object describing an OData conceptual schema of the property.</param>
-    /// <returns type="string">Etag value</returns>
-
-    if (propertyModel.concurrencyMode == "Fixed") {
-        if (etag.length > 0) {
-            etag += ",";
-        } else {
-            etag += "W/\"";
-        }
-        if (data[propertyModel.name] !== null) {
-            etag += formatLiteral(data[propertyModel.name], propertyModel.type);
-        } else {
-            etag += "null";
-        }
-    }
-    return etag;
-};
-
-var jsonLightComputeNavigationAndAssociationProperties = function (data, entityModel, baseTypeModel) {
-    /// <summary>Adds navigation links to the entry metadata</summary>
-    /// <param name="data" type="Object">JSON light entry.</param>
-    /// <param name="entityModel" type="Object">Object describing the entry model.</param>
-    /// <param name="baseTypeModel" type="Object"  optional="true">Object describing an OData conceptual schema of the baseType if it exists.</param>
-
-    var navigationLinkAnnotation = "@odata.navigationLinkUrl";
-    var associationLinkAnnotation = "@odata.associationLinkUrl";
-    var navigationPropertyName, navigationPropertyAnnotation, associationPropertyAnnotation;
-    for (var i = 0; entityModel.navigationProperty && i < entityModel.navigationProperty.length; i++) {
-        navigationPropertyName = entityModel.navigationProperty[i].name;
-        navigationPropertyAnnotation = navigationPropertyName + navigationLinkAnnotation;
-        if (data[navigationPropertyAnnotation] === undefined) {
-            data[navigationPropertyAnnotation] = data[jsonLightAnnotations.edit] + "/" + encodeURIComponent(navigationPropertyName);
-        }
-        associationPropertyAnnotation = navigationPropertyName + associationLinkAnnotation;
-        if (data[associationPropertyAnnotation] === undefined) {
-            data[associationPropertyAnnotation] = data[jsonLightAnnotations.edit] + "/$links/" + encodeURIComponent(navigationPropertyName);
-        }
-    }
-
-    if (baseTypeModel && baseTypeModel.navigationProperty) {
-        for (i = 0; i < baseTypeModel.navigationProperty.length; i++) {
-            navigationPropertyName = baseTypeModel.navigationProperty[i].name;
-            navigationPropertyAnnotation = navigationPropertyName + navigationLinkAnnotation;
-            if (data[navigationPropertyAnnotation] === undefined) {
-                data[navigationPropertyAnnotation] = data[jsonLightAnnotations.edit] + "/" + encodeURIComponent(navigationPropertyName);
-            }
-            associationPropertyAnnotation = navigationPropertyName + associationLinkAnnotation;
-            if (data[associationPropertyAnnotation] === undefined) {
-                data[associationPropertyAnnotation] = data[jsonLightAnnotations.edit] + "/$links/" + encodeURIComponent(navigationPropertyName);
-            }
-        }
-    }
-};
-
-var formatLiteral = function (value, type) {
-    /// <summary>Formats a value according to Uri literal format</summary>
-    /// <param name="value">Value to be formatted.</param>
-    /// <param name="type">Edm type of the value</param>
-    /// <returns type="string">Value after formatting</returns>
-
-    value = "" + formatRowLiteral(value, type);
-    value = encodeURIComponent(value.replace("'", "''"));
-    switch ((type)) {
-        case "Edm.Binary":
-            return "X'" + value + "'";
-        case "Edm.DateTime":
-            return "datetime" + "'" + value + "'";
-        case "Edm.DateTimeOffset":
-            return "datetimeoffset" + "'" + value + "'";
-        case "Edm.Decimal":
-            return value + "M";
-        case "Edm.Guid":
-            return "guid" + "'" + value + "'";
-        case "Edm.Int64":
-            return value + "L";
-        case "Edm.Float":
-            return value + "f";
-        case "Edm.Double":
-            return value + "D";
-        case "Edm.Geography":
-            return "geography" + "'" + value + "'";
-        case "Edm.Geometry":
-            return "geometry" + "'" + value + "'";
-        case "Edm.Time":
-            return "time" + "'" + value + "'";
-        case "Edm.String":
-            return "'" + value + "'";
-        default:
-            return value;
-    }
-};
-
-
-var formatRowLiteral = function (value, type) {
-    switch (type) {
-        case "Edm.Binary":
-            return convertByteArrayToHexString(value);
-        default:
-            return value;
-    }
-};
-
-var jsonLightComputeFunctionImports = function (data, entryInfo) {
-    /// <summary>Adds functions and actions links to the entry metadata</summary>
-    /// <param name="entry" type="Object">JSON light entry.</param>
-    /// <param name="entityInfo" type="Object">Object describing the entry</param>
-
-    var functionImport = entryInfo.functionImport || [];
-    for (var i = 0; i < functionImport.length; i++) {
-        if (functionImport[i].isBindable && functionImport[i].parameter[0] && functionImport[i].parameter[0].type == entryInfo.entitySet.entityType) {
-            var functionImportAnnotation = "#" + entryInfo.containerName + "." + functionImport[i].name;
-            if (data[functionImportAnnotation] == undefined) {
-                data[functionImportAnnotation] = {
-                    title: functionImport[i].name,
-                    target: data[jsonLightAnnotations.edit] + "/" + functionImport[i].name
-                };
-            }
-        }
-    }
-};
-
-var jsonLightComputeStreamLinks = function (data, entityModel, baseTypeModel) {
-    /// <summary>Adds stream links to the entry metadata</summary>
-    /// <param name="data" type="Object">JSON light entry.</param>
-    /// <param name="entityModel" type="Object">Object describing the entry model.</param>
-    /// <param name="baseTypeModel" type="Object"  optional="true">Object describing an OData conceptual schema of the baseType if it exists.</param>
-
-    if (entityModel.hasStream || (baseTypeModel && baseTypeModel.hasStream)) {
-        data[jsonLightAnnotations.mediaEdit] = data[jsonLightAnnotations.mediaEdit] || data[jsonLightAnnotations.mediaEdit] + "/$value";
-        data[jsonLightAnnotations.mediaRead] = data[jsonLightAnnotations.mediaRead] || data[jsonLightAnnotations.mediaEdit];
-    }
-};
-/*
-var jsonLightReadTopPrimitiveProperty = function (data, typeName, baseURI, recognizeDates) {
-    /// <summary>Converts a JSON light top level primitive property object into its library representation.</summary>
-    /// <param name="data" type="Object">JSON light feed object to convert.</param>
-    /// <param name="typeName" type="String">Type name of the primitive property.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-    /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
-    /// <returns type="Object">Top level primitive property object.</param>
-
-    var metadata = { type: typeName };
-    var value = jsonLightReadDataItemValue(data.value, typeName, metadata, baseURI, null, null, recognizeDates);
-    return jsonLightReadDataAnnotations(data, { __metadata: metadata, value: value }, baseURI);
-};*/
-
-/*
-var jsonLightReadTopCollectionProperty = function (data, typeName, baseURI, model, recognizeDates) {
-    /// <summary>Converts a JSON light top level collection property object into its library representation.</summary>
-    /// <param name="data" type="Object">JSON light feed object to convert.</param>
-    /// <param name="typeName" type="String">Type name of the collection property.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-    /// <param name="model" type="Object" optional="true">Object describing an OData conceptual schema.</param>
-    /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
-    /// <returns type="Object">Top level collection property object.</param>
-
-    var propertyMetadata = {};
-    var value = jsonLightReadCollectionPropertyValue(data.value, typeName, propertyMetadata, baseURI, model, recognizeDates);
-    extend(value.__metadata, propertyMetadata);
-    return jsonLightReadDataAnnotations(data, value, baseURI);
-};*/
-
-/*
-var jsonLightReadLinksDocument = function (data, baseURI) {
-    /// <summary>Converts a JSON light links collection object to its library representation.</summary>
-    /// <param name="data" type="Object">JSON light link object to convert.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-    /// <returns type="Object">Links collection object.</param>
-
-    var items = data.value;
-    if (!isArray(items)) {
-        return jsonLightReadLink(data, baseURI);
-    }
-
-    var results = [];
-    var i, len;
-    for (i = 0, len = items.length; i < len; i++) {
-        results.push(jsonLightReadLink(items[i], baseURI));
-    }
-
-    var links = { results: results };
-    return jsonLightReadDataAnnotations(data, links, baseURI);
-};*/
-
-/*
-var jsonLightReadLink = function (data, baseURI) {
-    /// <summary>Converts a JSON light link object to its library representation.</summary>
-    /// <param name="data" type="Object">JSON light link object to convert.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-    /// <returns type="Object">Link object.</param>
-
-    var link = { uri: normalizeURI(data.url, baseURI) };
-
-    link = jsonLightReadDataAnnotations(data, link, baseURI);
-    var metadata = link.__metadata || {};
-    var metadataProperties = metadata.properties || {};
-
-    jsonLightRemoveTypePropertyMetadata(metadataProperties.url);
-    renameProperty(metadataProperties, "url", "uri");
-
-    return link;
-};*/
-/*
-var jsonLightRemoveTypePropertyMetadata = function (propertyMetadata) {
-    /// <summary>Removes the type property from a property metadata object.</summary>
-    /// <param name="propertyMetadata" type="Object">Property metadata object.</param>
-
-    if (propertyMetadata) {
-        delete propertyMetadata.type;
-    }
-};*/
-/*
-var jsonLightReadSvcDocument = function (data, baseURI) {
-    /// <summary>Converts a JSON light service document object to its library representation.</summary>
-    /// <param name="data" type="Object">JSON light service document object to convert.</param>
-    /// <param name="baseURI" type="String">Base URI for normalizing relative URIs found in the payload.</param>
-    /// <returns type="Object">Link object.</param>
-
-    var items = data.value;
-    var collections = [];
-    var workspace = jsonLightReadDataAnnotations(data, { collections: collections }, baseURI);
-
-    var metadata = workspace.__metadata || {};
-    var metadataProperties = metadata.properties || {};
-
-    jsonLightRemoveTypePropertyMetadata(metadataProperties.value);
-    renameProperty(metadataProperties, "value", "collections");
-
-    var i, len;
-    for (i = 0, len = items.length; i < len; i++) {
-        var item = items[i];
-        var collection = { title: item.name, href: normalizeURI(item.url, baseURI) };
-
-        collection = jsonLightReadDataAnnotations(item, collection, baseURI);
-        metadata = collection.__metadata || {};
-        metadataProperties = metadata.properties || {};
-
-        jsonLightRemoveTypePropertyMetadata(metadataProperties.name);
-        jsonLightRemoveTypePropertyMetadata(metadataProperties.url);
-
-        renameProperty(metadataProperties, "name", "title");
-        renameProperty(metadataProperties, "url", "href");
-
-        collections.push(collection);
-    }
-
-    return { workspaces: [workspace] };
-};*/
-
-
-
-
-
-
-var jsonLightSerializableMetadata = ["@odata.type", "@odata.etag", "@odata.mediaEditLink", "@odata.mediaReadLink", "@odata.mediaContentType", "@odata.mediaEtag"];
-
-var formatJsonLightRequestPayload = function (data) {
-    if (!data) {
-        return data;
-    }
-
-    if (isPrimitive(data)) {
-        return data;
-    }
-
-    if (isArray(data)) {
-        var newArrayData = [];
-        var i, len;
-        for (i = 0, len = data.length; i < len; i++) {
-            newArrayData[i] = formatJsonLightRequestPayload(data[i]);
-        }
-
-        return newArrayData;
-    }
-
-    var newdata = {};
-    for (var property in data) {
-        if (isJsonLightSerializableProperty(property)) {
-            newdata[property] = formatJsonLightRequestPayload(data[property]);
-        }
-    }
-
-    return newdata;
-};
-
-var isJsonLightSerializableProperty = function (property) {
-    if (!property) {
-        return false;
-    }
-
-    if (property.indexOf("@odata.") == -1) {
-        return true;
-    }
-
-    var i, len;
-    for (i = 0, len = jsonLightSerializableMetadata.length; i < len; i++) {
-        var name = jsonLightSerializableMetadata[i];
-        if (property.indexOf(name) != -1) {
-            return true;
-        }
-    }
-
-    return false;
-};
-
-var formatJsonLight = function (obj, context) {
-    /// <summary>Converts an object in the library's internal representation to its json light representation.</summary>
-    /// <param name="obj" type="Object">Object the library's internal representation.</param>
-    /// <param name="context" type="Object">Object with the serialization context.</param>
-    /// <returns type="Object">Object in its json light representation.</returns>
-
-    // Regular expression used to test that the uri is for a $links document.
-    var linksUriRE = /\/\$links\//;
-    var data = {};
-    var metadata = obj.__metadata;
-
-    var islinks = context && linksUriRE.test(context.request.requestUri);
-    formatJsonLightData(obj, (metadata && metadata.properties), data, islinks);
-    return data;
-};
-
-var formatJsonLightMetadata = function (metadata, data) {
-    /// <summary>Formats an object's metadata into the appropriate json light annotations and saves them to data.</summary>
-    /// <param name="obj" type="Object">Object whose metadata is going to be formatted as annotations.</param>
-    /// <param name="data" type="Object">Object on which the annotations are going to be stored.</param>
-
-    if (metadata) {
-        var i, len;
-        for (i = 0, len = jsonLightSerializableMetadata.length; i < len; i++) {
-            // There is only a subset of metadata values that are interesting during update requests.
-            var name = jsonLightSerializableMetadata[i];
-            var qName = odataAnnotationPrefix + (jsonLightNameMap[name] || name);
-            formatJsonLightAnnotation(qName, null, metadata[name], data);
-        }
-    }
-};
-
-var formatJsonLightData = function (obj, pMetadata, data, isLinks) {
-    /// <summary>Formats an object's data into the appropriate json light values and saves them to data.</summary>
-    /// <param name="obj" type="Object">Object whose data is going to be formatted.</param>
-    /// <param name="pMetadata" type="Object">Object that contains metadata for the properties that are being formatted.</param>
-    /// <param name="data" type="Object">Object on which the formatted values are going to be stored.</param>
-    /// <param name="isLinks" type="Boolean">True if a links document is being formatted.  False otherwise.</param>
-
-    for (var key in obj) {
-        var value = obj[key];
-        if (key === "__metadata") {
-            // key is the object metadata.
-            formatJsonLightMetadata(value, data);
-        } else if (key.indexOf(".") === -1) {
-            // key is an regular property or array element.
-            if (isLinks && key === "uri") {
-                formatJsonLightEntityLink(value, data);
-            } else {
-                formatJsonLightProperty(key, value, pMetadata, data, isLinks);
-            }
-        } else {
-            data[key] = value;
-        }
-    }
-};
-
-var MyDateTime = function(value) {
-    this.value = value;
-}
-MyDateTime.prototype.getAsDateObject = function () { return { value : this.value }};
-
-var formatJsonLightProperty = function (name, value, pMetadata, data) {
-    /// <summary>Formats an object's value identified by name to its json light representation and saves it to data.</summary>
-    /// <param name="name" type="String">Property name.</param>
-    /// <param name="value">Property value.</param>
-    /// <param name="pMetadata" type="Object">Object that contains metadata for the property that is being formatted.</param>
-    /// <param name="data" type="Object">Object on which the formatted value is going to be stored.</param>
-
-    // Get property type from property metadata
-    var propertyMetadata = pMetadata && pMetadata[name] || { properties: undefined, type: undefined };
-    var typeName = dataItemTypeName(value, propertyMetadata);
-
-    if (isPrimitive(value) || !value) {
-        // It is a primitive value then.
-        formatJsonLightAnnotation(typeAnnotation, name, typeName, data);
-        
-        /*TODO*//*check the typename here*/
-        if ( typeName === 'Edm.DateTime') {
-            data[name] = new MyDateTime(value);
-        } else if ( typeName === 'Edm.DateTimeOffset') {
-            data[name] = new MyDateTime(value);
-        } else {
-            data[name] = value;
-        }
-        return;
-    }
-
-    if (isFeed(value, typeName) || isEntry(value)) {
-        formatJsonLightInlineProperty(name, value, data);
-        return;
-    }
-
-    if (!typeName && isDeferred(value)) {
-        // It is really a deferred property.
-        formatJsonLightDeferredProperty(name, value, data);
-        return;
-    }
-
-    if (isCollection(value, typeName)) {
-        // The thing is a collection, format it as one.
-        if (getCollectionType(typeName)) {
-            formatJsonLightAnnotation(typeAnnotation, name, typeName, data);
-        }
-        formatJsonLightCollectionProperty(name, value, data);
-        return;
-    }
-
-    djsassert(isComplex(value), "formatJsonLightProperty - Value is not a complex type value");
-
-    // Format the complex property value in a new object in data[name].
-    data[name] = {};
-    formatJsonLightAnnotation(typeAnnotation, null, typeName, data[name]);
-    formatJsonLightData(value, propertyMetadata.properties, data[name]);
-};
-
-var formatJsonLightEntityLink = function (value, data) {
-    /// <summary>Formats an entity link in a $links document and saves it into data.</summary>
-    /// <param name="value" type="String">Entity link value.</summary>
-    /// <param name="data" type="Object">Object on which the formatted value is going to be stored.</param>
-    data.url = value;
-};
-
-var formatJsonLightDeferredProperty = function (name, value, data) {
-    /// <summary>Formats the object value's identified by name as an odata.navigalinkurl annotation and saves it to data.</summary>
-    /// <param name="name" type="String">Name of the deferred property to be formatted.</param>
-    /// <param name="value" type="Object">Deferred property value to be formatted.</param>
-    /// <param name="data" type="Object">Object on which the formatted value is going to be stored.</param>
-
-    formatJsonLightAnnotation(navUrlAnnotation, name, value.__deferred.uri, data);
-};
-
-var formatJsonLightCollectionProperty = function (name, value, data) {
-    /// <summary>Formats a collection property in obj identified by name as a json light collection property and saves it to data.</summary>
-    /// <param name="name" type="String">Name of the collection property to be formatted.</param>
-    /// <param name="value" type="Object">Collection property value to be formatted.</param>
-    /// <param name="data" type="Object">Object on which the formatted value is going to be stored.</param>
-
-    data[name] = [];
-    var items = isArray(value) ? value : value.results;
-    formatJsonLightData(items, null, data[name]);
-};
-
-var formatJsonLightInlineProperty = function (name, value, data) {
-    /// <summary>Formats an inline feed or entry property in obj identified by name as a json light value and saves it to data.</summary>
-    /// <param name="name" type="String">Name of the inline feed or entry property to be formatted.</param>
-    /// <param name="value" type="Object or Array">Value of the inline feed or entry property.</param>
-    /// <param name="data" type="Object">Object on which the formatted value is going to be stored.</param>
-
-    if (isFeed(value)) {
-        data[name] = [];
-        // Format each of the inline feed entries
-        var entries = isArray(value) ? value : value.results;
-        var i, len;
-        for (i = 0, len = entries.length; i < len; i++) {
-            formatJsonLightInlineEntry(name, entries[i], true, data);
-        }
-        return;
-    }
-    formatJsonLightInlineEntry(name, value, false, data);
-};
-
-var formatJsonLightInlineEntry = function (name, value, inFeed, data) {
-    /// <summary>Formats an inline entry value in the property identified by name as a json light value and saves it to data.</summary>
-    /// <param name="name" type="String">Name of the inline feed or entry property that owns the entry formatted.</param>
-    /// <param name="value" type="Object">Inline entry value to be formatted.</param>
-    /// <param name="inFeed" type="Boolean">True if the entry is in an inline feed; false otherwise.
-    /// <param name="data" type="Object">Object on which the formatted value is going to be stored.</param>
-
-    // This might be a bind instead of a deep insert.
-    var uri = value.__metadata && value.__metadata.uri;
-    if (uri) {
-        formatJsonLightBinding(name, uri, inFeed, data);
-        return;
-    }
-
-    var entry = formatJsonLight(value);
-    if (inFeed) {
-        data[name].push(entry);
-        return;
-    }
-    data[name] = entry;
-};
-
-var formatJsonLightBinding = function (name, uri, inFeed, data) {
-    /// <summary>Formats an entry binding in the inline property in obj identified by name as an odata.bind annotation and saves it to data.</summary>
-    /// <param name="name" type="String">Name of the inline property that has the binding to be formated.</param>
-    /// <param name="uri" type="String">Uri to the bound entry.</param>
-    /// <param name="inFeed" type="Boolean">True if the binding is in an inline feed; false otherwise.
-    /// <param name="data" type="Object">Object on which the formatted value is going to be stored.</param>
-
-    var bindingName = name + bindAnnotation;
-    if (inFeed) {
-        // The binding is inside an inline feed, so merge it with whatever other bindings already exist in data.
-        data[bindingName] = data[bindingName] || [];
-        data[bindingName].push(uri);
-        return;
-    }
-    // The binding is on an inline entry; it can be safely overwritten.
-    data[bindingName] = uri;
-};
-
-var formatJsonLightAnnotation = function (qName, target, value, data) {
-    /// <summary>Formats a value as a json light annotation and stores it in data</summary>
-    /// <param name="qName" type="String">Qualified name of the annotation.</param>
-    /// <param name="target" type="String">Name of the property that the metadata value targets.</param>
-    /// <param name="value">Annotation value.</param>
-    /// <param name="data" type="Object">Object on which the annotation is going to be stored.</param>
-
-    if (value !== undefined) {
-        if(target) {
-            data[target + "@" + qName] = value;
-        }
-        else {
-            data[qName] = value;
-        }
-    }
-};
-
-// DATAJS INTERNAL START
-//exports.jsonLightPayloadInfo = jsonLightPayloadInfo;
-//exports.jsonLightReadPayload = jsonLightReadPayload;
-exports.formatJsonLight = formatJsonLight;
-exports.formatJsonLightRequestPayload = formatJsonLightRequestPayload;
-// DATAJS INTERNAL END
diff --git a/datajs/src/lib/odata/json.js b/datajs/src/lib/odata/json.js
index 43803f4..91f6d47 100644
--- a/datajs/src/lib/odata/json.js
+++ b/datajs/src/lib/odata/json.js
@@ -802,10 +802,6 @@
     }
 };
 
-
-
-
-
 var checkProperties = function(data,objectInfoType,baseURI,model, demandedFormat, recognizeDates) {
     for (var name in data) {
         if (name.indexOf("@") === -1) {
@@ -850,14 +846,11 @@
 
     data['@odata.type'] = '#'+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, demandedFormat, recognizeDates);
 };
 
@@ -891,125 +884,10 @@
 
 exports.jsonHandler = jsonHandler;
 
-// DATAJS INTERNAL START
 exports.jsonParser = jsonParser;
 exports.jsonSerializer = jsonSerializer;
 
 exports.parseJsonDateString = parseJsonDateString;
 exports.jsonLightPayloadInfo = jsonLightPayloadInfo;
-// DATAJS INTERNAL END
 
-//exports.jsonNormalizeData = jsonNormalizeData;
-//exports.normalizeServiceDocument = normalizeServiceDocument;
 
-/*
-var jsonReadAdvertisedActionsOrFunctions = function (value) {
-    /// <summary>Reads and object containing action or function metadata and maps them into a single array of objects.</summary>
-    /// <param name="value" type="Object">Object containing action or function metadata.</param>
-    /// <returns type="Array">Array of objects containing metadata for the actions or functions specified in value.</returns>
-
-    var result = [];
-    for (var name in value) {
-        var i, len;
-        for (i = 0, len = value[name].length; i < len; i++) {
-            result.push(extend({ metadata: name }, value[name][i]));
-        }
-    }
-    return result;
-};*/
-
-/*
-var jsonApplyMetadata = function (value, metadata, dateParser, recognizeDates) {
-    /// <summary>Applies metadata coming from both the payload and the metadata object to the value.</summary>
-    /// <param name="value" type="Object">Data on which the metada is going to be applied.</param>
-    /// <param name="metadata">Metadata store; one of edmx, schema, or an array of any of them.</param>
-    /// <param name="dateParser" type="function">Function used for parsing datetime values.</param>
-    /// <param name="recognizeDates" type="Boolean">
-    ///     True if strings formatted as datetime values should be treated as datetime values. False otherwise.
-    /// </param>
-    /// <returns type="Object">Transformed data.</returns>
-
-    if (value && typeof value === "object") {
-        var dataTypeName;
-        var valueMetadata = value.__metadata;
-
-        if (valueMetadata) {
-            if (valueMetadata.actions) {
-                valueMetadata.actions = jsonReadAdvertisedActionsOrFunctions(valueMetadata.actions);
-            }
-            if (valueMetadata.functions) {
-                valueMetadata.functions = jsonReadAdvertisedActionsOrFunctions(valueMetadata.functions);
-            }
-            dataTypeName = valueMetadata && valueMetadata.type;
-        }
-
-        var dataType = lookupEntityType(dataTypeName, metadata) || lookupComplexType(dataTypeName, metadata);
-        var propertyValue;
-        if (dataType) {
-            var properties = dataType.property;
-            if (properties) {
-                var i, len;
-                for (i = 0, len = properties.length; i < len; i++) {
-                    var property = properties[i];
-                    var propertyName = property.name;
-                    propertyValue = value[propertyName];
-
-                    if (property.type === "Edm.DateTime" || property.type === "Edm.DateTimeOffset") {
-                        if (propertyValue) {
-                            propertyValue = dateParser(propertyValue);
-                            if (!propertyValue) {
-                                throw { message: "Invalid date/time value" };
-                            }
-                            value[propertyName] = propertyValue;
-                        }
-                    } else if (property.type === "Edm.Time") {
-                        if (propertyValue) {
-                            value[propertyName] = parseDuration(propertyValue);    
-                        }
-                    }
-                }
-            }
-        } else if (recognizeDates) {
-            for (var name in value) {
-                propertyValue = value[name];
-                if (typeof propertyValue === "string") {
-                    value[name] = dateParser(propertyValue) || propertyValue;
-                }
-            }
-        }
-    }
-    return value;
-};*/
-/*
-var isJsonLight = function (contentType) {
-    /// <summary>Tests where the content type indicates a json light payload.</summary>
-    /// <param name="contentType">Object with media type and properties dictionary.</param>
-    /// <returns type="Boolean">True is the content type indicates a json light payload. False otherwise.</returns>
-
-    if (contentType) {
-        var odata = contentType.properties["odata.metadata"];
-        return odata === "none" || odata === "minimal" || odata === "full";
-    }
-    return false;
-};*/
-/*
-var normalizeServiceDocument = function (data, baseURI) {
-    /// <summary>Normalizes a JSON service document to look like an ATOM service document.</summary>
-    /// <param name="data" type="Object">Object representation of service documents as deserialized.</param>
-    /// <param name="baseURI" type="String">Base URI to resolve relative URIs.</param>
-    /// <returns type="Object">An object representation of the service document.</returns>
-    var workspace = { collections: [] };
-
-    var i, len;
-    for (i = 0, len = data.EntitySets.length; i < len; i++) {
-        var title = data.EntitySets[i];
-        var collection = {
-            title: title,
-            href: normalizeURI(title, baseURI)
-        };
-
-        workspace.collections.push(collection);
-    }
-
-    return { workspaces: [workspace] };
-};*/
\ No newline at end of file
