using System;
using System.IO;
using System.Globalization;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Crm.Sdk.Messages;
//using Microsoft.Xrm.Sdk.Workflow;
//using System.Activities;
using System.Data;
using System.Collections.Generic;
using Microsoft.Xrm.Sdk.Messages;
using System.Collections.ObjectModel;
using System.Collections;
using Microsoft.Xrm.Sdk.Metadata;

namespace VRM.VA.UserProvision.Plugin
{
    class PluginHelper
    {
        #region Generic Methods
        public static Entity GetEntity(string _entityName, string _columnsStringCommaDelimited, Guid _entityID, IOrganizationService _service, ITracingService _tracingService)
        {
            try
            {
                string[] columns = _columnsStringCommaDelimited.Split(',');

                ColumnSet cs1 = new ColumnSet();
                foreach (string columnName in columns)
                {
                    cs1.Columns.Add(columnName);
                }
                Entity currentEntity = _service.Retrieve(_entityName, _entityID, cs1);
                return currentEntity;
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                throw;
            }
        }
        
        public static String GetValueNode(System.Xml.XmlDocument doc, string key)
        {
            System.Xml.XmlNode node = doc.SelectSingleNode(String.Format("Settings/setting[@name='{0}']", key));

            if (node != null)
            {
                return node.SelectSingleNode("value").InnerText;
            }
            return string.Empty;
        }
        
        public static String GetFieldValue(Guid _inGUID, string _inEntity, string _inColumn, IOrganizationService _service, ITracingService _tracingService)
        {
            try
            {
                ColumnSet cs1 = new ColumnSet();
                cs1.Columns.Add(_inColumn);
                Guid cid = _inGUID;

                Entity currentEntity = _service.Retrieve(_inEntity, cid, cs1);
                if (currentEntity.Attributes.Contains(_inColumn) && currentEntity.Attributes[_inColumn] != null
                    && currentEntity.Attributes[_inColumn].ToString() != string.Empty)
                {
                    return currentEntity.Attributes[_inColumn].ToString();
                }
                else
                {
                    return string.Empty;
                }
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                throw;
            }
        }

        public static String GetFieldValueFetch(string _inCompareValue, string _inEntity, string _inCompareColumn, string _inReturnColumn, IOrganizationService _service, ITracingService _tracingService)
        {
            try
            {
                #region Get Profile records
                string fetchXml = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
                      <entity name='" + _inEntity + "'>";
                // Dynamically include the field from the profile that was passed in
                fetchXml += Environment.NewLine + "                        <attribute name='" + _inReturnColumn + "' />";
                fetchXml += Environment.NewLine + @"<order attribute='createdon' descending='true' />
                        <filter type='and'>
                            <condition attribute='statecode' operator='eq' value='0' />
                            <condition attribute='" + _inCompareColumn + "' operator='eq' value='";
                fetchXml += _inCompareValue;
                fetchXml += @"' />
                          </filter>
                      </entity>
                    </fetch>";
                //_tracingService.Trace(fetchXml);
                // Run the query with the FetchXML.
                FetchExpression fetchExpression = new FetchExpression(fetchXml);
                EntityCollection fetchResult = _service.RetrieveMultiple(fetchExpression);
                #endregion
                if (fetchResult.Entities.Count > 0 && fetchResult[0].Attributes.Contains(_inReturnColumn))
                {
                    return fetchResult[0].Attributes[_inReturnColumn].ToString();
                }
                else
                {
                    return string.Empty;
                }
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                throw;
            }
        }

