﻿/// <reference path="json2.js">
// =====================================================================
//  This file is part of the Microsoft Dynamics CRM SDK code samples.
//
//  Copyright (C) Microsoft Corporation.  All rights reserved.
//
//  This source code is intended only as a supplement to Microsoft
//  Development Tools and/or on-line documentation.  See these other
//  materials for detailed information regarding Microsoft code samples.
//
//  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
// =====================================================================
// <snippetSDK.MetaData.js>
//var DEV_URL = "http://abnc-crm3:5560/insurance2011";
//var DEV_URL = "http://localhost:5555/mindfiresolutions2011";

var DEV_URL = 'http://localhost:5558/mfbbsrcrm';
if (typeof (SDK) == "undefined")
{ SDK = { __namespace: true }; }
// Namespace container for functions in this library.
SDK.MetaData = {
    _ServerUrl: function () {///<summary>
        /// Private function used to establish the path to the SOAP endpoint based on context
        /// provided by the Xrm.Page object or the context object returned by the GlobalContext object.
        ///</summary>
        var ServerUrl;

        var errorMessage = "Context to retrieve the Server URL is not available.";
        if (typeof GetGlobalContext != "undefined")
        { ServerUrl = GetGlobalContext().getServerUrl(); }
        else {
            if (typeof Xrm != "undefined") {
                ServerUrl = Xrm.Page.context.getServerUrl();
            }
            else {
                if (typeof DEV_URL != "undefined") {
                    ServerUrl = DEV_URL;
                } else {
                    return new Error(errorMessage);
                }
            }
        }
        if (ServerUrl.match(/\/$/)) {
            ServerUrl = ServerUrl.substring(0, ServerUrl.length - 1);
        }
        return ServerUrl + "/XRMServices/2011/Organization.svc/web";
    },
    RetrieveAttributeRequest: function (EntityName, AttributeLogicalName, MetadataId, RetrieveAsIfPublished, successCallBack, errorCallBack) {
        var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
        request += "<request i:type=\"a:RetrieveAttributeRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
        request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>EntityLogicalName</b:key>";
        request += "<b:value i:type=\"c:string\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + EntityName + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        if (MetadataId == null)
        { MetadataId = "00000000-0000-0000-0000-000000000000"; }
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>MetadataId</b:key>";
        request += "<b:value i:type=\"ser:guid\"  xmlns:ser=\"http://schemas.microsoft.com/2003/10/Serialization/\">" + MetadataId + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>RetrieveAsIfPublished</b:key>";
        request += "<b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + RetrieveAsIfPublished + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>LogicalName</b:key>";
        request += "<b:value i:type=\"c:string\"   xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + AttributeLogicalName + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "</a:Parameters>";
        request += "<a:RequestId i:nil=\"true\" /><a:RequestName>RetrieveAttribute</a:RequestName></request>";
        request += "</Execute>";
        request = this._getSOAPWrapper(request);

        var req = new XMLHttpRequest();
        var async = (!!successCallBack);
        req.open("POST", this._ServerUrl(), async);
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", this._Action.Execute);
        if (async)
            req.onreadystatechange = function () { SDK.MetaData._returnAttribute(req, successCallBack, errorCallBack) };
        req.send(request);

        if (!async) {
            var attrMetadataNodes = req.responseXML.selectNodes("//b:value");
            var attrObj = {};
            if (attrMetadataNodes.length > 0) {
                attributeData = attrMetadataNodes[0];
                var a = new SDK.MetaData._attributeMetadata(attributeData);
                var attribute;

                switch (a.AttributeType) {
                    case "BigInt":
                        attribute = new SDK.MetaData._bigIntAttributeMetadata(attributeData);
                        break;
                    case "Boolean":
                        attribute = new SDK.MetaData._booleanAttributeMetadata(attributeData);
                        break;
                    case "CalendarRules":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "Customer":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "DateTime":
                        attribute = new SDK.MetaData._dateTimeAttributeMetadata(attributeData);
                        break;
                    case "Decimal":
                        attribute = new SDK.MetaData._decimalAttributeMetadata(attributeData);
                        break;
                    case "Double":
                        attribute = new SDK.MetaData._doubleAttributeMetadata(attributeData);
                        break;
                    case "EntityName":
                        attribute = new SDK.MetaData._entityNameAttributeMetadata(attributeData);
                        break;
                    case "Integer":
                        attribute = new SDK.MetaData._integerAttributeMetadata(attributeData);
                        break;
                    case "Lookup":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "ManagedProperty":
                        attribute = new SDK.MetaData._managedPropertyAttributeMetadata(attributeData);
                        break;
                    case "Memo":
                        attribute = new SDK.MetaData._memoAttributeMetadata(attributeData);
                        break;
                    case "Money":
                        attribute = new SDK.MetaData._moneyAttributeMetadata(attributeData);
                        break;
                    case "Owner":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "PartyList":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "Picklist":
                        attribute = new SDK.MetaData._picklistAttributeMetadata(attributeData);
                        break;
                    case "State":
                        attribute = new SDK.MetaData._stateAttributeMetadata(attributeData);
                        break;
                    case "Status":
                        attribute = new SDK.MetaData._statusAttributeMetadata(attributeData);
                        break;
                    case "String":
                        attribute = new SDK.MetaData._stringAttributeMetadata(attributeData);
                        break;
                    case "Uniqueidentifier":
                        attribute = new SDK.MetaData._attributeMetadata(attributeData);
                        break;
                    case "Virtual": //Contains the text value of picklist fields
                        attribute = new SDK.MetaData._attributeMetadata(attributeData);
                        break;
                }
                return attribute;
            }
        }
    },
    _returnAttribute: function (resp, successCallBack, errorCallBack) {
        if (resp.readyState == 4 /* complete */) {
            if (resp.status == 200) {
                //Success				
                var attrMetadataNodes = resp.responseXML.selectNodes("//b:value");
                if (attrMetadataNodes.length > 0) {
                    attributeData = attrMetadataNodes[0];
                    var a = new SDK.MetaData._attributeMetadata(attributeData);
                    var attribute;

                    switch (a.AttributeType) {
                        case "BigInt":
                            attribute = new SDK.MetaData._bigIntAttributeMetadata(attributeData);
                            break;
                        case "Boolean":
                            attribute = new SDK.MetaData._booleanAttributeMetadata(attributeData);
                            break;
                        case "CalendarRules":
                            attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                            break;
                        case "Customer":
                            attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                            break;
                        case "DateTime":
                            attribute = new SDK.MetaData._dateTimeAttributeMetadata(attributeData);
                            break;
                        case "Decimal":
                            attribute = new SDK.MetaData._decimalAttributeMetadata(attributeData);
                            break;
                        case "Double":
                            attribute = new SDK.MetaData._doubleAttributeMetadata(attributeData);
                            break;
                        case "EntityName":
                            attribute = new SDK.MetaData._entityNameAttributeMetadata(attributeData);
                            break;
                        case "Integer":
                            attribute = new SDK.MetaData._integerAttributeMetadata(attributeData);
                            break;
                        case "Lookup":
                            attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                            break;
                        case "ManagedProperty":
                            attribute = new SDK.MetaData._managedPropertyAttributeMetadata(attributeData);
                            break;
                        case "Memo":
                            attribute = new SDK.MetaData._memoAttributeMetadata(attributeData);
                            break;
                        case "Money":
                            attribute = new SDK.MetaData._moneyAttributeMetadata(attributeData);
                            break;
                        case "Owner":
                            attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                            break;
                        case "PartyList":
                            attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                            break;
                        case "Picklist":
                            attribute = new SDK.MetaData._picklistAttributeMetadata(attributeData);
                            break;
                        case "State":
                            attribute = new SDK.MetaData._stateAttributeMetadata(attributeData);
                            break;
                        case "Status":
                            attribute = new SDK.MetaData._statusAttributeMetadata(attributeData);
                            break;
                        case "String":
                            attribute = new SDK.MetaData._stringAttributeMetadata(attributeData);
                            break;
                        case "Uniqueidentifier":
                            attribute = new SDK.MetaData._attributeMetadata(attributeData);
                            break;
                        case "Virtual": //Contains the text value of picklist fields
                            attribute = new SDK.MetaData._attributeMetadata(attributeData);
                            break;
                    }
                    successCallBack(attribute);
                }
            }
            else {
                //Failure
                errorCallBack(SDK.MetaData._getError(resp));
            }
        }
    },
    UpdateSiteMapRequest: function (entity, successCallBack, errorCallBack) {
        var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
//        request += "<request i:type=\"a:UpdateRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
//        request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
//        request += "<a:KeyValuePairOfstringanyType>";
//        request += "<b:key>Target</b:key>";
//        request += "<b:value i:type=\"a:Entity\">";
//        request += "<a:Attributes>";
//        request += "    <a:KeyValuePairOfstringanyType>";
//        request += "        <b:key>sitemapidunique</b:key>";
//        request += "        <b:value i:type=\"c:guid\" xmlns:c=\"http://schemas.microsoft.com/2003/10/Serialization\">" + entity.SiteMapIdUnique + "</b:value>";
//        request += "    </a:KeyValuePairOfstringanyType>";
//        request += "    <a:KeyValuePairOfstringanyType>";
//        request += "         <b:key>solutionid</b:key>";
//        request += "         <b:value i:type=\"c:guid\" xmlns:c=\"http://schemas.microsoft.com/2003/10/Serialization\">" + entity.SolutionId + "</b:value>";
//        request += "       </a:KeyValuePairOfstringanyType>";
//        request += "    <a:KeyValuePairOfstringanyType>";
//        request += "         <b:key>ismanaged</b:key>";
//        request += "         <b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">true</b:value>";
//        request += "    </a:KeyValuePairOfstringanyType>";
//        request += "    <a:KeyValuePairOfstringanyType>";
//        request += "         <b:key>sitemapxml</b:key>";
//        request += "         <b:value i:type=\"c:string\">" + entity.SiteMapXml.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
//        request += "         </b:value>";
//        request += "    </a:KeyValuePairOfstringanyType>";
//        request += "    <a:KeyValuePairOfstringanyType>";
//        request += "         <b:key>organizationid</b:key>";
//        request += "         <b:value i:type=\"a:EntityReference\">";
//        request += "           <a:Id>" + entity.OrganizationId.Id + "</a:Id>";
//        request += "           <a:LogicalName>organization</a:LogicalName>";
//        request += "           <a:Name i:nil=\"true\" />";
//        request += "         </b:value>";
//        request += "       </a:KeyValuePairOfstringanyType>";
//        request += "    <a:KeyValuePairOfstringanyType>";
//        request += "         <b:key>sitemapid</b:key>";
//        request += "         <b:value i:type=\"c:guid\" xmlns:c=\"http://schemas.microsoft.com/2003/10/Serialization\">" + entity.SiteMapId + "</b:value>";
//        request += "    </a:KeyValuePairOfstringanyType>";
//        request += "</a:Attributes>";
//        request += "<a:Id>" + entity.SiteMapId + "</a:Id>";
//        request += "<a:LogicalName>sitemap</a:LogicalName>";
//        request += "</b:value>";
//        request += "</a:KeyValuePairOfstringanyType>";
//        request += "</a:Parameters>";
//        request += "<a:RequestId i:nil=\"true\" /><a:RequestName>Update</a:RequestName></request>";
        request += "</Execute>";
        request = this._getSOAPWrapper(request);

        var async = (!!successCallBack);
        var req = new XMLHttpRequest();
        req.open("POST", this._ServerUrl(), async);
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", this._Action.Execute);
        if (async)
            req.onreadystatechange = function () { SDK.MetaData._returnAllEntities(req, successCallBack, errorCallBack) };
        req.send(request);

        if (!async) {
            return req.responseXML.xml;
        }
    },
    PublishXmlRequest: function (xml, successCallBack, errorCallBack) {
        var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
//        request += "<request i:type=\"b:PublishXmlRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">";
//        request += "<a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
//        request += "  <a:KeyValuePairOfstringanyType>";
//        request += "    <c:key>ParameterXml</c:key>";
//        request += "    <c:value i:type=\"d:string\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\">" + xml.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;') + "</c:value>";
//        request += "  </a:KeyValuePairOfstringanyType>";
//        request += "</a:Parameters>";
//        request += "<a:RequestId i:nil=\"true\" />";
//        request += "<a:RequestName>PublishXml</a:RequestName>";
        //        request += "</request>";
        request += "<request i:type=\"b:PublishXmlRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">";
        request += "<a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
        request += "  <a:KeyValuePairOfstringanyType>";
        request += "    <c:key>ParameterXml</c:key>";
        request += "    <c:value i:type=\"d:string\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\">&lt;importexportxml&gt;&lt;sitemaps&gt;&lt;sitemap&gt;&lt;/sitemap&gt;&lt;/sitemaps&gt;&lt;/importexportxml&gt;</c:value>";
        request += "  </a:KeyValuePairOfstringanyType>";
        request += "</a:Parameters>";
        request += " <a:RequestId i:nil=\"true\" />";
        request += "<a:RequestName>PublishXml</a:RequestName>";
        request += "</request>";
        request += "</Execute>";
        var async = (!!successCallBack);
        var req = new XMLHttpRequest();
        req.open("POST", this._ServerUrl(), async);
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", this._Action.Execute);
        if (async)
            req.onreadystatechange = function () { SDK.MetaData._returnAllEntities(req, successCallBack, errorCallBack) };
        req.send(request);

        if (!async) {
            return req.responseXML.xml;
        }
    },
    RetrieveRequest: function (Type, Target, Columns, successCallBack, errorCallBack) {
        var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
        request += "<request i:type=\"a:RetrieveRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
        request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>ColumnSet</b:key>";
        request += "<b:value i:type=\"a:ColumnSet\">";
        request += "<a:AllColumns>true</a:AllColumns>";
        request += "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>Target</b:key>";
        request += "<b:value i:type=\"a:EntityReference\">";
        request += "<a:Id>" + Target + "</a:Id>";
        request += "<a:LogicalName>" + Type + "</a:LogicalName>";
        request += "<a:Name i:nil=\"true\" />";
        request += "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "</a:Parameters>";
        request += "<a:RequestId i:nil=\"true\" /><a:RequestName>Retrieve</a:RequestName></request>";
        request += "</Execute>";
        request = this._getSOAPWrapper(request);

        var async = (!!successCallBack);
        var req = new XMLHttpRequest();
        req.open("POST", this._ServerUrl(), async);
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", this._Action.Execute);
        if (async)
            req.onreadystatechange = function () { SDK.MetaData._returnAllEntities(req, successCallBack, errorCallBack) };
        req.send(request);

        if (!async) {
            return req.responseXML.xml;
        }
    },
//    PublishXmlRequest: function (xml, successCallBack, errorCallBack) {
//        var parameterxml = xml.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
//        var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
//        request += "<request i:type=\"a:PublishXmlRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
//        request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
//        request += "<a:KeyValuePairOfstringanyType>";
//        request += "<b:key>ParameterXml</b:key>";
//        request += "<b:value i:type=\"c:string\">" + parameterxml + "</b:value>";
//        request += "</a:KeyValuePairOfstringanyType>";
//        request += "</a:Parameters>";
//        request += "<a:RequestId i:nil=\"true\" /><a:RequestName>PublishXml</a:RequestName></request>";
//        request += "</Execute>";
//        request = this._getSOAPWrapper(request);

//        var async = (!!successCallBack);
//        var req = new XMLHttpRequest();
//        req.open("POST", this._ServerUrl(), async);
//        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
//        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
//        req.setRequestHeader("SOAPAction", this._Action.Execute);
//        if (async)
//            req.onreadystatechange = function () { SDK.MetaData._returnAllEntities(req, successCallBack, errorCallBack) };
//        req.send(request);

//        if (!async) {
//            return req.responseXML.xml;
//        }
//    },
    RetrieveMultipleFetchXmlRequest: function (Query, successCallBack, errorCallBack) {

        var fetchxml = Query.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
        var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
        request += "<request i:type=\"a:RetrieveMultipleRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
        request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>Query</b:key>";
        request += "<b:value i:type=\"a:FetchExpression\">";
        request += "<a:Query>" + fetchxml + "</a:Query>";
        request += "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "</a:Parameters>";
        request += "<a:RequestId i:nil=\"true\" /><a:RequestName>RetrieveMultiple</a:RequestName></request>";
        request += "</Execute>";
        request = this._getSOAPWrapper(request);

        var async = (!!successCallBack);
        var req = new XMLHttpRequest();
        req.open("POST", this._ServerUrl(), async);
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", this._Action.Execute);
        if (async)
            req.onreadystatechange = function () { SDK.MetaData._returnAllEntities(req, successCallBack, errorCallBack) };
        req.send(request);

        if (!async) {
            return req.responseXML.xml;
        }
    },
    RetrieveAllEntitiesAsync: function (EntityFilters, RetrieveAsIfPublished, successCallBack, errorCallBack) {
        ///<summary>
        /// Sends an asynchronous RetrieveAllEntities Request to retrieve all entities in the system
        ///</summary>
        ///<returns>entityMetadataCollection</returns>
        ///<param name="EntityFilters" type="String">
        /// SDK.MetaData.EntityFilters provides dictionary for the filters available to filter which data is retrieved.
        /// Alternatively a string consisting of the values 'Entity Attributes Relationships Privileges' can be used directly.
        /// Include only those elements of the entity you want to retrieve. Retrieving all parts of all entitities may take significant time.
        ///</param>
        ///<param name="RetrieveAsIfPublished" type="Boolean">
        /// Sets whether to retrieve the metadata that has not been published.
        ///</param>
        ///<param name="successCallBack" type="Function">
        /// The function that will be passed through and be called by a successful response.
        /// This function must accept the entityMetadataCollection as a parameter.
        ///</param>
        ///<param name="errorCallBack" type="Function">
        /// The function that will be passed through and be called by a failed response.
        /// This function must accept an Error object as a parameter.
        ///</param>

        var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
        request += "<request i:type=\"a:RetrieveAllEntitiesRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
        request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>EntityFilters</b:key>";
        request += "<b:value i:type=\"c:EntityFilters\" xmlns:c=\"http://schemas.microsoft.com/xrm/2011/Metadata\">" + EntityFilters + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>RetrieveAsIfPublished</b:key>";
        request += "<b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + RetrieveAsIfPublished + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "</a:Parameters>";
        request += "<a:RequestId i:nil=\"true\" /><a:RequestName>RetrieveAllEntities</a:RequestName></request>";
        request += "</Execute>";
        request = this._getSOAPWrapper(request);

        var async = (!!successCallBack);

        var req = new XMLHttpRequest();
        req.open("POST", this._ServerUrl(), async);
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", this._Action.Execute);
        if (async)
            req.onreadystatechange = function () { SDK.MetaData._returnAllEntities(req, successCallBack, errorCallBack) };
        req.send(request);

        if (!async) {
            var entityMetadataNodes = req.responseXML.selectNodes("//c:EntityMetadata");
            var entityMetadataCollection = [];
            for (var i = 0; i < entityMetadataNodes.length; i++) {
                var entityMetadata = new SDK.MetaData._entityMetaData(entityMetadataNodes[i])
                entityMetadataCollection.push(entityMetadata);
            }
            entityMetadataCollection.sort();

            return entityMetadataCollection;
        }
    },
    _returnAllEntities: function (resp, successCallBack, errorCallBack) {
        ///<summary>
        /// Private function that processes the response from SDK.MetaData.RetrieveAllEntitiesAsync
        ///</summary>
        ///<param name="resp" type="XMLHttpRequest">
        /// The XMLHttpRequest representing the response.
        ///</param>
        ///<param name="successCallBack" type="Function">
        /// The function passed through to be executed when a successful retrieval is complete.
        ///</param>
        ///<param name="errorCallBack" type="Function">
        /// The function that will be passed through and be called by a failed response.
        /// This function must accept an Error object as a parameter.
        ///</param>
        if (resp.readyState == 4 /* complete */) {
            if (resp.status == 200) {
                //Success				
                var entityMetadataNodes = resp.responseXML.selectNodes("//c:EntityMetadata");
                var entityMetadataCollection = [];
                for (var i = 0; i < entityMetadataNodes.length; i++) {
                    var entityMetadata = new SDK.MetaData._entityMetaData(entityMetadataNodes[i])
                    entityMetadataCollection.push(entityMetadata);
                }
                entityMetadataCollection.sort();
                if (successCallBack) {
                    successCallBack(entityMetadataCollection);
                }
                else {
                    resp.responseXML = JSON.stringify(entityMetadataCollection);
                }

            }
            else {
                if (errorCallBack) {
                    errorCallBack(SDK.MetaData._getError(resp));
                }
                else {
                    var e = SDK.MetaData._getError(resp)
                    alert("Error : " + e.name + " Message: " + e.message + ": " + e.number);
                }

            }

        }
    },
    RetrieveEntityAsync: function (EntityFilters, LogicalName, MetadataId, RetrieveAsIfPublished, successCallBack, errorCallBack) {
        ///<summary>
        /// Sends an asynchronous RetrieveEntity Request to retrieve a specific entity
        ///</summary>
        ///<returns>entityMetadata</returns>
        ///<param name="EntityFilters" type="String">
        /// SDK.MetaData.EntityFilters provides dictionary for the filters available to filter which data is retrieved.
        /// Alternatively a string consisting of the values 'Entity Attributes Relationships Privileges' can be used directly.
        /// Include only those elements of the entity you want to retrieve.
        ///</param>
        ///<param name="LogicalName" optional="true" type="String">
        /// The logical name of the entity requested. A null value may be used if a MetadataId is provided.
        ///</param>
        ///<param name="MetadataId" optional="true" type="String">
        /// A null value or an empty guid may be passed if a LogicalName is provided.
        ///</param>
        ///<param name="RetrieveAsIfPublished" type="Boolean">
        /// Sets whether to retrieve the metadata that has not been published.
        ///</param>
        ///<param name="successCallBack" type="Function">
        /// The function that will be passed through and be called by a successful response.
        /// This function must accept the entityMetadata as a parameter.
        ///</param>
        ///<param name="errorCallBack" type="Function">
        /// The function that will be passed through and be called by a failed response.
        /// This function must accept an Error object as a parameter.
        ///</param>
        var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
        request += "<request i:type=\"a:RetrieveEntityRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
        request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>EntityFilters</b:key>";
        request += "<b:value i:type=\"c:EntityFilters\" xmlns:c=\"http://schemas.microsoft.com/xrm/2011/Metadata\">" + EntityFilters + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        if (MetadataId == null)
        { MetadataId = "00000000-0000-0000-0000-000000000000"; }
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>MetadataId</b:key>";
        request += "<b:value i:type=\"ser:guid\"  xmlns:ser=\"http://schemas.microsoft.com/2003/10/Serialization/\">" + MetadataId + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>RetrieveAsIfPublished</b:key>";
        request += "<b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + RetrieveAsIfPublished + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>LogicalName</b:key>";
        request += "<b:value i:type=\"c:string\"   xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + LogicalName + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "</a:Parameters>";
        request += "<a:RequestId i:nil=\"true\" /><a:RequestName>RetrieveEntity</a:RequestName></request>";
        request += "</Execute>";
        request = this._getSOAPWrapper(request);

        var async = (!!successCallBack);

        var req = new XMLHttpRequest();
        req.open("POST", this._ServerUrl(), async);
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", this._Action.Execute);
        if (async)
            req.onreadystatechange = function () { SDK.MetaData._returnEntity(req, successCallBack, errorCallBack) };
        req.send(request);

        if (!async) {
            var entityMetadata = new SDK.MetaData._entityMetaData(req.responseXML.selectSingleNode("//b:value"));

            return entityMetadata;
        }
    },
    _returnEntity: function (resp, successCallBack, errorCallBack) {
        ///<summary>
        /// Private function that processes the response from SDK.MetaData.RetrieveEntityAsync
        ///</summary>
        ///<param name="resp" type="XMLHttpRequest">
        /// The XMLHttpRequest representing the response.
        ///</param>
        ///<param name="successCallBack" type="Function">
        /// The function passed through to be executed when a successful retrieval is complete.
        ///</param>
        ///<param name="errorCallBack" type="Function">
        /// The function that will be passed through and be called by a failed response.
        /// This function must accept an Error object as a parameter.
        ///</param>
        if (resp.readyState == 4 /* complete */) {
            if (resp.status == 200) {
                //Success				
                var entityMetadata = new SDK.MetaData._entityMetaData(resp.responseXML.selectSingleNode("//b:value"));

                successCallBack(entityMetadata);

            }
            else {
                //Failure
                errorCallBack(SDK.MetaData._getError(resp));
            }
        }

    },
    _getError: function (resp) {
        ///<summary>
        /// Private function that attempts to parse errors related to connectivity or WCF faults.
        ///</summary>
        ///<param name="resp" type="XMLHttpRequest">
        /// The XMLHttpRequest representing failed response.
        ///</param>

        //Error descriptions come from http://support.microsoft.com/kb/193625
        if (resp.status == 12029)
        { return new Error("The attempt to connect to the server failed."); }
        if (resp.status == 12007)
        { return new Error("The server name could not be resolved."); }
        var faultXml = resp.responseXML;
        var errorMessage = "Unknown (unable to parse the fault)";
        if (typeof faultXml == "object") {

            var bodyNode = faultXml.firstChild.firstChild;

            //Retrieve the fault node
            for (var i = 0; i < bodyNode.childNodes.length; i++) {
                var node = bodyNode.childNodes[i];

                //NOTE: This comparison does not handle the case where the XML namespace changes
                if ("s:Fault" == node.nodeName) {
                    for (var j = 0; j < node.childNodes.length; j++) {
                        var faultStringNode = node.childNodes[j];
                        if ("faultstring" == faultStringNode.nodeName) {
                            errorMessage = faultStringNode.text;
                            break;
                        }
                    }
                    break;
                }
            }
        }

        return new Error(errorMessage);

    },
    EntityFilters: {
        All: "Entity Attributes Relationships Privileges",
        Default: "Entity Attributes Relationships Privileges",
        Attributes: "Attributes",
        Entity: "Entity",
        Privileges: "Privileges",
        Relationships: "Relationships"
    },
    _Action: {
        Execute: "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute"
    },
    _getSOAPWrapper: function (request) {
        ///<summary>
        /// Private function that wraps a soap envelope around a request.
        ///</summary>
        var SOAP = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Body>";
        SOAP += request;
        SOAP += "</soapenv:Body></soapenv:Envelope>";
        return SOAP;
    },
    _associatedMenuConfiguration: function (node) {
        ///<summary>
        /// Private function that parses xml data describing AssociatedMenuConfiguration
        ///</summary>
        var orderValue;
        if (isNaN(parseInt(node.selectSingleNode("c:Order").text, 10)))
        { orderValue = null; }
        else
        { orderValue = parseInt(node.selectSingleNode("c:Order").text, 10); }
        return {
            Behavior: node.selectSingleNode("c:Behavior").text,
            Group: node.selectSingleNode("c:Group").text,
            Label: new SDK.MetaData._label(node.selectSingleNode("c:Label")),
            Order: orderValue
        };
    },
    _oneToManyRelationshipMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing OneToManyRelationshipMetadata
        ///</summary>
        return { OneToManyRelationshipMetadata: {
            MetadataId: node.selectSingleNode("c:MetadataId").text,
            IsCustomRelationship: (node.selectSingleNode("c:IsCustomRelationship").text == "true") ? true : false,
            IsCustomizable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsCustomizable")),
            IsManaged: (node.selectSingleNode("c:IsManaged").text == "true") ? true : false,
            IsValidForAdvancedFind: (node.selectSingleNode("c:IsValidForAdvancedFind").text == "true") ? true : false,
            SchemaName: node.selectSingleNode("c:SchemaName").text,
            SecurityTypes: node.selectSingleNode("c:SecurityTypes").text,
            AssociatedMenuConfiguration: new SDK.MetaData._associatedMenuConfiguration(node.selectSingleNode("c:AssociatedMenuConfiguration")),
            CascadeConfiguration: {
                Assign: node.selectSingleNode("c:CascadeConfiguration/c:Assign").text,
                Delete: node.selectSingleNode("c:CascadeConfiguration/c:Delete").text,
                Merge: node.selectSingleNode("c:CascadeConfiguration/c:Merge").text,
                Reparent: node.selectSingleNode("c:CascadeConfiguration/c:Reparent").text,
                Share: node.selectSingleNode("c:CascadeConfiguration/c:Share").text,
                Unshare: node.selectSingleNode("c:CascadeConfiguration/c:Unshare").text
            },
            ReferencedAttribute: node.selectSingleNode("c:ReferencedAttribute").text,
            ReferencedEntity: node.selectSingleNode("c:ReferencedEntity").text,
            ReferencingAttribute: node.selectSingleNode("c:ReferencingAttribute").text,
            ReferencingEntity: node.selectSingleNode("c:ReferencingEntity").text
        }
        };
    },
    _manyToManyRelationshipMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing ManyToManyRelationshipMetadata
        ///</summary>
        return { ManyToManyRelationshipMetadata: {
            MetadataId: node.selectSingleNode("c:MetadataId").text,
            IsCustomRelationship: (node.selectSingleNode("c:IsCustomRelationship").text == "true") ? true : false,
            IsCustomizable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsCustomizable")),
            IsManaged: (node.selectSingleNode("c:IsManaged").text == "true") ? true : false,
            IsValidForAdvancedFind: (node.selectSingleNode("c:IsValidForAdvancedFind").text == "true") ? true : false,
            SchemaName: node.selectSingleNode("c:SchemaName").text,
            SecurityTypes: node.selectSingleNode("c:SecurityTypes").text,
            Entity1AssociatedMenuConfiguration: new SDK.MetaData._associatedMenuConfiguration(node.selectSingleNode("c:Entity1AssociatedMenuConfiguration")),
            Entity1IntersectAttribute: node.selectSingleNode("c:Entity1IntersectAttribute").text,
            Entity1LogicalName: node.selectSingleNode("c:Entity1LogicalName").text,
            Entity2AssociatedMenuConfiguration: new SDK.MetaData._associatedMenuConfiguration(node.selectSingleNode("c:Entity2AssociatedMenuConfiguration")),
            Entity2IntersectAttribute: node.selectSingleNode("c:Entity2IntersectAttribute").text,
            Entity2LogicalName: node.selectSingleNode("c:Entity2LogicalName").text,
            IntersectEntityName: node.selectSingleNode("c:IntersectEntityName").text
        }
        };
    },
    _entityMetaData: function (node) {
        ///<summary>
        /// Private function that parses xml data describing EntityMetaData
        ///</summary>
        //Check for Attributes and add them if they are included.
        var attributes = [];
        var attributesData = node.selectSingleNode("c:Attributes")
        if (attributesData.childNodes.length > 0) {
            //There are attributes
            for (var i = 0; i < attributesData.childNodes.length; i++) {
                var attributeData = attributesData.childNodes[i];
                var attributeType = attributeData.selectSingleNode("c:AttributeType").text;
                var attribute = {};
                switch (attributeType) {
                    case "BigInt":
                        attribute = new SDK.MetaData._bigIntAttributeMetadata(attributeData);
                        break;
                    case "Boolean":
                        attribute = new SDK.MetaData._booleanAttributeMetadata(attributeData);
                        break;
                    case "CalendarRules":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "Customer":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "DateTime":
                        attribute = new SDK.MetaData._dateTimeAttributeMetadata(attributeData);
                        break;
                    case "Decimal":
                        attribute = new SDK.MetaData._decimalAttributeMetadata(attributeData);
                        break;
                    case "Double":
                        attribute = new SDK.MetaData._doubleAttributeMetadata(attributeData);
                        break;
                    case "EntityName":
                        attribute = new SDK.MetaData._entityNameAttributeMetadata(attributeData);
                        break;
                    case "Integer":
                        attribute = new SDK.MetaData._integerAttributeMetadata(attributeData);
                        break;
                    case "Lookup":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "ManagedProperty":
                        attribute = new SDK.MetaData._managedPropertyAttributeMetadata(attributeData);
                        break;
                    case "Memo":
                        attribute = new SDK.MetaData._memoAttributeMetadata(attributeData);
                        break;
                    case "Money":
                        attribute = new SDK.MetaData._moneyAttributeMetadata(attributeData);
                        break;
                    case "Owner":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "PartyList":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "Picklist":
                        attribute = new SDK.MetaData._picklistAttributeMetadata(attributeData);
                        break;
                    case "State":
                        attribute = new SDK.MetaData._stateAttributeMetadata(attributeData);
                        break;
                    case "Status":
                        attribute = new SDK.MetaData._statusAttributeMetadata(attributeData);
                        break;
                    case "String":
                        attribute = new SDK.MetaData._stringAttributeMetadata(attributeData);
                        break;
                    case "Uniqueidentifier":
                        attribute = new SDK.MetaData._attributeMetadata(attributeData);
                        break;
                    case "Virtual": //Contains the text value of picklist fields
                        attribute = new SDK.MetaData._attributeMetadata(attributeData);

                        break;
                }
                attributes.push(attribute);

            }
            attributes.sort();
        }

        //Check for Privileges and add them if they are included.
        var privileges = [];
        var privilegesData = node.selectSingleNode("c:Privileges");
        if (privilegesData.childNodes.length > 0) {
            for (var i = 0; i < privilegesData.childNodes.length; i++) {
                var privilegeData = privilegesData.childNodes[i];
                var securityPrivilegeMetadata = {
                    SecurityPrivilegeMetadata: {
                        CanBeBasic: (privilegeData.selectSingleNode("c:CanBeBasic").text == "true") ? true : false,
                        CanBeDeep: (privilegeData.selectSingleNode("c:CanBeDeep").text == "true") ? true : false,
                        CanBeGlobal: (privilegeData.selectSingleNode("c:CanBeGlobal").text == "true") ? true : false,
                        CanBeLocal: (privilegeData.selectSingleNode("c:CanBeLocal").text == "true") ? true : false,
                        Name: privilegeData.selectSingleNode("c:Name").text,
                        PrivilegeId: privilegeData.selectSingleNode("c:PrivilegeId").text,
                        PrivilegeType: privilegeData.selectSingleNode("c:PrivilegeType").text
                    }
                };
                privileges.push(securityPrivilegeMetadata);
            }
        }

        //Check for Relationships and add them if they are included.
        var manyToManyRelationships = [];
        var manyToManyRelationshipsData = node.selectSingleNode("c:ManyToManyRelationships");
        if (manyToManyRelationshipsData.childNodes.length > 0) {
            for (var i = 0; i < manyToManyRelationshipsData.childNodes.length; i++) {
                var manyToManyRelationshipMetadataData = manyToManyRelationshipsData.childNodes[i];

                var manyToManyRelationshipMetadata = new SDK.MetaData._manyToManyRelationshipMetadata(manyToManyRelationshipMetadataData);
                manyToManyRelationships.push(manyToManyRelationshipMetadata);
            }
        }

        var manyToOneRelationships = [];
        var manyToOneRelationshipsData = node.selectSingleNode("c:ManyToOneRelationships");
        if (manyToOneRelationshipsData.childNodes.length > 0) {

            for (var i = 0; i < manyToOneRelationshipsData.childNodes.length; i++) {
                var manyToOneRelationshipMetadata = new SDK.MetaData._oneToManyRelationshipMetadata(manyToOneRelationshipsData.childNodes[i]);

                manyToOneRelationships.push(manyToOneRelationshipMetadata);

            }

        }

        var oneToManyRelationships = [];
        var oneToManyRelationshipsData = node.selectSingleNode("c:OneToManyRelationships");
        if (oneToManyRelationshipsData.childNodes.length > 0) {
            for (var i = 0; i < oneToManyRelationshipsData.childNodes.length; i++) {
                var oneToManyRelationshipMetadata = new SDK.MetaData._oneToManyRelationshipMetadata(oneToManyRelationshipsData.childNodes[i]);
                oneToManyRelationships.push(oneToManyRelationshipMetadata);
            }
        }


        return {
            ActivityTypeMask: SDK.MetaData._nullableInt(node.selectSingleNode("c:ActivityTypeMask")),
            Attributes: attributes,
            AutoRouteToOwnerQueue: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:AutoRouteToOwnerQueue")),
            CanBeInManyToMany: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanBeInManyToMany")),
            CanBePrimaryEntityInRelationship: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanBePrimaryEntityInRelationship")),
            CanBeRelatedEntityInRelationship: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanBeRelatedEntityInRelationship")),
            CanCreateAttributes: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanCreateAttributes")),
            CanCreateCharts: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanCreateCharts")),
            CanCreateForms: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanCreateForms")),
            CanCreateViews: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanCreateViews")),
            CanModifyAdditionalSettings: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanModifyAdditionalSettings")),
            CanTriggerWorkflow: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:CanTriggerWorkflow")),
            Description: new SDK.MetaData._label(node.selectSingleNode("c:Description")),
            DisplayCollectionName: new SDK.MetaData._label(node.selectSingleNode("c:DisplayCollectionName")),
            DisplayName: new SDK.MetaData._label(node.selectSingleNode("c:DisplayName")),
            IconLargeName: node.selectSingleNode("c:IconLargeName").text,
            IconMediumName: node.selectSingleNode("c:IconMediumName").text,
            IconSmallName: node.selectSingleNode("c:IconSmallName").text,
            IsActivity: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsActivity")),
            IsActivityParty: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsActivityParty")),
            IsAuditEnabled: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsAuditEnabled")),
            IsAvailableOffline: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsAvailableOffline")),
            IsChildEntity: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsChildEntity")),
            IsConnectionsEnabled: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsConnectionsEnabled")),
            IsCustomEntity: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsCustomEntity")),
            IsCustomizable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsCustomizable")),
            IsDocumentManagementEnabled: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsDocumentManagementEnabled")),
            IsDuplicateDetectionEnabled: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsDuplicateDetectionEnabled")),
            IsEnabledForCharts: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsEnabledForCharts")),
            IsImportable: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsImportable")),
            IsIntersect: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsIntersect")),
            IsMailMergeEnabled: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsMailMergeEnabled")),
            IsManaged: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsManaged")),
            IsMappable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsMappable")),
            IsReadingPaneEnabled: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsReadingPaneEnabled")),
            IsRenameable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsRenameable")),
            IsValidForAdvancedFind: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsValidForAdvancedFind")),
            IsValidForQueue: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsValidForQueue")),
            IsVisibleInMobile: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsVisibleInMobile")),
            LogicalName: node.selectSingleNode("c:LogicalName").text,
            ManyToManyRelationships: manyToManyRelationships,
            ManyToOneRelationships: manyToOneRelationships,
            MetadataId: node.selectSingleNode("c:MetadataId").text,
            ObjectTypeCode: SDK.MetaData._nullableInt(node.selectSingleNode("c:ObjectTypeCode")),
            OneToManyRelationships: oneToManyRelationships,
            OwnershipType: node.selectSingleNode("c:OwnershipType").text,
            PrimaryIdAttribute: node.selectSingleNode("c:PrimaryIdAttribute").text,
            PrimaryNameAttribute: node.selectSingleNode("c:PrimaryNameAttribute").text,
            Privileges: privileges,
            RecurrenceBaseEntityLogicalName: node.selectSingleNode("c:RecurrenceBaseEntityLogicalName").text,
            ReportViewName: node.selectSingleNode("c:ReportViewName").text,
            SchemaName: node.selectSingleNode("c:SchemaName").text,
            // So the LogicalName property will be used for an array.sort().
            toString: function () { return this.LogicalName }
        };


    },
    _nullableInt: function (node) {
        ///<summary>
        /// Private function that parses xml data describing nullable Integer values
        ///</summary>
        if (node.text == "")
        { return null; }
        else
        { return parseInt(node.text, 10); }

    },
    _nullableBoolean: function (node) {
        ///<summary>
        /// Private function that parses xml data describing nullable Boolean values
        ///</summary>
        if (node.text == "")
        { return null; }
        if (node.text == "true")
        { return true; }
        else
        { return false; }
    },
    _booleanManagedProperty: function (node) {
        ///<summary>
        /// Private function that parses xml data describing BooleanManagedProperty 
        ///</summary>
        return {
            CanBeChanged: (node.selectSingleNode("a:CanBeChanged").text == "true") ? true : false,
            ManagedPropertyLogicalName: node.selectSingleNode("a:ManagedPropertyLogicalName").text,
            Value: (node.selectSingleNode("a:Value").text == "true") ? true : false
        };

    },
    _requiredLevelManagedProperty: function (node) {
        ///<summary>
        /// Private function that parses xml data describing AttributeRequiredLevelManagedProperty  
        ///</summary>
        return {
            CanBeChanged: (node.selectSingleNode("a:CanBeChanged").text == "true") ? true : false,
            ManagedPropertyLogicalName: node.selectSingleNode("a:ManagedPropertyLogicalName").text,
            Value: node.selectSingleNode("a:Value").text
        };

    },
    _label: function (node) {
        ///<summary>
        /// Private function that parses xml data describing Label 
        ///</summary>
        if (node.text == "") {
            return {
                LocalizedLabels: [],
                UserLocalizedLabel: null
            };
        }
        else {
            var locLabels = node.selectSingleNode("a:LocalizedLabels");
            var userLocLabel = node.selectSingleNode("a:UserLocalizedLabel");
            var arrLocLabels = [];
            for (var i = 0; i < locLabels.childNodes.length; i++) {
                var LocLabelNode = locLabels.childNodes[i];
                var locLabel = {
                    LocalizedLabel: {
                        IsManaged: (LocLabelNode.selectSingleNode("a:IsManaged").text == "true") ? true : false,
                        Label: LocLabelNode.selectSingleNode("a:Label").text,
                        LanguageCode: parseInt(LocLabelNode.selectSingleNode("a:LanguageCode").text, 10)
                    }
                };
                arrLocLabels.push(locLabel);
            }

            return {
                LocalizedLabels: arrLocLabels,
                UserLocalizedLabel: {
                    IsManaged: (userLocLabel.selectSingleNode("a:IsManaged").text == "true") ? true : false,
                    Label: userLocLabel.selectSingleNode("a:Label").text,
                    LanguageCode: parseInt(userLocLabel.selectSingleNode("a:LanguageCode").text, 10)
                }
            };

        }


    },
    _options: function (node) {
        ///<summary>
        /// Private function that parses xml data describing OptionSetMetadata Options 
        ///</summary>
        var optionMetadatas = [];
        for (var i = 0; i < node.childNodes.length; i++) {
            var optionMetadata = node.childNodes[i];
            var option = { OptionMetadata:
			{ MetadataId: optionMetadata.selectSingleNode("c:MetadataId").text,
			    Description: new SDK.MetaData._label(optionMetadata.selectSingleNode("c:Description")),
			    IsManaged: SDK.MetaData._nullableBoolean(optionMetadata.selectSingleNode("c:IsManaged")),
			    Label: new SDK.MetaData._label(optionMetadata.selectSingleNode("c:Label")),
			    Value: parseInt(optionMetadata.selectSingleNode("c:Value").text, 10)

			}
            };
            optionMetadatas.push(option);

        }
        return optionMetadatas;
    },
    _booleanOptionSet: function (node) {
        ///<summary>
        /// Private function that parses xml data describing BooleanOptionSetMetadata 
        ///</summary>
        if (node.childNodes.length == 0)
        { return null; }
        else {
            return {
                MetadataId: node.selectSingleNode("c:MetadataId").text,
                Description: new SDK.MetaData._label(node.selectSingleNode("c:Description")),
                DisplayName: new SDK.MetaData._label(node.selectSingleNode("c:DisplayName")),
                IsCustomOptionSet: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsCustomOptionSet")),
                IsCustomizable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsCustomizable")),
                IsGlobal: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsGlobal")),
                IsManaged: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsManaged")),
                Name: node.selectSingleNode("c:Name").text,
                OptionSetType: node.selectSingleNode("c:OptionSetType").text,
                FalseOption: {
                    MetadataId: node.selectSingleNode("c:FalseOption/c:MetadataId").text,
                    Description: new SDK.MetaData._label(node.selectSingleNode("c:FalseOption/c:Description")),
                    IsManaged: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:FalseOption/c:IsManaged")),
                    Label: new SDK.MetaData._label(node.selectSingleNode("c:FalseOption/c:Label")),
                    Value: parseInt(node.selectSingleNode("c:FalseOption/c:Value").text, 10)
                },
                TrueOption: {
                    MetadataId: node.selectSingleNode("c:TrueOption/c:MetadataId").text,
                    Description: new SDK.MetaData._label(node.selectSingleNode("c:TrueOption/c:Description")),
                    IsManaged: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:TrueOption/c:IsManaged")),
                    Label: new SDK.MetaData._label(node.selectSingleNode("c:TrueOption/c:Label")),
                    Value: parseInt(node.selectSingleNode("c:TrueOption/c:Value").text, 10)
                }
            };
        }


    },
    _optionSet: function (node) {
        ///<summary>
        /// Private function that parses xml data describing OptionSetMetadata 
        ///</summary>
        if (node.childNodes.length == 0)
        { return null; }
        else {
            return {
                MetadataId: node.selectSingleNode("c:MetadataId").text,
                Description: new SDK.MetaData._label(node.selectSingleNode("c:Description")),
                DisplayName: new SDK.MetaData._label(node.selectSingleNode("c:DisplayName")),
                IsCustomOptionSet: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsCustomOptionSet")),
                IsCustomizable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsCustomizable")),
                IsGlobal: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsGlobal")),
                IsManaged: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsManaged")),
                Name: node.selectSingleNode("c:Name").text,
                OptionSetType: node.selectSingleNode("c:OptionSetType").text,
                Options: new SDK.MetaData._options(node.selectSingleNode("c:Options"))
            };
        }


    },
    _attributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing AttributeMetadata 
        ///</summary>
        return {
            AttributeOf: node.selectSingleNode("c:AttributeOf").text,
            AttributeType: node.selectSingleNode("c:AttributeType").text,
            CanBeSecuredForCreate: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:CanBeSecuredForCreate")),
            CanBeSecuredForRead: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:CanBeSecuredForRead")),
            CanBeSecuredForUpdate: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:CanBeSecuredForUpdate")),
            CanModifyAdditionalSettings: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanModifyAdditionalSettings")),
            ColumnNumber: SDK.MetaData._nullableInt(node.selectSingleNode("c:ColumnNumber")),
            DeprecatedVersion: node.selectSingleNode("c:DeprecatedVersion").text,
            Description: new SDK.MetaData._label(node.selectSingleNode("c:Description")),
            DisplayName: new SDK.MetaData._label(node.selectSingleNode("c:DisplayName")),
            EntityLogicalName: node.selectSingleNode("c:EntityLogicalName").text,
            ExtensionData: null, //No node for ExtensionData
            IsAuditEnabled: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsAuditEnabled")),
            IsCustomAttribute: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsCustomAttribute")),
            IsCustomizable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsCustomizable")),
            IsManaged: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsManaged")),
            IsPrimaryId: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsPrimaryId")),
            IsPrimaryName: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsPrimaryName")),
            IsRenameable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsRenameable")),
            IsSecured: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsSecured")),
            IsValidForAdvancedFind: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsValidForAdvancedFind")),
            IsValidForCreate: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsValidForCreate")),
            IsValidForRead: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsValidForRead")),
            IsValidForUpdate: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsValidForUpdate")),
            LinkedAttributeId: node.selectSingleNode("c:LinkedAttributeId").text,
            LogicalName: node.selectSingleNode("c:LogicalName").text,
            MetadataId: node.selectSingleNode("c:MetadataId").text,
            RequiredLevel: new SDK.MetaData._requiredLevelManagedProperty(node.selectSingleNode("c:RequiredLevel")),
            SchemaName: node.selectSingleNode("c:SchemaName").text,
            toString: function ()
            { return this.LogicalName; }
        };
    },
    _enumAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing EnumAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.DefaultFormValue = SDK.MetaData._nullableBoolean(node.selectSingleNode("c:DefaultFormValue")),
		attributeMetadata.OptionSet = new SDK.MetaData._optionSet(node.selectSingleNode("c:OptionSet"));

        return attributeMetadata;

    },
    _stateAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing StateAttributeMetadata 
        ///</summary>
        var enumAttributeMetadata = new SDK.MetaData._enumAttributeMetadata(node);

        return enumAttributeMetadata;
    },
    _stringAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing StringAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);

        attributeMetadata.Format = node.selectSingleNode("c:Format").text;
        attributeMetadata.ImeMode = node.selectSingleNode("c:ImeMode").text;
        attributeMetadata.MaxLength = parseInt(node.selectSingleNode("c:MaxLength").text, 10);
        attributeMetadata.YomiOf = node.selectSingleNode("c:YomiOf").text;

        return attributeMetadata;

    },
    _managedPropertyAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing ManagedPropertyAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.ManagedPropertyLogicalName = node.selectSingleNode("c:ManagedPropertyLogicalName").text;
        attributeMetadata.ParentAttributeName = node.selectSingleNode("c:ParentAttributeName").text;
        attributeMetadata.ParentComponentType = SDK.MetaData._nullableInt(node.selectSingleNode("c:ParentComponentType"));
        attributeMetadata.ValueAttributeTypeCode = node.selectSingleNode("c:ValueAttributeTypeCode").text;

        return attributeMetadata;

    },
    _bigIntAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing BigIntAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.MaxValue = node.selectSingleNode("c:MaxValue").text;
        attributeMetadata.MinValue = node.selectSingleNode("c:MaxValue").text;

        return attributeMetadata;

    },
    _booleanAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing BooleanAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.DefaultValue = SDK.MetaData._nullableBoolean(node.selectSingleNode("c:DefaultValue"));
        attributeMetadata.OptionSet = new SDK.MetaData._booleanOptionSet(node.selectSingleNode("c:OptionSet"));

        return attributeMetadata;
    },
    _dateTimeAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing DateTimeAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.Format = node.selectSingleNode("c:Format").text;
        attributeMetadata.ImeMode = node.selectSingleNode("c:ImeMode").text;


        return attributeMetadata;
    },
    _decimalAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing DecimalAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.ImeMode = node.selectSingleNode("c:ImeMode").text;
        attributeMetadata.MaxValue = node.selectSingleNode("c:MaxValue").text;
        attributeMetadata.MinValue = node.selectSingleNode("c:MinValue").text;
        attributeMetadata.Precision = parseInt(node.selectSingleNode("c:Precision").text, 10);

        return attributeMetadata;
    },
    _doubleAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing DoubleAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.ImeMode = node.selectSingleNode("c:ImeMode").text,
		attributeMetadata.MaxValue = node.selectSingleNode("c:MaxValue").text;
        attributeMetadata.MinValue = node.selectSingleNode("c:MinValue").text;
        attributeMetadata.Precision = parseInt(node.selectSingleNode("c:Precision").text, 10);

        return attributeMetadata;
    },
    _entityNameAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing EntityNameAttributeMetadata 
        ///</summary>
        var _enumAttributeMetadata = new SDK.MetaData._enumAttributeMetadata(node);

        return _enumAttributeMetadata;
    },
    _integerAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing IntegerAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.Format = node.selectSingleNode("c:Format").text;
        attributeMetadata.MaxValue = parseInt(node.selectSingleNode("c:MaxValue").text, 10);
        attributeMetadata.MinValue = parseInt(node.selectSingleNode("c:MinValue").text, 10);

        return attributeMetadata;
    },
    _picklistAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing PicklistAttributeMetadata 
        ///</summary>
        var enumAttributeMetadata = new SDK.MetaData._enumAttributeMetadata(node);

        return enumAttributeMetadata;
    },
    _statusAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing StatusAttributeMetadata 
        ///</summary>
        var enumAttributeMetadata = new SDK.MetaData._enumAttributeMetadata(node);

        return enumAttributeMetadata;
    },
    _memoAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing MemoAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.Format = node.selectSingleNode("c:Format").text;
        attributeMetadata.ImeMode = node.selectSingleNode("c:ImeMode").text;
        attributeMetadata.MaxLength = parseInt(node.selectSingleNode("c:MaxLength").text, 10);

        return attributeMetadata;
    },
    _moneyAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing MoneyAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.CalculationOf = node.selectSingleNode("c:CalculationOf").text;
        attributeMetadata.ImeMode = node.selectSingleNode("c:ImeMode").text;
        attributeMetadata.MaxValue = node.selectSingleNode("c:MaxValue").text;
        attributeMetadata.MinValue = node.selectSingleNode("c:MinValue").text;
        attributeMetadata.Precision = parseInt(node.selectSingleNode("c:Precision").text, 10);
        attributeMetadata.PrecisionSource = SDK.MetaData._nullableInt(node.selectSingleNode("c:PrecisionSource"));

        return attributeMetadata;
    },
    _lookupAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing LookupAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.Targets = null;

        return attributeMetadata;
    },
    __namespace: true
};
// </snippetSDK.MetaData.js>