/// <summary>
        /// Converts all representations of the state property to an integer.
        /// </summary>
        /// <param name="stateName">The state to get the integer value of as a <c>string</c>.</param>
        /// <param name="entityName">The name of the entity type to get the state code for.</param>
        /// <param name="adapter">The <see cref="DynamicCrmAdapter"/> to use for calling into a CRM for resolving that state.</param>
        /// <returns>An <c>int</c> the represents the state.</returns>
        public static int ConvertStateNameToValue(string stateName, string entityName, DynamicCrmAdapter adapter)
        {
            if (adapter == null)
            {
                throw new ArgumentNullException("adapter");
            }

            RetrieveAttributeRequest attribReq = new RetrieveAttributeRequest()
            {
                EntityLogicalName = entityName, LogicalName = "statecode", RetrieveAsIfPublished = true
            };

            // Get the attribute metadata for the state attribute.
            RetrieveAttributeResponse metadataResponse = (RetrieveAttributeResponse)adapter.OrganizationService.Execute(attribReq);
            StateAttributeMetadata    picklistAttrib   = (StateAttributeMetadata)metadataResponse.AttributeMetadata;

            var picklistValue = from option in picklistAttrib.OptionSet.Options
                                where option.Label.UserLocalizedLabel.Label.ToUpperInvariant() == stateName.ToUpperInvariant()
                                select option.Value;

            // Ensure that both the returned list and the first item in the returned list are not null or empty.
            if ((picklistValue.Count() > 0) && (picklistValue.First() != null))
            {
                return(picklistValue.First().Value);
            }

            return(CRM2011AdapterUtilities.GetDefaultStateCodeValue(stateName));
        }
        /// <summary>
        /// Gets a <c>Picklist</c> instance who's values are set based on the parameters provided.
        /// </summary>
        /// <param name="entity">The current <c>Entity</c>.</param>
        /// <param name="field">The current <c>DefinitionField</c> for the property being mapped to this <c>Picklist</c>.</param>
        /// <param name="mappedLookupObject">The <c>Dictionary</c> containing the lookup information for the <c>Picklist</c>.</param>
        /// <param name="crm2011Adapter">The <c>CRM2011Adapter</c> to use when calling the CRM web service.</param>
        /// <param name="providedEntityName">The name of the <c>Entity</c> that the current object provider is for.</param>
        /// <returns>A <c>Picklist</c> with it's value property set to the one requested in the <c>Dictionary</c>, if one is found and <c>null</c> otherwise.</returns>
        /// <exception cref="ArgumentException">Thrown if the requested value is not currently in the <c>Picklist</c> within the CRM system.</exception>
        public static OptionSetValue MapPicklist(Entity entity, FieldDefinition field, Dictionary <string, object> mappedLookupObject, DynamicCrmAdapter crm2011Adapter, string providedEntityName)
        {
            if (entity == null || field == null || crm2011Adapter == null)
            {
                throw new AdapterException(string.Format(CultureInfo.CurrentCulture, Resources.ArgumentNullExceptionMessage))
                      {
                          ExceptionId = AdapterException.SystemExceptionGuid
                      };
            }

            ValidateDictionary(mappedLookupObject);

            if (!mappedLookupObject.Keys.Contains("Value"))
            {
                if (!mappedLookupObject.Keys.Contains("name") || string.IsNullOrEmpty(mappedLookupObject["name"] as string))
                {
                    return(null);
                }

                RetrieveAttributeRequest attribReq = new RetrieveAttributeRequest()
                {
                    EntityLogicalName = entity.LogicalName, LogicalName = field.Name, RetrieveAsIfPublished = true
                };
                if (IsSpecialAddressPicklist(entity, field))
                {
                    attribReq.EntityLogicalName = providedEntityName;
                    attribReq.LogicalName       = string.Format(CultureInfo.CurrentCulture, "address{0}_{1}", ((int?)entity["addressnumber"]).Value.ToString(CultureInfo.CurrentCulture), field.Name);
                }

                // Get the attribute metadata for the state attribute.
                RetrieveAttributeResponse metadataResponse = (RetrieveAttributeResponse)crm2011Adapter.OrganizationService.Execute(attribReq);
                PicklistAttributeMetadata picklistAttrib   = (PicklistAttributeMetadata)metadataResponse.AttributeMetadata;

                var picklistValue = from option in picklistAttrib.OptionSet.Options
                                    where option.Label.UserLocalizedLabel.Label.ToUpperInvariant() == mappedLookupObject["name"].ToString().ToUpperInvariant()
                                    select option.Value;

                // ensure that both the returned list and the first item in the returned list are not null or empty.
                if ((picklistValue.Count() > 0) && (picklistValue.First() != null))
                {
                    return(new OptionSetValue(picklistValue.First().Value));
                }

                throw new AdapterException(string.Format(CultureInfo.CurrentCulture, Resources.PicklistValueNotFound, mappedLookupObject["name"].ToString(), field.DisplayName, entity.LogicalName))
                      {
                          ExceptionId = ErrorCodes.PicklistMappingNotFound
                      };
            }

            OptionSetValue mapping = new OptionSetValue();

            SetRelationshipValuesFromDictionary(mappedLookupObject, mapping);
            return(mapping);
        }
        /// <summary>
        /// Gets an instance of the <c>customeraddress</c> class.
        /// </summary>
        /// <param name="addressIntegrationKeyValue">The value of the address's dynamics_integrationkey property to query for.</param>
        /// <param name="parentKey">The parent of this address to use when querying for the existence of this address instance.</param>
        /// <param name="adapter">An instance of the <c>CRM2011Adapter</c> class to use when calling CRM.</param>
        /// <param name="addressIntegrationKeyProperty">The key attribute on the <c>customeraddress</c> that the supplied value is for.</param>
        /// <returns>A new instance with it's dynamics_integrationkey initialized to the value supplied or an existing instance.</returns>
        public static Entity GetDynamicAddressInstance(string addressIntegrationKeyValue, Guid parentKey, DynamicCrmAdapter adapter, string addressIntegrationKeyProperty)
        {
            if (parentKey == null || adapter == null)
            {
                throw new AdapterException(string.Format(CultureInfo.CurrentCulture, Resources.ArgumentNullExceptionMessage))
                      {
                          ExceptionId = AdapterException.SystemExceptionGuid
                      };
            }

            if (string.IsNullOrEmpty(addressIntegrationKeyProperty))
            {
                throw new AdapterException(string.Format(CultureInfo.CurrentCulture, Resources.AddressIntegrationKeyPropertyInvalidMessage))
                      {
                          ExceptionId = ErrorCodes.AddressIntegrationKeyPropertyException
                      };
            }

            RetrieveMultipleRequest retrieveRequest = new RetrieveMultipleRequest();

            KeyValuePair <string, string>[] propertyValues = new KeyValuePair <string, string> [2];
            propertyValues[0]     = new KeyValuePair <string, string>(addressIntegrationKeyProperty, addressIntegrationKeyValue);
            propertyValues[1]     = new KeyValuePair <string, string>("parentid", parentKey.ToString());
            retrieveRequest.Query = CRM2011AdapterUtilities.GetMultipartQueryExpression(LogicalOperator.And, "customeraddress", propertyValues);
            RetrieveMultipleResponse retrieveResponse = (RetrieveMultipleResponse)adapter.OrganizationService.Execute(retrieveRequest);
            Entity returnedEntity = null;

            if (retrieveResponse.EntityCollection.Entities.Count == 1)
            {
                returnedEntity = retrieveResponse.EntityCollection.Entities[0] as Entity;
                returnedEntity[CRM2011AdapterUtilities.IsNew] = false;
                return(returnedEntity);
            }
            else if (retrieveResponse.EntityCollection.Entities.Count < 1)
            {
                // this is a new entity instance and we need to map the provided data onto the DynamicsEntity
                returnedEntity = new Entity()
                {
                    LogicalName = "customeraddress"
                };
                if (addressIntegrationKeyProperty.Equals("customeraddressid", StringComparison.OrdinalIgnoreCase))
                {
                    returnedEntity[addressIntegrationKeyProperty] = new Guid(addressIntegrationKeyValue);
                }
                else
                {
                    returnedEntity[addressIntegrationKeyProperty] = addressIntegrationKeyValue;
                }

                returnedEntity[CRM2011AdapterUtilities.IsNew] = true;
                return(returnedEntity);
            }
            else
            {
                throw new AdapterException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              Resources.MultipleDynamicEntitiesReturnedExceptionMessage,
                              "customeraddress",
                              addressIntegrationKeyProperty,
                              addressIntegrationKeyValue))
                      {
                          ExceptionId = ErrorCodes.MultipleCustomerAddressResult
                      };
            }
        }
        /// <summary>
        /// Gets a <c>QueryExpression</c> instance with it's properties set to the values supplied
        /// </summary>
        /// <param name="entityName">The name of the <c>BusinessEntity</c> as a <c>string</c> to be queried</param>
        /// <param name="modifiedDate">The <c>string</c> value for the date to be queried from</param>
        /// <param name="adapter">An instance of a <c>CRM2011Adapter</c> used to retrieve the INTEGRATION user's <c>Guid</c></param>
        /// <param name="isDynamic">True if the object provider calling into this method is a <c>DynamicObbjectProvider</c> and false otherwise</param>
        /// <param name="columnSet">A CRM <c>ColumnSet</c> that contains the columns to be returned from the query.</param>
        /// <returns>An instance of a <c>QueryExpression</c> that can used as a parameter to a <c>RetrieveMultipleRequest</c></returns>
        /// <remarks>The method generates a query that is retrieved by the modified date supplied as well as the IntegrationReady flag and the modified by
        /// property not being equal to the INTEGRATION user's id</remarks>
        public static QueryExpression GetReaderQueryExpression(string entityName, DateTime modifiedDate, DynamicCrmAdapter adapter, bool isDynamic, ColumnSet columnSet)
        {
            if (adapter == null)
            {
                throw new AdapterException(string.Format(CultureInfo.CurrentCulture, Resources.ArgumentNullExceptionMessage), new ArgumentNullException("adapter"))
                      {
                          ExceptionId = AdapterException.SystemExceptionGuid
                      };
            }

            ValidatePropertyQueryParameters(entityName, "modifiedon");
            QueryExpression queryHelper = new QueryExpression(entityName)
            {
                Distinct = false, Criteria = new FilterExpression(), ColumnSet = columnSet
            };

            queryHelper.ColumnSet.AllColumns = true;

            if (entityName != null)
            {
                if (entityName == "activitymimeattachment")
                {
                    LinkEntity emailLink = new LinkEntity()
                    {
                        LinkFromEntityName    = "activitymimeattachment",
                        LinkFromAttributeName = "activityid",
                        LinkToEntityName      = "email",
                        LinkToAttributeName   = "activityid",
                        LinkCriteria          =
                        {
                            Conditions =
                            {
                                new ConditionExpression(
                                    "modifiedon", ConditionOperator.GreaterEqual, modifiedDate)
                            }
                        }
                    };

                    queryHelper.LinkEntities.Add(emailLink);
                }
                else
                {
                    queryHelper.Criteria.Conditions.Add(new ConditionExpression("modifiedon", ConditionOperator.GreaterEqual, modifiedDate));
                }
            }

            if (!isDynamic)
            {
                queryHelper.Criteria.Conditions.Add(new ConditionExpression(CRM2011AdapterUtilities.DynamicsIntegrationReady, ConditionOperator.Equal, true));
            }

            return(queryHelper);
        }