        public static String GetStringValue(Entity anyEntity, string fld, IOrganizationService service, ITracingService tracingService)
        {
            try
            {
                string Answer = "";
                tracingService.Trace("Getting String for: " + fld);

                if (anyEntity.Attributes[fld] == null) { return Answer; }

                if (anyEntity.Attributes[fld].GetType().Equals(typeof(EntityReference)))
                {

                    tracingService.Trace("Type is Lookup");
                    RetrieveEntityRequest retrieveRequest = new RetrieveEntityRequest { EntityFilters = EntityFilters.Entity, LogicalName = ((EntityReference)anyEntity[fld]).LogicalName };
                    tracingService.Trace("Logical Name: " + ((EntityReference)anyEntity[fld]).LogicalName);

                    RetrieveEntityResponse retrieveResponse = (RetrieveEntityResponse)service.Execute(retrieveRequest);
                    if (retrieveResponse.Results.Count > 0)
                    {
                        string primaryNameAttribute = retrieveResponse.EntityMetadata.PrimaryNameAttribute;
                        tracingService.Trace("primaryNameAttribute: " + primaryNameAttribute);
                        //needs to use retrieve to get the lookup entity first
                        string lookupEntityName = ((EntityReference)anyEntity.Attributes[fld]).LogicalName;
                        Entity lookupEntity = service.Retrieve(lookupEntityName, ((EntityReference)anyEntity[fld]).Id, new ColumnSet(true));
                        if (lookupEntity.Attributes.Contains(primaryNameAttribute))
                        {
                            Answer = lookupEntity.Attributes[primaryNameAttribute].ToString();
                        }
                    }
                    else
                    {
                        Answer = "";
                    }

                    return Answer;
                }
                else if (anyEntity.Attributes[fld].GetType().Equals(typeof(System.DateTime)))
                {
                    tracingService.Trace("Type is datetime");
                    DateTime dateField = Convert.ToDateTime(anyEntity.Attributes[fld].ToString());
                    string formattedDate = dateField.Year.ToString() + dateField.Month.ToString() + dateField.Day.ToString();
                    Answer = formattedDate;
                }
                else if (anyEntity.Attributes[fld].GetType().Equals(typeof(OptionSetValue)))
                {
                    tracingService.Trace("Type is Optionset");
                    OptionSetValue myVal = anyEntity.GetAttributeValue<OptionSetValue>(fld);
                    string optionLabel = String.Empty;
                    RetrieveAttributeRequest attributeRequest = new RetrieveAttributeRequest { EntityLogicalName = anyEntity.LogicalName, LogicalName = fld, RetrieveAsIfPublished = true };
                    RetrieveAttributeResponse attributeResponse = (RetrieveAttributeResponse)service.Execute(attributeRequest);
                    AttributeMetadata attrMetadata = (AttributeMetadata)attributeResponse.AttributeMetadata;
                    PicklistAttributeMetadata picklistMetadata = (PicklistAttributeMetadata)attrMetadata;
                    // For every status code value within all of our status codes values    
                    //  (all of the values in the drop down list)    
                    foreach (OptionMetadata optionMeta in picklistMetadata.OptionSet.Options)
                    {        // Check to see if our current value matches       
                        if (optionMeta.Value == myVal.Value)
                        {
                            optionLabel = optionMeta.Label.UserLocalizedLabel.Label;
                            Answer = optionLabel;

                        }
                    }

                }
                else if (anyEntity.Attributes[fld].GetType().Equals(typeof(Boolean)))
                {
                    tracingService.Trace("Type is boolean");
                    RetrieveAttributeRequest attributeRequest = new RetrieveAttributeRequest { EntityLogicalName = anyEntity.LogicalName, LogicalName = fld, RetrieveAsIfPublished = true };
                    RetrieveAttributeResponse attributeResponse = (RetrieveAttributeResponse)service.Execute(attributeRequest);
                    AttributeMetadata attrMetadata = (AttributeMetadata)attributeResponse.AttributeMetadata;
                    BooleanAttributeMetadata booleanMetadata = (BooleanAttributeMetadata)attrMetadata;
                    // For every status code value within all of our status codes values    
                    //  (all of the values in the drop down list)    
                    if (anyEntity.GetAttributeValue<Boolean>(fld) == true)
                    {
                        Answer = booleanMetadata.OptionSet.TrueOption.Label.UserLocalizedLabel.Label;
                    }
                    else
                    {
                        Answer = booleanMetadata.OptionSet.FalseOption.Label.UserLocalizedLabel.Label;
                    }

                }
                else
                {
                    Answer = anyEntity.Attributes[fld].ToString();
                }
                return Answer;
            }
            catch (Exception ex)
            {
                tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", ex.ToString()));
                throw;
            }
        }

