private void PopulateResults(SearchAttributeDetails matchingData)
        {
            if (!matchingData.FailedRecords.Any())
            {
                // We haven't already calculated the results, so let's do that now.
                foreach (var failedRecord in matchingData.FailedRecords)
                {
                    var id     = failedRecord.Id;
                    var entity = Service.Retrieve(entitySelection.SelectedEntity.LogicalName, id, new ColumnSet(matchingData.LogicalName, entitySelection.SelectedEntity.PrimaryNameAttribute));
                    var result = new FailedRecord()
                    {
                        Id            = id,
                        FailureReason = "Invalid data",
                        FailedValue   = entity.GetAttributeValue <string>(matchingData.LogicalName)
                    };

                    if (entity[matchingData.LogicalName] is OptionSetValue)
                    {
                        result.FailedValue = entity.GetAttributeValue <OptionSetValue>(matchingData.LogicalName).Value.ToString();
                    }

                    matchingData.FailedRecords.Add(result);
                }
            }

            resultsView.ColumnHeadersVisible = false;
            resultsView.DataSource           = new BindingList <FailedRecord>(matchingData.FailedRecords);
            resultsView.ColumnHeadersVisible = true;

            for (var i = 0; i < resultsView.ColumnCount; i++)
            {
                resultsView.Columns[i].Width = 150;
            }
        }
        private void entitySelection_SelectedItemChanged(object sender, EventArgs e)
        {
            if (entitySelection.SelectedEntity == null)
            {
                return;
            }

            var retrieveEntityReq = new RetrieveEntityRequest()
            {
                EntityFilters = EntityFilters.Attributes,
                LogicalName   = entitySelection.SelectedEntity.LogicalName
            };

            _searchingDetails = new List <SearchAttributeDetails>();

            var entityMetadata = (RetrieveEntityResponse)Service.Execute(retrieveEntityReq);
            var stringAttrs    = entityMetadata.EntityMetadata.Attributes.Where(a =>
                                                                                a.AttributeType == AttributeTypeCode.String && string.IsNullOrEmpty(a.AttributeOf))
                                 .Select(t => (StringAttributeMetadata)t).ToList();

            var memoAttrs = entityMetadata.EntityMetadata.Attributes.Where(a =>
                                                                           a.AttributeType == AttributeTypeCode.Memo && string.IsNullOrEmpty(a.AttributeOf))
                            .Select(t => (MemoAttributeMetadata)t).ToList();

            var doubleAttr = entityMetadata.EntityMetadata.Attributes.Where(a =>
                                                                            a.AttributeType == AttributeTypeCode.Double && string.IsNullOrEmpty(a.AttributeOf))
                             .Select(t => (DoubleAttributeMetadata)t).ToList();

            var intAttr = entityMetadata.EntityMetadata.Attributes.Where(a =>
                                                                         a.AttributeType == AttributeTypeCode.Integer && string.IsNullOrEmpty(a.AttributeOf))
                          .Select(t => (IntegerAttributeMetadata)t).ToList();

            var decimalAttr = entityMetadata.EntityMetadata.Attributes.Where(a =>
                                                                             a.AttributeType == AttributeTypeCode.Decimal && string.IsNullOrEmpty(a.AttributeOf))
                              .Select(t => (DecimalAttributeMetadata)t).ToList();

            var bigIntAttr = entityMetadata.EntityMetadata.Attributes.Where(a =>
                                                                            a.AttributeType == AttributeTypeCode.BigInt && string.IsNullOrEmpty(a.AttributeOf))
                             .Select(t => (BigIntAttributeMetadata)t).ToList();

            var picklistAttr = entityMetadata.EntityMetadata.Attributes.Where(a =>
                                                                              a.AttributeType == AttributeTypeCode.Picklist && string.IsNullOrEmpty(a.AttributeOf))
                               .Select(t => (PicklistAttributeMetadata)t).ToList();

            var stateAttr = entityMetadata.EntityMetadata.Attributes.Where(a =>
                                                                           a.AttributeType == AttributeTypeCode.State && string.IsNullOrEmpty(a.AttributeOf))
                            .Select(t => (StateAttributeMetadata)t).ToList();

            var statusAttr = entityMetadata.EntityMetadata.Attributes.Where(a =>
                                                                            a.AttributeType == AttributeTypeCode.Status && string.IsNullOrEmpty(a.AttributeOf))
                             .Select(t => (StatusAttributeMetadata)t).ToList();

            _searchingDetails.AddRange(stringAttrs.Select(t => new SearchAttributeDetails()
            {
                LogicalName   = t.LogicalName,
                DisplayName   = t.DisplayName.UserLocalizedLabel?.Label ?? t.LogicalName,
                AttrType      = SearchAttributeDetails.AttributeType.String,
                MaxLength     = t.MaxLength,
                Format        = t.FormatName.Value,
                RequiredLevel = t.RequiredLevel.Value
            }));

            _searchingDetails.AddRange(memoAttrs.Select(t => new SearchAttributeDetails()
            {
                LogicalName   = t.LogicalName,
                DisplayName   = t.DisplayName.UserLocalizedLabel?.Label ?? t.LogicalName,
                AttrType      = SearchAttributeDetails.AttributeType.String,
                MaxLength     = t.MaxLength,
                RequiredLevel = t.RequiredLevel.Value
            }));

            _searchingDetails.AddRange(doubleAttr.Select(t => new SearchAttributeDetails()
            {
                LogicalName    = t.LogicalName,
                DisplayName    = t.DisplayName.UserLocalizedLabel?.Label ?? t.LogicalName,
                AttrType       = SearchAttributeDetails.AttributeType.Double,
                DoubleMinValue = t.MinValue,
                DoubleMaxValue = t.MaxValue,
                RequiredLevel  = t.RequiredLevel.Value
            }));

            _searchingDetails.AddRange(decimalAttr.Select(t => new SearchAttributeDetails()
            {
                LogicalName     = t.LogicalName,
                DisplayName     = t.DisplayName.UserLocalizedLabel?.Label ?? t.LogicalName,
                AttrType        = SearchAttributeDetails.AttributeType.Decimal,
                DecimalMinValue = t.MinValue,
                DecimalMaxValue = t.MaxValue,
                RequiredLevel   = t.RequiredLevel.Value
            }));

            _searchingDetails.AddRange(intAttr.Select(t => new SearchAttributeDetails()
            {
                LogicalName   = t.LogicalName,
                DisplayName   = t.DisplayName.UserLocalizedLabel?.Label ?? t.LogicalName,
                AttrType      = SearchAttributeDetails.AttributeType.Int,
                IntMinValue   = t.MinValue,
                IntMaxValue   = t.MaxValue,
                RequiredLevel = t.RequiredLevel.Value
            }));

            _searchingDetails.AddRange(bigIntAttr.Select(t => new SearchAttributeDetails()
            {
                LogicalName    = t.LogicalName,
                DisplayName    = t.DisplayName.UserLocalizedLabel?.Label ?? t.LogicalName,
                AttrType       = SearchAttributeDetails.AttributeType.BigInt,
                BigIntMinValue = t.MinValue,
                BigIntMaxValue = t.MaxValue,
                RequiredLevel  = t.RequiredLevel.Value
            }));

            _searchingDetails.AddRange(picklistAttr.Select(t => new SearchAttributeDetails()
            {
                LogicalName     = t.LogicalName,
                DisplayName     = t.DisplayName.UserLocalizedLabel?.Label ?? t.LogicalName,
                AttrType        = SearchAttributeDetails.AttributeType.Picklist,
                AllowableValues = t.OptionSet.Options.Where(o => o.Value.HasValue).Select(o => o.Value.Value).ToArray(),
                RequiredLevel   = t.RequiredLevel.Value
            }));

            _searchingDetails.AddRange(stateAttr.Select(t => new SearchAttributeDetails()
            {
                LogicalName     = t.LogicalName,
                DisplayName     = t.DisplayName.UserLocalizedLabel?.Label ?? t.LogicalName,
                AttrType        = SearchAttributeDetails.AttributeType.State,
                AllowableValues = t.OptionSet.Options.Where(o => o.Value.HasValue).Select(o => o.Value.Value).ToArray(),
                RequiredLevel   = t.RequiredLevel.Value
            }));

            foreach (var status in statusAttr)
            {
                var detail = new SearchAttributeDetails()
                {
                    LogicalName = status.LogicalName,
                    DisplayName = status.DisplayName.UserLocalizedLabel?.Label ?? status.LogicalName,
                    AttrType    = SearchAttributeDetails.AttributeType.Status,
                };

                foreach (StatusOptionMetadata option in status.OptionSet.Options)
                {
                    detail.StatusLookups.Add(new StatusCodeLookup()
                    {
                        StateCode  = option.State.Value,
                        StatusCode = option.Value.Value
                    });
                }

                _searchingDetails.Add(detail);
            }

            _searchingDetails = _searchingDetails.OrderBy(a => a.LogicalName).ToList();

            var bindedAttrs = new BindingList <SearchAttributeDetails>(_searchingDetails);

            metadataView.DataSource = bindedAttrs;

            for (int i = 1; i < metadataView.ColumnCount; i++)
            {
                metadataView.Columns[i].ReadOnly = true;
            }

            metadataView.Columns[4].Width = 275;
            previewGroup.Visible          = true;
        }