public static async Task<List<CRMEntityDisplayName>> GetEntityDisplayNameList(this CRMWebAPI api, int LCID=0)
        {
            var result = new List<CRMEntityDisplayName>();

            CRMGetListOptions options = new CRMGetListOptions()
            {
                Filter = "IsPrivate eq false",

                Select = new[] { "MetadataId","EntitySetName","DisplayName",
                        "DisplayCollectionName","LogicalName","LogicalCollectionName","PrimaryIdAttribute" }
            };

            var queryResults = await api.GetList("EntityDefinitions", options);

            foreach(dynamic entity in queryResults.List)
            {
                CRMEntityDisplayName edm = new CRMEntityDisplayName();
                edm.MetadataId = Guid.Parse(entity.MetadataId);
                edm.EntitySetName = entity.EntitySetName;
                edm.LogicalName = entity.LogicalName;
                edm.LogicalCollectionName = entity.LogicalCollectionName;
                edm.PrimaryIdAttribute = entity.PrimaryIdAttribute;
                if ((entity.DisplayName.LocalizedLabels != null) && (entity.DisplayName.LocalizedLabels.Count > 0))
                {
                    edm.DisplayName = entity.DisplayName.LocalizedLabels[0].Label;
                    if (LCID != 0)
                        foreach (dynamic label in entity.DisplayName.LocalizedLabels)
                        { if (label.LanguageCode == LCID) edm.DisplayName = label.Label; }
                        
                }
                else
                    edm.DisplayName = edm.LogicalName;
                if ((entity.DisplayCollectionName.LocalizedLabels != null) && (entity.DisplayCollectionName.LocalizedLabels.Count > 0))
                {
                    edm.DisplayCollectionName = entity.DisplayCollectionName.LocalizedLabels[0].Label;
                    if (LCID != 0)
                        foreach (dynamic label in entity.DisplayCollectionName.LocalizedLabels)
                        { if (label.LanguageCode == LCID) edm.DisplayCollectionName = label.Label; }
                }
                else
               edm.DisplayCollectionName = entity.LogicalCollectionName;
               edm.LogicalDisplayName = edm.DisplayName + "(" + edm.LogicalName + ")";
               edm.LogicalDisplayCollectionName = edm.DisplayCollectionName + "(" + edm.LogicalCollectionName + ")";

               result.Add(edm);

            }

            return result;

        }
        public static async Task<ExpandoObject> GetOptionSetByName(this CRMWebAPI api, string optionSetName)
        {
            CRMGetListOptions options = new CRMGetListOptions() { Select = new[] { "Name" } };

            var queryResult = await api.GetList("GlobalOptionSetDefinitions", options);

            foreach(dynamic optionSet in queryResult.List)
            {
                
                if ((optionSet != null)  && (optionSet.Name == optionSetName))
                {
                    var matchingOptionSet = await api.Get("GlobalOptionSetDefinitions", Guid.Parse( optionSet.MetadataId));

                    return matchingOptionSet;
                }
            }

            return null; 

        }
        public static async Task<List<CRMAttributeDisplayName>> GetAttributeDisplayNameList(this CRMWebAPI api, Guid entityID,int LCID = 0)
        {
            var result = new List<CRMAttributeDisplayName>();

            CRMGetListOptions options = new CRMGetListOptions()
            {
                Filter = "((IsValidForRead eq true) and (AttributeOf eq null))",

                Select = new[] { "MetadataId", "DisplayName", "LogicalName", "SchemaName", "AttributeType", "IsPrimaryId" }
            };

            var queryResults = await api.GetList("EntityDefinitions(" + entityID.ToString() + ")/Attributes", options);

            foreach (dynamic attrib in queryResults.List)
            {
                CRMAttributeDisplayName edm = new CRMAttributeDisplayName();
                edm.MetadataId = Guid.Parse(attrib.MetadataId);
                edm.LogicalName = attrib.LogicalName;
                edm.SchemaName = attrib.SchemaName;
                edm.IsPrimaryId = attrib.IsPrimaryId;
                edm.AttributeType = attrib.AttributeType;
                if (attrib.AttributeType == "Lookup" || attrib.AttributeType == "Customer" || attrib.AttributeType == "Owner")
                    edm.ODataLogicalName = "_" + attrib.LogicalName + "_value";
                else
                    edm.ODataLogicalName = attrib.LogicalName;

                if ((attrib.DisplayName.LocalizedLabels != null) && (attrib.DisplayName.LocalizedLabels.Count > 0))
                {
                    edm.DisplayName = attrib.DisplayName.LocalizedLabels[0].Label;
                    if (LCID != 0)
                        foreach (dynamic label in attrib.DisplayName.LocalizedLabels)
                        { if (label.LanguageCode == LCID) edm.DisplayName = label.Label; }
                }
                else
                    edm.DisplayName = edm.LogicalName;
                edm.LogicalDisplayName = edm.DisplayName + "(" + edm.LogicalName + ")";
                result.Add(edm);
            }



                return result;

        }
        public void TestExpandQuery()
        {

            Task.Run(async () =>
            {
                var api = GetAPI();

                dynamic whoamiResults = await api.ExecuteFunction("WhoAmI");
                CRMGetListOptions userOptions = new CRMGetListOptions()
                {
                     Expand = new CRMExpandOptions[]
                        { new CRMExpandOptions()
                            { Property="businessunitid",
                              Select = new string[] { "businessunitid","name","websiteurl" }
                            }
                        }
                };
                
                var userResults = await api.Get("systemusers",Guid.Parse(whoamiResults.UserId),QueryOptions:userOptions);

                CRMGetListOptions buOptions = new CRMGetListOptions()
                {
                    Expand = new CRMExpandOptions[]
                       { new CRMExpandOptions()
                            { Property="business_unit_system_users",
                              Select = new string[] { "systemuserid","fullname" },
                              Filter = "systemuserid ne " + whoamiResults.UserId,
                              OrderBy = new string[] {"createdon asc"},
                              Top=5

                            }
                       }
                };
                var buResult = await api.Get("businessunits",
                     Guid.Parse(userResults.businessunitid.businessunitid),
                      QueryOptions: buOptions);
                dynamic userCount = buResult.business_unit_system_users.Count;

                System.Diagnostics.Trace.WriteLine("finished");


            }).Wait();
        }