        public static String GetFieldDisplayName(string _Entity, string fld, IOrganizationService service, ITracingService tracingService)
        {
            try
            {
                string Answer = "";
                tracingService.Trace("Getting Display Name for: " + fld);

                RetrieveAttributeRequest attributeRequest = new RetrieveAttributeRequest { EntityLogicalName = _Entity, LogicalName = fld, RetrieveAsIfPublished = true };
                RetrieveAttributeResponse attributeResponse = (RetrieveAttributeResponse)service.Execute(attributeRequest);
                AttributeMetadata attrMetadata = (AttributeMetadata)attributeResponse.AttributeMetadata;
                Answer = attrMetadata.DisplayName.LocalizedLabels[0].Label;                    

                return Answer;
            }
            catch (Exception ex)
            {
                tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", ex.ToString()));
                throw;
            }
        }

        #region Code from:
        //https://limhong.wordpress.com/2015/06/03/mscrm-2013-activatedeactivate-records-in-crm-using-c/
        //Deactivate a record
        public static void DeactivateRecord(string entityName, Guid recordId, IOrganizationService organizationService)
        {
            var cols = new ColumnSet(new[] { "statecode", "statuscode" });

            //Check if it is Active or not
            var entity = organizationService.Retrieve(entityName, recordId, cols);

            if (entity != null && entity.GetAttributeValue<OptionSetValue>("statecode").Value == 0)
            {
                //StateCode = 1 and StatusCode = 2 for deactivating Account or Contact
                SetStateRequest setStateRequest = new SetStateRequest()
                {
                    EntityMoniker = new EntityReference
                    {
                        Id = recordId,
                        LogicalName = entityName,
                    },
                    State = new OptionSetValue(1),
                    Status = new OptionSetValue(2)
                };
                organizationService.Execute(setStateRequest);
            }
        }

        //Activate a record
        public static void ActivateRecord(string entityName, Guid recordId, IOrganizationService organizationService)
        {
            var cols = new ColumnSet(new[] { "statecode", "statuscode" });

            //Check if it is Inactive or not
            var entity = organizationService.Retrieve(entityName, recordId, cols);

            if (entity != null && entity.GetAttributeValue<OptionSetValue>("statecode").Value == 1)
            {
                //StateCode = 0 and StatusCode = 1 for activating Account or Contact
                SetStateRequest setStateRequest = new SetStateRequest()
                {
                    EntityMoniker = new EntityReference
                    {
                        Id = recordId,
                        LogicalName = entityName,
                    },
                    State = new OptionSetValue(0),
                    Status = new OptionSetValue(1)
                };
                organizationService.Execute(setStateRequest);          
            }
        }
        #endregion

        public static void CreateAndThrowError(String _errMess, ITracingService _tracingService)
        {
            OrganizationServiceFault osf = new OrganizationServiceFault();
            osf.ErrorCode = -2147220891;
            osf.Message = _errMess;
            FaultException<OrganizationServiceFault> e = new FaultException<OrganizationServiceFault>(osf);
            _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
            throw (e);
        }
        #endregion

        #region Entity Specific Methods
        public static Entity GetOpportunity(Guid _opportunityGUID, IOrganizationService _service, ITracingService _tracingService)
        {
            try
            {
                ColumnSet cs1 = new ColumnSet();
                cs1.Columns.Add("name");
                cs1.Columns.Add("customerid");
                Guid cid = _opportunityGUID;

                Entity currentOpportunity = _service.Retrieve("opportunity", cid, cs1);
                return currentOpportunity;
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                throw;
            }
        }

        public static Entity GetAccount(Guid _accountGUID, IOrganizationService _service, ITracingService _tracingService)
        {
            try
            {
                ColumnSet cs1 = new ColumnSet();
                cs1.Columns.Add("name");
                cs1.Columns.Add("accountnumber");
                Guid cid = _accountGUID;

                Entity currentAccount = _service.Retrieve("account", cid, cs1);
                return currentAccount;
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                throw;
            }
        }
                
        public static Entity GetCampaign(Guid _campaignGUID, IOrganizationService _service, ITracingService _tracingService)
        {
            try
            {
                ColumnSet cs1 = new ColumnSet();
                cs1.Columns.Add("name");
                cs1.Columns.Add("typecode");
                cs1.Columns.Add("transactioncurrencyid");
                Guid cid = _campaignGUID;

                Entity parentCampaign = _service.Retrieve("campaign", cid, cs1);
                return parentCampaign;
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                throw;
            }
        }

