public override void DeployModel(object modelHost, DefinitionBase model)
        {
            base.DeployModel(modelHost, model);

            var listItemModelHost = modelHost.WithAssertAndCast<ListItemModelHost>("modelHost", value => value.RequireNotNull());
            var typedDefinition = model.WithAssertAndCast<ContentByQueryWebPartDefinition>("model", value => value.RequireNotNull());

            var pageItem = listItemModelHost.HostListItem;

            WithExistingWebPart(listItemModelHost.HostFile, typedDefinition, spObject =>
            {
                var assert = ServiceFactory.AssertService
                                           .NewAssert(model, typedDefinition, spObject)
                                                 .ShouldNotBeNull(spObject);

                if (!string.IsNullOrEmpty(typedDefinition.ContentTypeBeginsWithId))
                    throw new NotImplementedException();
                else
                    assert.SkipProperty(m => m.ContentTypeBeginsWithId, "ContentTypeBeginsWithId is null or empty, skipping.");

                // mappings
                if (!string.IsNullOrEmpty(typedDefinition.DataMappings))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.DataMappings);
                        var isValid = false;

                        isValid = s.DataMappings == CurrentWebPartXml.GetProperty("DataMappings");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.DataMappings, "DataMappings is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.DataMappingViewFields))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.DataMappingViewFields);
                        var isValid = false;

                        isValid = s.DataMappingViewFields == CurrentWebPartXml.GetProperty("DataMappingViewFields");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.DataMappingViewFields, "DataMappingViewFields is null or empty, skipping.");

                // filter display values

                if (!string.IsNullOrEmpty(typedDefinition.FilterDisplayValue1))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.FilterDisplayValue1);
                        var isValid = false;

                        isValid = s.FilterDisplayValue1 == CurrentWebPartXml.GetProperty("FilterDisplayValue1");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.FilterDisplayValue1, "FilterDisplayValue1 is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.FilterDisplayValue2))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.FilterDisplayValue2);
                        var isValid = false;

                        isValid = s.FilterDisplayValue2 == CurrentWebPartXml.GetProperty("FilterDisplayValue2");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.FilterDisplayValue2, "FilterDisplayValue2 is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.FilterDisplayValue3))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.FilterDisplayValue3);
                        var isValid = false;

                        isValid = s.FilterDisplayValue3 == CurrentWebPartXml.GetProperty("FilterDisplayValue3");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.FilterDisplayValue3, "FilterDisplayValue3 is null or empty, skipping.");

                // filter operator

                if (!string.IsNullOrEmpty(typedDefinition.FilterOperator1))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.FilterOperator1);
                        var isValid = false;

                        isValid = s.FilterOperator1 == CurrentWebPartXml.GetProperty("FilterOperator1");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.FilterOperator1, "FilterOperator1 is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.FilterOperator2))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.FilterOperator2);
                        var isValid = false;

                        isValid = s.FilterOperator2 == CurrentWebPartXml.GetProperty("FilterOperator2");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.FilterOperator2, "FilterOperator2 is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.FilterOperator3))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.FilterOperator3);
                        var isValid = false;

                        isValid = s.FilterOperator3 == CurrentWebPartXml.GetProperty("FilterOperator3");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.FilterOperator3, "FilterOperator3 is null or empty, skipping.");

                // filter types

                if (!string.IsNullOrEmpty(typedDefinition.FilterType1))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.FilterType1);
                        var isValid = false;

                        isValid = s.FilterType1 == CurrentWebPartXml.GetProperty("FilterType1");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.FilterType1, "FilterType1 is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.FilterType2))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.FilterType2);
                        var isValid = false;

                        isValid = s.FilterType2 == CurrentWebPartXml.GetProperty("FilterType2");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.FilterType2, "FilterType2 is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.FilterType3))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.FilterType3);
                        var isValid = false;

                        isValid = s.FilterType3 == CurrentWebPartXml.GetProperty("FilterType3");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.FilterType3, "FilterType3 is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.SortBy))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.SortBy);
                        var isValid = false;

                        isValid = s.SortBy == CurrentWebPartXml.GetProperty("SortBy");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.SortBy, "SortBy is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.SortByFieldType))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.SortByFieldType);
                        var isValid = false;

                        isValid = s.SortByFieldType == CurrentWebPartXml.GetProperty("SortByFieldType");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.SortByFieldType, "SortByFieldType is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.SortByDirection))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.SortByDirection);
                        var isValid = false;

                        isValid = s.SortByDirection == CurrentWebPartXml.GetProperty("SortByDirection");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.SortByDirection, "SortByDirection is null or empty, skipping.");

                // filter values

                if (!string.IsNullOrEmpty(typedDefinition.FilterValue1))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.FilterValue1);
                        var isValid = false;

                        isValid = s.FilterValue1 == CurrentWebPartXml.GetProperty("FilterValue1");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.FilterValue1, "FilterValue1 is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.FilterValue2))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.FilterValue2);
                        var isValid = false;

                        isValid = s.FilterValue2 == CurrentWebPartXml.GetProperty("FilterValue2");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.FilterValue2, "FilterValue2 is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.FilterValue3))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.FilterValue3);
                        var isValid = false;

                        isValid = s.FilterValue3 == CurrentWebPartXml.GetProperty("FilterValue3");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.FilterValue3, "FilterValue3 is null or empty, skipping.");

                // styles

                if (!string.IsNullOrEmpty(typedDefinition.GroupStyle))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.GroupStyle);
                        var isValid = false;

                        isValid = s.GroupStyle == CurrentWebPartXml.GetGroupStyle();

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.GroupStyle, "GroupStyle is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.ItemStyle))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.ItemStyle);
                        var isValid = false;

                        isValid = s.ItemStyle == CurrentWebPartXml.GetItemStyle();

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.ItemStyle, "ItemStyle is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.ItemXslLink))
                    throw new NotImplementedException();
                else
                    assert.SkipProperty(m => m.ItemXslLink, "ItemXslLink is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.MainXslLink))
                    throw new NotImplementedException();
                else
                    assert.SkipProperty(m => m.MainXslLink, "MainXslLink is null or empty, skipping.");

                // list bindings

                if (!string.IsNullOrEmpty(typedDefinition.WebUrl))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.WebUrl);
                        var isValid = false;

                        isValid = s.WebUrl == CurrentWebPartXml.GetWebUrl();

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.WebUrl, "WebUrl is null or empty, skipping.");

                if (typedDefinition.WebId.HasValue)
                {
                    throw new NotImplementedException();
                }
                else
                    assert.SkipProperty(m => m.WebId, "WebId is null or empty, skipping.");

                if (typedDefinition.ListGuid.HasGuidValue())
                    throw new NotImplementedException();
                else
                    assert.SkipProperty(m => m.ListGuid, "ListGuid is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.ListName))
                    throw new NotImplementedException();
                else
                    assert.SkipProperty(m => m.ListName, "ListName is null or empty, skipping.");

                if (!string.IsNullOrEmpty(typedDefinition.ListUrl))
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.ListUrl);
                        var isValid = false;

                        // resolve web / url by list URL
                        // check ListId

                        var webLookup = new LookupFieldModelHandler();

                        var targetWeb = webLookup.GetTargetWeb(listItemModelHost.HostSite,
                            typedDefinition.WebUrl,
                            typedDefinition.WebId);

                        var list = targetWeb.QueryAndGetListByUrl(typedDefinition.ListUrl);
                        isValid = CurrentWebPartXml.GetListGuid() == list.Id.ToString("D");

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                    assert.SkipProperty(m => m.ListUrl, "ListUrl is null or empty, skipping.");

                // misc

                if (typedDefinition.ServerTemplate.HasValue)
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.ServerTemplate);
                        var isValid = false;

                        isValid = ConvertUtils.ToInt(CurrentWebPartXml.GetProperty("ServerTemplate"))
                                        == typedDefinition.ServerTemplate;

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                {
                    assert.SkipProperty(m => m.ServerTemplate, "ServerTemplate is null or empty, skipping.");
                }

                if (typedDefinition.ItemLimit.HasValue)
                {
                    assert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.ItemLimit);
                        var isValid = false;

                        isValid = ConvertUtils.ToInt(CurrentWebPartXml.GetProperty("ItemLimit"))
                                        == typedDefinition.ItemLimit;

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                {
                    assert.SkipProperty(m => m.ItemLimit, "ItemLimit is null or empty, skipping.");
                }

                if (typedDefinition.PlayMediaInBrowser.HasValue)
                    throw new NotImplementedException();
                else
                    assert.SkipProperty(m => m.PlayMediaInBrowser, "PlayMediaInBrowser is null or empty, skipping.");

                if (typedDefinition.ShowUntargetedItems.HasValue)
                    throw new NotImplementedException();
                else
                    assert.SkipProperty(m => m.ShowUntargetedItems, "ShowUntargetedItems is null or empty, skipping.");

                if (typedDefinition.UseCopyUtil.HasValue)
                    throw new NotImplementedException();
                else
                    assert.SkipProperty(m => m.UseCopyUtil, "UseCopyUtil is null or empty, skipping.");

            });
        }
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            var definition = model.WithAssertAndCast<FieldDefinition>("model", value => value.RequireNotNull());
            var spObject = GetField(modelHost, definition);

            HostList = ExtractListFromHost(modelHost);
            HostSite = ExtractSiteFromHost(modelHost);

            var assert = ServiceFactory.AssertService.NewAssert(model, definition, spObject);

            ValidateField(assert, spObject, definition);

            var typedField = spObject.Context.CastTo<FieldLookup>(spObject);
            var typedDefinition = model.WithAssertAndCast<LookupFieldDefinition>("model", value => value.RequireNotNull());

            var typedFieldAssert = ServiceFactory.AssertService.NewAssert(model, typedDefinition, typedField);

            typedFieldAssert.ShouldBeEqual(m => m.AllowMultipleValues, o => o.AllowMultipleValues);

            if (typedDefinition.LookupWebId.HasValue)
            {
                typedFieldAssert.ShouldBeEqual(m => m.LookupWebId, o => o.LookupWebId);
            }
            else
            {
                typedFieldAssert.SkipProperty(m => m.LookupWebId, "LookupWebId is NULL. Skipping.");
            }

            if (!string.IsNullOrEmpty(typedDefinition.LookupWebUrl))
            {

            }
            else
            {
                typedFieldAssert.SkipProperty(m => m.LookupWebUrl, "LookupWebUrl is NULL. Skipping.");
            }

            if (!string.IsNullOrEmpty(typedDefinition.RelationshipDeleteBehavior))
            {
                typedFieldAssert.ShouldBeEqual((p, s, d) =>
                {
                    var srcProp = s.GetExpressionValue(m => m.RelationshipDeleteBehavior);
                    var isValid = s.RelationshipDeleteBehavior == d.RelationshipDeleteBehavior.ToString();

                    return new PropertyValidationResult
                    {
                        Tag = p.Tag,
                        Src = srcProp,
                        Dst = null,
                        IsValid = isValid
                    };
                });
            }
            else
            {
                typedFieldAssert.SkipProperty(m => m.RelationshipDeleteBehavior, "RelationshipDeleteBehavior is NULL. Skipping.");
            }

            // web url
            if (!string.IsNullOrEmpty(typedDefinition.LookupWebUrl))
            {
                var lookupFieldModelHandler = new LookupFieldModelHandler();
                var targetWeb = lookupFieldModelHandler.GetTargetWeb(HostSite, typedDefinition);

                typedFieldAssert.ShouldBeEqual((p, s, d) =>
                {
                    var srcProp = s.GetExpressionValue(m => m.LookupWebUrl);

                    var isValid = d.LookupWebId == targetWeb.Id;

                    return new PropertyValidationResult
                    {
                        Tag = p.Tag,
                        Src = srcProp,
                        Dst = null,
                        IsValid = isValid
                    };
                });
            }
            else
            {
                typedFieldAssert.SkipProperty(m => m.LookupWebUrl, "LookupWebUrl is NULL. Skipping.");
            }

            if (!string.IsNullOrEmpty(typedDefinition.LookupListTitle))
            {
                var site = HostSite;
                var context = site.Context;

                var lookupFieldModelHandler = new LookupFieldModelHandler();
                var web = lookupFieldModelHandler.GetTargetWeb(site, typedDefinition);


                context.Load(web);
                context.ExecuteQueryWithTrace();

                var list = web.Lists.GetByTitle(typedDefinition.LookupListTitle);

                context.Load(list);
                context.ExecuteQueryWithTrace();

                typedFieldAssert.ShouldBeEqual((p, s, d) =>
                {
                    var srcProp = s.GetExpressionValue(m => m.LookupListTitle);

                    var isValid = list.Id == new Guid(typedField.LookupList);

                    return new PropertyValidationResult
                    {
                        Tag = p.Tag,
                        Src = srcProp,
                        Dst = null,
                        IsValid = isValid
                    };
                });
            }
            else
            {
                typedFieldAssert.SkipProperty(m => m.LookupListTitle, "LookupListTitle is NULL. Skipping.");
            }

            if (!string.IsNullOrEmpty(typedDefinition.LookupListUrl))
            {
                var site = HostSite;
                var context = site.Context;


                var lookupFieldModelHandler = new LookupFieldModelHandler();
                var web = lookupFieldModelHandler.GetTargetWeb(site, typedDefinition);


                context.Load(web);
                context.ExecuteQueryWithTrace();

                var list = web.QueryAndGetListByUrl(UrlUtility.CombineUrl(web.ServerRelativeUrl, typedDefinition.LookupListUrl));

                context.Load(list);
                context.ExecuteQueryWithTrace();

                typedFieldAssert.ShouldBeEqual((p, s, d) =>
                {
                    var srcProp = s.GetExpressionValue(m => m.LookupListUrl);

                    var isValid = list.Id == new Guid(typedField.LookupList);

                    return new PropertyValidationResult
                    {
                        Tag = p.Tag,
                        Src = srcProp,
                        Dst = null,
                        IsValid = isValid
                    };
                });
            }
            else
            {
                typedFieldAssert.SkipProperty(m => m.LookupListUrl, "LookupListUrl is NULL. Skipping.");
            }

            if (!string.IsNullOrEmpty(typedDefinition.LookupList))
            {
                if (typedDefinition.LookupList.ToUpper() == "USERINFO")
                {
                    typedFieldAssert.ShouldBeEqual((p, s, d) =>
                    {
                        var srcProp = s.GetExpressionValue(m => m.LookupList);

                        var site = HostSite;
                        var context = site.Context;

                        var userInfoList = site.RootWeb.SiteUserInfoList;
                        context.Load(userInfoList);
                        context.ExecuteQueryWithTrace();

                        var isValid = userInfoList.Id == new Guid(typedField.LookupList);

                        return new PropertyValidationResult
                        {
                            Tag = p.Tag,
                            Src = srcProp,
                            Dst = null,
                            IsValid = isValid
                        };
                    });
                }
                else
                {
                    typedFieldAssert.ShouldBeEqual(m => m.LookupList, o => o.LookupList);
                }
            }
            else
            {
                typedFieldAssert.SkipProperty(m => m.LookupList, "LookupList is NULL. Skipping.");
            }

            if (!string.IsNullOrEmpty(typedDefinition.LookupField))
            {
                typedFieldAssert.ShouldBeEqual(m => m.LookupField, o => o.LookupField);
            }
            else
            {
                typedFieldAssert.SkipProperty(m => m.LookupField, "LookupField is NULL. Skipping.");
            }
        }
        protected override string GetWebpartXmlDefinition(ListItemModelHost listItemModelHost, WebPartDefinitionBase webPartModel)
        {
            var typedDefinition = webPartModel.WithAssertAndCast<ContentByQueryWebPartDefinition>("model", value => value.RequireNotNull());
            var wpXml = WebpartXmlExtensions.LoadWebpartXmlDocument(this.ProcessCommonWebpartProperties(BuiltInWebPartTemplates.ContentByQueryWebPart, webPartModel));

            // reset SortBy initially
            // it is set to {8c06beca-0777-48f7-91c7-6da68bc07b69} initially
            //wpXml.SetOrUpdateProperty("SortBy", string.Empty);

            var context = listItemModelHost.HostClientContext;

            // xslt links
            if (!string.IsNullOrEmpty(typedDefinition.MainXslLink))
            {
                var linkValue = typedDefinition.MainXslLink;

                TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Original MainXslLink: [{0}]", linkValue);

                linkValue = TokenReplacementService.ReplaceTokens(new TokenReplacementContext
                {
                    Value = linkValue,
                    Context = listItemModelHost
                }).Value;

                TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Token replaced MainXslLink: [{0}]", linkValue);

                wpXml.SetOrUpdateProperty("MainXslLink", linkValue);
            }

            if (!string.IsNullOrEmpty(typedDefinition.ItemXslLink))
            {
                var linkValue = typedDefinition.ItemXslLink;

                TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Original ItemXslLink: [{0}]", linkValue);

                linkValue = TokenReplacementService.ReplaceTokens(new TokenReplacementContext
                {
                    Value = linkValue,
                    Context = listItemModelHost
                }).Value;

                TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Token replaced ItemXslLink: [{0}]", linkValue);

                wpXml.SetOrUpdateProperty("ItemXslLink", linkValue);
            }

            if (!string.IsNullOrEmpty(typedDefinition.HeaderXslLink))
            {
                var linkValue = typedDefinition.HeaderXslLink;

                TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Original HeaderXslLink: [{0}]", linkValue);

                linkValue = TokenReplacementService.ReplaceTokens(new TokenReplacementContext
                {
                    Value = linkValue,
                    Context = listItemModelHost
                }).Value;

                TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Token replaced HeaderXslLink: [{0}]", linkValue);

                wpXml.SetOrUpdateProperty("HeaderXslLink", linkValue);
            }

            // styles
            if (!string.IsNullOrEmpty(typedDefinition.ItemStyle))
                wpXml.SetItemStyle(typedDefinition.ItemStyle);

            if (!string.IsNullOrEmpty(typedDefinition.GroupStyle))
                wpXml.SetGroupStyle(typedDefinition.GroupStyle);

            // cache settings
            if (typedDefinition.UseCache.HasValue)
                wpXml.SetUseCache(typedDefinition.UseCache.ToString());

            if (typedDefinition.CacheXslStorage.HasValue)
                wpXml.SetOrUpdateProperty("CacheXslStorage", typedDefinition.CacheXslStorage.ToString());

            if (typedDefinition.CacheXslTimeOut.HasValue)
                wpXml.SetOrUpdateProperty("CacheXslTimeOut", typedDefinition.CacheXslTimeOut.ToString());

            // item limit
            if (typedDefinition.ItemLimit.HasValue)
                wpXml.SetOrUpdateProperty("ItemLimit", typedDefinition.ItemLimit.ToString());

            // mappings
            if (!string.IsNullOrEmpty(typedDefinition.DataMappings))
                wpXml.SetOrUpdateProperty("DataMappings", typedDefinition.DataMappings);

            if (!string.IsNullOrEmpty(typedDefinition.DataMappingViewFields))
                wpXml.SetOrUpdateProperty("DataMappingViewFields", typedDefinition.DataMappingViewFields);

            // misc
            if (typedDefinition.ShowUntargetedItems.HasValue)
                wpXml.SetOrUpdateProperty("ShowUntargetedItems", typedDefinition.ShowUntargetedItems.ToString());

            if (typedDefinition.PlayMediaInBrowser.HasValue)
                wpXml.SetOrUpdateProperty("PlayMediaInBrowser", typedDefinition.PlayMediaInBrowser.ToString());

            // FilterTypeXXX
            if (!string.IsNullOrEmpty(typedDefinition.FilterType1))
                wpXml.SetOrUpdateProperty("FilterType1", typedDefinition.FilterType1);

            if (!string.IsNullOrEmpty(typedDefinition.FilterType2))
                wpXml.SetOrUpdateProperty("FilterType2", typedDefinition.FilterType2);

            if (!string.IsNullOrEmpty(typedDefinition.FilterType3))
                wpXml.SetOrUpdateProperty("FilterType3", typedDefinition.FilterType3);

            // FilterFieldXXX
            if (!string.IsNullOrEmpty(typedDefinition.FilterField1))
                wpXml.SetOrUpdateProperty("FilterField1", typedDefinition.FilterField1);

            if (!string.IsNullOrEmpty(typedDefinition.FilterField2))
                wpXml.SetOrUpdateProperty("FilterField2", typedDefinition.FilterField2);

            if (!string.IsNullOrEmpty(typedDefinition.FilterField3))
                wpXml.SetOrUpdateProperty("FilterField3", typedDefinition.FilterField3);

            // FilterXXXIsCustomValue
            if (typedDefinition.Filter1IsCustomValue.HasValue)
                wpXml.SetOrUpdateProperty("Filter1IsCustomValue", typedDefinition.Filter1IsCustomValue.ToString());

            if (typedDefinition.Filter2IsCustomValue.HasValue)
                wpXml.SetOrUpdateProperty("Filter2IsCustomValue", typedDefinition.Filter2IsCustomValue.ToString());

            if (typedDefinition.Filter3IsCustomValue.HasValue)
                wpXml.SetOrUpdateProperty("Filter3IsCustomValue", typedDefinition.Filter3IsCustomValue.ToString());

            // FilterValueXXX
            if (!string.IsNullOrEmpty(typedDefinition.FilterValue1))
                wpXml.SetOrUpdateProperty("FilterValue1", typedDefinition.FilterValue1);

            if (!string.IsNullOrEmpty(typedDefinition.FilterValue2))
                wpXml.SetOrUpdateProperty("FilterValue2", typedDefinition.FilterValue2);

            if (!string.IsNullOrEmpty(typedDefinition.FilterValue3))
                wpXml.SetOrUpdateProperty("FilterValue3", typedDefinition.FilterValue3);

            var filterChainingOperatorType = "Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart+FilterChainingOperator, Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c";

            if (!string.IsNullOrEmpty(typedDefinition.Filter1ChainingOperator))
                wpXml.SetTypedProperty("Filter1ChainingOperator", typedDefinition.Filter1ChainingOperator, filterChainingOperatorType);

            if (!string.IsNullOrEmpty(typedDefinition.Filter2ChainingOperator))
                wpXml.SetTypedProperty("Filter2ChainingOperator", typedDefinition.Filter2ChainingOperator, filterChainingOperatorType);

            // sorting
            if (!string.IsNullOrEmpty(typedDefinition.SortBy))
                wpXml.SetOrUpdateProperty("SortBy", typedDefinition.SortBy);

            if (!string.IsNullOrEmpty(typedDefinition.SortByDirection))
                wpXml.SetTypedProperty("SortByDirection", typedDefinition.SortByDirection, "Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart+SortDirection, Microsoft.SharePoint.Publishing, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");

            if (!string.IsNullOrEmpty(typedDefinition.SortByFieldType))
                wpXml.SetOrUpdateProperty("SortByFieldType", typedDefinition.SortByFieldType);

            if (!string.IsNullOrEmpty(typedDefinition.GroupByDirection))
                wpXml.SetTypedProperty("GroupByDirection", typedDefinition.GroupByDirection, "Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart+SortDirection, Microsoft.SharePoint.Publishing, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");

            var filterOperatorType = "Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart+FilterFieldQueryOperator, Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c";

            // FilterOperatorXXX
            if (!string.IsNullOrEmpty(typedDefinition.FilterOperator1))
                wpXml.SetTypedProperty("FilterOperator1", typedDefinition.FilterOperator1, filterOperatorType);

            if (!string.IsNullOrEmpty(typedDefinition.FilterOperator2))
                wpXml.SetTypedProperty("FilterOperator2", typedDefinition.FilterOperator2, filterOperatorType);

            if (!string.IsNullOrEmpty(typedDefinition.FilterOperator3))
                wpXml.SetTypedProperty("FilterOperator3", typedDefinition.FilterOperator3, filterOperatorType);

            // FilterDisplayValueXXX

            if (!string.IsNullOrEmpty(typedDefinition.FilterDisplayValue1))
                wpXml.SetOrUpdateProperty("FilterDisplayValue1", typedDefinition.FilterDisplayValue1);

            if (!string.IsNullOrEmpty(typedDefinition.FilterDisplayValue2))
                wpXml.SetOrUpdateProperty("FilterDisplayValue2", typedDefinition.FilterDisplayValue2);

            if (!string.IsNullOrEmpty(typedDefinition.FilterDisplayValue3))
                wpXml.SetOrUpdateProperty("FilterDisplayValue3", typedDefinition.FilterDisplayValue3);

            // bindings
            if (typedDefinition.ServerTemplate.HasValue)
                wpXml.SetOrUpdateProperty("ServerTemplate", typedDefinition.ServerTemplate.ToString());

            if (!string.IsNullOrEmpty(typedDefinition.ContentTypeName))
                wpXml.SetOrUpdateProperty("ContentTypeName", typedDefinition.ContentTypeName);

            if (!string.IsNullOrEmpty(typedDefinition.ContentTypeBeginsWithId))
                wpXml.SetOrUpdateProperty("ContentTypeBeginsWithId", typedDefinition.ContentTypeBeginsWithId);

            if (typedDefinition.ListId.HasGuidValue())
                wpXml.SetTypedProperty("ListId", typedDefinition.ListId.Value.ToString("D"), "Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart+FilterChainingOperator, Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");

            if (typedDefinition.ListGuid.HasGuidValue())
                wpXml.SetOrUpdateProperty("ListGuid", typedDefinition.ListGuid.Value.ToString("D"));

            if (!string.IsNullOrEmpty(typedDefinition.ListName))
            {
                // ServerTemplate

                var webLookup = new LookupFieldModelHandler();

                var targetWeb = webLookup.GetTargetWeb(listItemModelHost.HostSite,
                    typedDefinition.WebUrl,
                    typedDefinition.WebId);

                var list = targetWeb.QueryAndGetListByTitle(typedDefinition.ListName);
                wpXml.SetOrUpdateProperty("ListGuid", list.Id.ToString("D"));

            #if !NET35
                var folder = list.RootFolder;

                context.Load(folder, f => f.Properties);
                context.ExecuteQueryWithTrace();

                var serverTemplate = ConvertUtils.ToString(list.RootFolder.Properties["vti_listservertemplate"]);

                if (string.IsNullOrEmpty(serverTemplate))
                {
                    throw new SPMeta2Exception(
                        string.Format("Cannot find vti_listservertemplate property for the list name:[{0}]",
                        typedDefinition.ListName));
                }

                wpXml.SetOrUpdateProperty("ServerTemplate", serverTemplate);
            #endif
            }

            if (!string.IsNullOrEmpty(typedDefinition.ListUrl))
            {
                var webLookup = new LookupFieldModelHandler();

                var targetWeb = webLookup.GetTargetWeb(listItemModelHost.HostSite,
                    typedDefinition.WebUrl,
                    typedDefinition.WebId);

                var list = targetWeb.QueryAndGetListByUrl(typedDefinition.ListUrl);
                wpXml.SetOrUpdateProperty("ListGuid", list.Id.ToString("D"));

            #if !NET35
                var folder = list.RootFolder;

                context.Load(folder, f => f.Properties);
                context.ExecuteQueryWithTrace();

                var serverTemplate = ConvertUtils.ToString(list.RootFolder.Properties["vti_listservertemplate"]);

                if (string.IsNullOrEmpty(serverTemplate))
                {
                    throw new SPMeta2Exception(
                        string.Format("Cannot find vti_listservertemplate property for the list url:[{0}]",
                        typedDefinition.ListUrl));
                }

                wpXml.SetOrUpdateProperty("ServerTemplate", serverTemplate);
            #endif
            }

            if (!string.IsNullOrEmpty(typedDefinition.WebUrl))
                wpXml.SetOrUpdateProperty("WebUrl", typedDefinition.WebUrl);

            // overrides
            if (!string.IsNullOrEmpty(typedDefinition.ListsOverride))
                wpXml.SetOrUpdateProperty("ListsOverride", typedDefinition.ListsOverride);

            if (!string.IsNullOrEmpty(typedDefinition.ViewFieldsOverride))
                wpXml.SetOrUpdateProperty("ViewFieldsOverride", typedDefinition.ViewFieldsOverride);

            if (!string.IsNullOrEmpty(typedDefinition.QueryOverride))
                wpXml.SetOrUpdateProperty("QueryOverride", typedDefinition.QueryOverride);

            if (!string.IsNullOrEmpty(typedDefinition.CommonViewFields))
                wpXml.SetOrUpdateProperty("CommonViewFields", typedDefinition.CommonViewFields);

            if (typedDefinition.FilterByAudience.HasValue)
                wpXml.SetOrUpdateProperty("FilterByAudience", typedDefinition.FilterByAudience.ToString());

            return wpXml.ToString();
        }