public void AddListItems(DataRowCollection dataRows, ProvisioningTemplate template, TokenParser parser, PnPMonitoredScope scope)
        {
            Microsoft.SharePoint.Client.FieldCollection fields = this.List.Fields;
            this.Context.Load(fields);
            this.Context.Load(this.List, l => l.RootFolder.ServerRelativeUrl);
            this.Context.ExecuteQueryRetry();

            ItemPathProvider itemPathProvider = new ItemPathProvider(this.List, this.Web);

            bool isDocLib = ( this.List.BaseType == BaseType.DocumentLibrary );

            var items = new List<ListItemInfo>();
            this.Context.ExecuteQueryBatch(dataRows.ToList(), (dataRow) =>
            {
                scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_list_item__0_, dataRows.IndexOf(dataRow) + 1);

                var listitem = itemPathProvider.CreateListItem(dataRow, template);
                if (null != listitem)
                {
                    foreach (var dataValue in dataRow.Values)
                    {
                        Field dataField = fields.FirstOrDefault(
                            f => f.InternalName == parser.ParseString(dataValue.Key));

                        if ((dataField != null) && CanFieldContentBeIncluded(dataField, false))
                        {
                            string fieldValue = parser.ParseString(dataValue.Value);
                            if (!string.IsNullOrEmpty(fieldValue))
                            {
                                FieldValueProvider valueProvider = GetFieldValueProvider(dataField, this.Web);
                                if (null != valueProvider)
                                {
                                    object itemValue = valueProvider.GetFieldValueTyped(fieldValue);
                                    if (null != itemValue)
                                    {
                                        if (dataField.FieldTypeKind == FieldType.Lookup)
                                        {
                                            FieldLookup lookupField = (FieldLookup)dataField;
                                            RegisterLookupReference(lookupField, listitem, itemValue);
                                        }
                                        else
                                        {
                                            listitem[dataField.InternalName] = itemValue;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    listitem.Update();

                    this.Context.Load(listitem);
                    if (isDocLib)
                    {
                        this.Context.Load(listitem.File);
                    }

                    items.Add(new ListItemInfo()
                    {
                        Item = listitem,
                        Row = dataRow
                    });
                }

            }, (error, dataRow) =>
            {
                for (var i = items.Count - 1; i >= 0; i--)
                {
                    if (items[i].Row == dataRow)
                    {
                        items.RemoveAt(i);
                    }
                }
                scope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstancesDataRows_Creating_listitem_failed___0_____1_, error, "");
            }, isDocLib ? 1 : BATCH_SIZE);

            //Ensure files CheckIn
            if (isDocLib)
            {
                this.Context.ExecuteQueryBatch(items, (itemInfo) =>
                {
                    Microsoft.SharePoint.Client.File file = itemInfo.Item.File;
                    if ((null != file.ServerObjectIsNull) && (!(bool)file.ServerObjectIsNull) &&
                            (file.CheckOutType != CheckOutType.None))
                    {
                        file.CheckIn("", CheckinType.MajorCheckIn);
                    }
                }, BATCH_SIZE);
            }

            foreach (ListItemInfo itemInfo in items)
            {
                try
                {
                    var listitem = itemInfo.Item;
                    var dataRow = itemInfo.Row;
                    if (0 < listitem.Id)
                    {
                        AddIDMappingEntry(listitem, dataRow);

                        if (dataRow.Security != null && dataRow.Security.RoleAssignments.Count != 0)
                        {
                            //Should be optimized (run in batch)
                            listitem.SetSecurity(parser, dataRow.Security);
                        }
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }
        public List<DataRow> ExtractItems( ProvisioningTemplateCreationInformation creationInfo, TokenParser parser, PnPMonitoredScope scope)
        {
            List<DataRow> dataRows = new List<DataRow>();

            bool isPageLib = (List.BaseTemplate == (int)ListTemplateType.WebPageLibrary) ||
                (List.BaseTemplate == (int)ListTemplateType.HomePageLibrary) ||
                (List.BaseTemplate == (int)ListTemplateType.PublishingPages);

            CamlQuery query = isPageLib ? CamlQuery.CreateAllFoldersQuery() : CamlQuery.CreateAllItemsQuery();
            query.DatesInUtc = true;
            ListItemCollection items = this.List.GetItems(query);
            this.Context.Load(items, col => col.IncludeWithDefaultProperties(i => i.HasUniqueRoleAssignments));
            this.Context.Load(this.List.Fields);
            this.Context.Load(this.List, l=> l.RootFolder.ServerRelativeUrl, l=> l.BaseType);
            this.Context.ExecuteQueryRetry();

            ItemPathProvider itemPathProvider = new ItemPathProvider(this.List, this.Web);

            List<Field> fields = GetListContentSerializableFields(true);
            foreach (ListItem item in items)
            {
                try
                {
                    Dictionary<string, string> values = new Dictionary<string, string>();
                    foreach (Field field in fields)
                    {
                        if (CanFieldContentBeIncluded(field, true))
                        {
                            string str = "";
                            object value = null; ;
                            try
                            {
                                value = item[field.InternalName];
                            }
                            catch (Exception ex)
                            {
                                scope.LogWarning(ex,
                                    "Failed to read item field value. List:{0}, Item ID:{1}, Field: {2}", this.List.Title, item.Id, field.InternalName);
                            }
                            if (null != value)
                            {
                                try
                                {
                                    FieldValueProvider provider = GetFieldValueProvider(field, this.Web);
                                    str = provider.GetValidatedValue(value);
                                }
                                catch (Exception ex)
                                {
                                    scope.LogWarning(ex,
                                        "Failed to serialize item field value. List:{0}, Item ID:{1}, Field: {2}", this.List.Title, item.Id, field.InternalName);
                                }
                                if (!string.IsNullOrEmpty(str))
                                {
                                    values.Add(field.InternalName, str);
                                }
                            }
                        }
                    }

                    string fileSrc;
                    itemPathProvider.ExtractItemPathValues(item, values, creationInfo, out fileSrc);

                    if (values.Any())
                    {
                        ObjectSecurity security = null;
                        if (item.HasUniqueRoleAssignments)
                        {
                            try
                            {
                                security = item.GetSecurity(parser);
                                security.ClearSubscopes = true;
                            }
                            catch (Exception ex)
                            {
                                scope.LogWarning(ex, "Failed to get item security. Item ID: {0}, List: '{1}'.", item.Id, this.List.Title);
                            }
                        }

                        DataRow row = new DataRow(values, security, fileSrc);
                        dataRows.Add(row);
                    }
                }
                catch (Exception ex)
                {
                    scope.LogError(ex, "Failed to save item in template. Item ID: {0}, List: '{1}'.", item.Id, this.List.Title);
                }
            }

            return dataRows;
        }