        public static Entity GetMarketingList(Guid _listGUID, IOrganizationService _service, ITracingService _tracingService)
        {
            try
            {
                ColumnSet cs1 = new ColumnSet();
                cs1.Columns.Add("listname");
                cs1.Columns.Add("membertype");
                cs1.Columns.Add("type");
                Guid cid = _listGUID;

                Entity parentList = _service.Retrieve("list", cid, cs1);
                return parentList;
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                throw;
            }
        }

        public static EntityCollection GetMarketingListIDsForCampaign(Guid _campaignGUID, IOrganizationService _service, ITracingService _tracingService)
        {
            try
            {
                var fetchXml =
                @"<fetch mapping='logical' version='1.0'>
	                <entity name='list'>
		                <attribute name='listid' />
                        <attribute name='createdfromcode' />
                        <attribute name='membercount' />
                        <attribute name='membertype' />
                        <attribute name='type' />
                        <attribute name='listname' />
                        <link-entity name='campaignitem' from='entityid' to='listid' visible='false' intersect='true'>
                          <link-entity name='campaign' from='campaignid' to='campaignid' alias='aa'>
                            <filter type='and'>
                              <condition attribute='campaignid' operator='eq' uitype='campaign' value='";
                fetchXml += _campaignGUID;
                fetchXml += @"' />
                            </filter>
			                </link-entity>
		                </link-entity>
	                </entity>
                </fetch>";

                // Run the query with the FetchXML.
                var fetchExpression = new FetchExpression(fetchXml);
                EntityCollection fetchResult =
                    _service.RetrieveMultiple(fetchExpression);
                return fetchResult;
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                throw;
            }
        }

        public static EntityCollection GetItemsForMarketingListID(Guid _listGUID, string _listType, IOrganizationService _service, ITracingService _tracingService)
        {
            try
            {
                string fetchXml;
                switch (_listType)
                {
                    case "1":
                        #region Account = 1
                        fetchXml =
                        @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
                          <entity name='account'>
                            <attribute name='name' />
                            <attribute name='accountid' />
                            <order attribute='name' descending='false' />
                            <link-entity name='listmember' from='entityid' to='accountid' visible='false' intersect='true'>
                              <link-entity name='list' from='listid' to='listid' alias='aa'>
                                <filter type='and'>
                                  <condition attribute='listid' operator='eq' uitype='list' value='";
                        fetchXml += _listGUID;
                        fetchXml += @"' />
                                    </filter>
			                        </link-entity>
		                        </link-entity>
	                        </entity>
                        </fetch>";
                        #endregion
                        break;
                    case "2":
                        #region Contact = 2
                        fetchXml =
                        @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
                          <entity name='contact'>
                            <attribute name='fullname' />
                            <attribute name='contactid' />
                            <order attribute='fullname' descending='false' />
                            <link-entity name='listmember' from='entityid' to='contactid' visible='false' intersect='true'>
                              <link-entity name='list' from='listid' to='listid' alias='aa'>
                                <filter type='and'>
                                  <condition attribute='listid' operator='eq uitype='list' value='";
                        fetchXml += _listGUID;
                        fetchXml += @"' />
                                    </filter>
			                        </link-entity>
		                        </link-entity>
	                        </entity>
                        </fetch>";
                        #endregion
                        break;
                    case "4":
                        #region Lead = 4
                        fetchXml =
                        @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
                          <entity name='lead'>
                            <attribute name='fullname' />
                            <attribute name='companyname' />
                            <attribute name='telephone1' />
                            <attribute name='leadid' />
                            <order attribute='fullname' descending='false' />
                            <link-entity name='listmember' from='entityid' to='leadid' visible='false' intersect='true'>
                                <link-entity name='list' from='listid' to='listid' alias='aa'>
                                <filter type='and'>
                                    <condition attribute='listid' operator='eq' uitype='list' value='";
                        fetchXml += _listGUID;
                        fetchXml += @"' />
                                    </filter>
			                        </link-entity>
		                        </link-entity>
	                        </entity>
                        </fetch>";
                        #endregion
                        break;
                    default:
                        fetchXml = string.Empty;
                        break;
                }

                // Run the query with the FetchXML.
                var fetchExpression = new FetchExpression(fetchXml);
                EntityCollection fetchResult =
                    _service.RetrieveMultiple(fetchExpression);
                return fetchResult;
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                throw;
            }
        }

        public static Guid GetGuidofCurrency(IOrganizationService _service, ITracingService _tracingService, out string outMessageSub)
        {
            Guid CurrencyGuid = new Guid();
            outMessageSub = string.Empty;
            QueryExpression queryCurrency = new QueryExpression("currency")
            {
                EntityName = "transactioncurrency",
                ColumnSet = new ColumnSet(new string[] { "transactioncurrencyid" }),
                Criteria = new FilterExpression()
            };

            try
            {
                DataCollection<Entity> entityData = _service.RetrieveMultiple(queryCurrency).Entities;
                int count = entityData.Count;

                if (count > 0)
                {
                    CurrencyGuid = (Guid)entityData[count - 1].Id;

                }
            }
            catch (Exception e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                outMessageSub = string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString());
            }


            return CurrencyGuid;
        }

        // TODO: combine these three calls into a generic "get entities by criteria" call
        public static EntityCollection GetUsersByEmail(string _inEmail, IOrganizationService _service, ITracingService _tracingService)
        {
            try
            {
                var fetchXml = @"<fetch mapping='logical' version='1.0'>
	                <entity name='systemuser'>
                        <attribute name='businessunitid' />
                        <attribute name='systemuserid' />
                        <attribute name='lastname' />
                        <attribute name='firstname' />
                        <attribute name='isdisabled' />
                        <attribute name='bah_aadisabled' />
                        <order attribute='createdon' descending='true' />
                        <filter type='and'>
                            <condition attribute='domainname' operator='eq' value='";
                fetchXml += _inEmail;
                fetchXml += @"' />
                            </filter>
	                </entity>
                </fetch>";

                // Run the query with the FetchXML.
                var fetchExpression = new FetchExpression(fetchXml);
                EntityCollection fetchResult =
                    _service.RetrieveMultiple(fetchExpression);
                return fetchResult;
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                throw;
            }
        }

        public static EntityCollection GetRolesByNameUnit(string _inName, Guid _inBU, IOrganizationService _service, ITracingService _tracingService)
        {
            try
            {
                var fetchXml = @"<fetch mapping='logical' version='1.0'>
	                  <entity name='role'>
                        <attribute name='name' />
                        <attribute name='roleid' />
                        <order attribute='name' descending='false' />
                        <filter type='and'>
                          <condition attribute='name' operator='eq' value='";
                fetchXml += _inName;
                fetchXml += @"' />
                          <condition attribute='businessunitid' operator='eq' value='";
                fetchXml += _inBU.ToString();
                fetchXml += @"' />
                            </filter>
	                </entity>
                </fetch>";

                // Run the query with the FetchXML.
                var fetchExpression = new FetchExpression(fetchXml);
                EntityCollection fetchResult =
                    _service.RetrieveMultiple(fetchExpression);
                return fetchResult;
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                throw;
            }
        }
        
        public static EntityCollection GetTeamsByName(string _inName, IOrganizationService _service, ITracingService _tracingService)
        {
            try
            {
                var fetchXml = @"<fetch mapping='logical' version='1.0'>	                  
                    <entity name='team'>
                        <attribute name='name' />
                        <attribute name='teamid' />
                        <attribute name='teamtype' />
                        <order attribute='name' descending='false' />
                        <filter type='and'>
                          <condition attribute='name' operator='eq' value='";
                fetchXml += _inName;
                fetchXml += @"' />
                            </filter>
	                </entity>
                </fetch>";

                // Run the query with the FetchXML.
                var fetchExpression = new FetchExpression(fetchXml);
                EntityCollection fetchResult =
                    _service.RetrieveMultiple(fetchExpression);
                return fetchResult;
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                throw;
            }
        }

        public static bool IsRoleRequiredByUser(string _inName, Guid _inUser, IOrganizationService _service, ITracingService _tracingService)
        {
            try
            {
                bool isRequired = false;

                // Get any related user provision records
                var fetchXml = @"<fetch mapping='logical' version='1.0'>
                    <entity name='vhacrm_userprovisionrole'>
                        <attribute name='vhacrm_userprovisionroleid' />
                        <attribute name='vhacrm_name' />
                        <attribute name='vhacrm_roles_text' />
                        <order attribute='vhacrm_name' descending='false' />
                        <link-entity name='vhacrm_userrole' from='vhacrm_userprovisionroleid' to='vhacrm_userprovisionroleid' alias='ad'>
                          <filter type='and'>
                            <condition attribute='statecode' operator='eq' value='0' />
                            <condition attribute='vhacrm_systemuserid' operator='eq' uitype='systemuser' value='";
                fetchXml += _inUser;
                fetchXml += @"' />
                          </filter>
                        </link-entity>
	                    </entity>
                    </fetch>";

                // Run the query with the FetchXML.
                var fetchExpression = new FetchExpression(fetchXml);
                EntityCollection fetchResult =
                    _service.RetrieveMultiple(fetchExpression);

                // If a record was found, loop and parse any and all rolls
                if (fetchResult != null)
                {
                    for (int i = 0; i < fetchResult.Entities.Count; i++)
                    {
                        if (fetchResult.Entities[i].Attributes.Contains("vhacrm_roles_text"))
                        {
                            string[] parsedRoles = fetchResult.Entities[i].Attributes["vhacrm_roles_text"].ToString().Split(',');
                            for (int j = 0; j < parsedRoles.Length; j++)
                            {
                                if (_inName == parsedRoles[j]) isRequired = true;
                            }
                        }
                    }
                }
                return isRequired;
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                throw;
            }
        }

        public static bool IsTeamRequiredByUser(string _inName, Guid _inUser, IOrganizationService _service, ITracingService _tracingService)
        {
            try
            {
                bool isRequired = false;

                // Get any related user provision records
                var fetchXml = @"<fetch mapping='logical' version='1.0'>
                    <entity name='vhacrm_userprovisionrole'>
                        <attribute name='vhacrm_userprovisionroleid' />
                        <attribute name='vhacrm_name' />
                        <attribute name='vhacrm_teams_text' />
                        <order attribute='vhacrm_name' descending='false' />
                        <link-entity name='vhacrm_userrole' from='vhacrm_userprovisionroleid' to='vhacrm_userprovisionroleid' alias='ad'>
                          <filter type='and'>
                            <condition attribute='statecode' operator='eq' value='0' />
                            <condition attribute='vhacrm_systemuserid' operator='eq' uitype='systemuser' value='";
                fetchXml += _inUser;
                fetchXml += @"' />
                          </filter>
                        </link-entity>
	                    </entity>
                    </fetch>";

                // Run the query with the FetchXML.
                var fetchExpression = new FetchExpression(fetchXml);
                EntityCollection fetchResult =
                    _service.RetrieveMultiple(fetchExpression);

                // If a record was found, loop and parse any and all rolls
                if (fetchResult != null)
                {
                    for (int i = 0; i < fetchResult.Entities.Count; i++)
                    {
                        if (fetchResult.Entities[i].Attributes.Contains("vhacrm_teams_text"))
                        {
                            string[] parsedTeams = fetchResult.Entities[i].Attributes["vhacrm_teams_text"].ToString().Split(',');
                            for (int j = 0; j < parsedTeams.Length; j++)
                            {
                                if (_inName == parsedTeams[j]) isRequired = true;
                            }
                        }
                    }
                }
                return isRequired;
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                throw;
            }
        }

        public static EntityCollection GetUserRoles(Guid _inUser, Guid _inRole, IOrganizationService _service, ITracingService _tracingService)
        {
            try
            {
                // Get any related user provision records
                var fetchXml = @"<fetch mapping='logical' version='1.0'>
                        <entity name='vhacrm_userrole'>
                            <attribute name='vhacrm_userroleid' />
                            <attribute name='vhacrm_name' />
                            <attribute name='createdon' />
                            <order attribute='vhacrm_name' descending='false' />
                            <filter type='and'>
                                <condition attribute='statecode' operator='eq' value='0' />
                                <condition attribute='vhacrm_systemuserid' operator='eq' uitype='systemuser' value='";
                fetchXml += _inUser;
                fetchXml += @"' />
                                <condition attribute='vhacrm_userprovisionroleid' operator='eq' uitype='vhacrm_userprovisionrole' value='";
                fetchXml += _inRole;
                fetchXml += @"' />                          
                            </filter>
	                    </entity>
                    </fetch>";
                
                // Run the query with the FetchXML.
                var fetchExpression = new FetchExpression(fetchXml);
                EntityCollection fetchResult =
                    _service.RetrieveMultiple(fetchExpression);
                                
                return fetchResult;
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                _tracingService.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
                throw;
            }
        }
        #endregion
    }
}
