private void CreateOrUpdateView(Web web, View view, SPClient.View existingView, List createdList, PnPMonitoredScope monitoredScope)
        {
            try
            {
                var viewElement = view.XmlNode;
                var viewTitle = view.GetAttributeValue("DisplayName");
                if (string.IsNullOrEmpty(viewTitle))
                {
                    throw new ApplicationException("Invalid View element, missing a valid value for the attribute DisplayName.");
                }
                monitoredScope.LogDebug(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_view__0_, viewTitle);

                // Type
                var viewTypeString = viewElement.Attribute("Type") != null ? viewElement.Attribute("Type").Value : "None";
                viewTypeString = viewTypeString[0].ToString().ToUpper() + viewTypeString.Substring(1).ToLower();
                var viewType = (ViewType)Enum.Parse(typeof(ViewType), viewTypeString);

                // Fields
                string[] viewFields = null;
                var viewFieldsElement = viewElement.Descendants("ViewFields").FirstOrDefault();
                if (viewFieldsElement != null)
                {
                    viewFields = (from field in viewElement.Descendants("ViewFields").Descendants("FieldRef") select field.Attribute("Name").Value).ToArray();
                }

                // Default view
                var viewDefault = viewElement.Attribute("DefaultView") != null && Boolean.Parse(viewElement.Attribute("DefaultView").Value);

                // Row limit
                var viewPaged = true;
                uint viewRowLimit = 30;
                var rowLimitElement = viewElement.Descendants("RowLimit").FirstOrDefault();
                if (rowLimitElement != null)
                {
                    if (rowLimitElement.Attribute("Paged") != null)
                    {
                        viewPaged = bool.Parse(rowLimitElement.Attribute("Paged").Value);
                    }
                    viewRowLimit = uint.Parse(rowLimitElement.Value);
                }

                // Query
                var viewQuery = new StringBuilder();
                foreach (var queryElement in viewElement.Descendants("Query").Elements())
                {
                    viewQuery.Append(queryElement);
                }

                var viewCI = new ViewCreationInformation
                {
                    ViewFields = viewFields,
                    RowLimit = viewRowLimit,
                    Paged = viewPaged,
                    Title = viewTitle,
                    Query = viewQuery.ToString(),
                    ViewTypeKind = viewType,
                    PersonalView = false,
                    SetAsDefaultView = viewDefault,
                };

                // Allow to specify a custom view url. View url is taken from title, so we first set title to the view url value we need,
                // create the view and then set title back to the original value
                var urlAttribute = viewElement.Attribute("Url");
                var urlHasValue = urlAttribute != null && !string.IsNullOrEmpty(urlAttribute.Value);
                if (urlHasValue)
                {
                    //set Title to be equal to url (in order to generate desired url)
                    viewCI.Title = Path.GetFileNameWithoutExtension(urlAttribute.Value);
                }

                if (null != existingView)
                {
                    bool needToDelete = false;
                    bool isDirty = false;
                    if (!string.Equals(viewCI.ViewTypeKind.ToString(), existingView.ViewType, StringComparison.OrdinalIgnoreCase))
                    {
                        needToDelete = true;
                    }
                    else
                    {
                        if (string.Join(",", existingView.ViewFields.ToArray()) != string.Join(",", viewCI.ViewFields))
                        {
                            existingView.ViewFields.RemoveAll();
                            foreach (string fieldName in viewCI.ViewFields)
                            {
                                existingView.ViewFields.Add(fieldName);
                            }
                            isDirty = true;
                        }
                        if (existingView.RowLimit != viewCI.RowLimit)
                        {
                            existingView.RowLimit = viewCI.RowLimit;
                            isDirty = true;
                        }
                        if (existingView.Paged != viewCI.Paged)
                        {
                            existingView.Paged = viewCI.Paged;
                            isDirty = true;
                        }
                        if (existingView.Title != viewTitle)
                        {
                            existingView.Title = viewTitle;
                            isDirty = true;
                        }
                        if (existingView.ViewQuery != viewCI.Query)
                        {
                            existingView.ViewQuery = viewCI.Query;
                            isDirty = true;
                        }
                        if (existingView.DefaultView != viewCI.SetAsDefaultView)
                        {
                            existingView.DefaultView = viewCI.SetAsDefaultView;
                            isDirty = true;
                        }
                    }

                    if (needToDelete)
                    {
                        existingView.DeleteObject();
                web.Context.ExecuteQueryRetry();
                        existingView = null;
                    }
                    else if (isDirty)
                    {
                        existingView.Update();
                        web.Context.ExecuteQueryRetry();
                    }
                }

                SPClient.View createdView = null;
                if (null == existingView)
                {
                    createdView = createdList.Views.Add(viewCI);
                    web.Context.Load(createdView);
                    web.Context.ExecuteQueryRetry();
                }
                else
                {
                    createdView = existingView;
                }

                bool dirty = false;
                if ( createdView.Title != viewTitle )
                {
                    //restore original title
                    createdView.Title = viewTitle;
                    dirty = true;
                }

                // ContentTypeID
                var contentTypeID = viewElement.Attribute("ContentTypeID") != null ? viewElement.Attribute("ContentTypeID").Value : null;
                if (!string.IsNullOrEmpty(contentTypeID) && (contentTypeID != BuiltInContentTypeId.System))
                {
                    ContentTypeId childContentTypeId = null;
                    if (contentTypeID == BuiltInContentTypeId.RootOfList)
                    {
                        var childContentType = web.GetContentTypeById(contentTypeID);
                        childContentTypeId = childContentType != null ? childContentType.Id : null;
                    }
                    else
                    {
                        childContentTypeId = createdList.ContentTypes.BestMatch(contentTypeID);
                    }
                    if (childContentTypeId != null)
                    {
                        if ((null == createdView.ContentTypeId) || (createdView.ContentTypeId.ToString() != childContentTypeId.ToString()))
                        {
                        createdView.ContentTypeId = childContentTypeId;
                            dirty = true;
                        }
                }
                }

                // Default for content type
                bool parsedDefaultViewForContentType;
                var defaultViewForContentType = viewElement.Attribute("DefaultViewForContentType") != null ? viewElement.Attribute("DefaultViewForContentType").Value : null;
                if (!string.IsNullOrEmpty(defaultViewForContentType) && bool.TryParse(defaultViewForContentType, out parsedDefaultViewForContentType))
                {
                    if (createdView.DefaultViewForContentType != parsedDefaultViewForContentType)
                    {
                    createdView.DefaultViewForContentType = parsedDefaultViewForContentType;
                        dirty = true;
                    }
                }

                // Scope
                var scope = viewElement.Attribute("Scope") != null ? viewElement.Attribute("Scope").Value : null;
                ViewScope parsedScope;
                if (!string.IsNullOrEmpty(scope) && Enum.TryParse(scope, out parsedScope))
                {
                    if (createdView.Scope != parsedScope)
                    {
                    createdView.Scope = parsedScope;
                        dirty = true;
                    }
                }

                // JSLink
                var jslinkElement = viewElement.Descendants("JSLink").FirstOrDefault();
                if (jslinkElement != null)
                {
                    var jslink = jslinkElement.Value;
                    if (createdView.JSLink != jslink)
                    {
                        createdView.JSLink = jslink;
                        dirty = true;
                    }
                }
                if (dirty)
                {
                        createdView.Update();
                    }
                createdList.Update();
                web.Context.ExecuteQueryRetry();
            }
            catch (Exception ex)
            {
                monitoredScope.LogError(CoreResources.Provisioning_ObjectHandlers_ListInstances_Creating_view_failed___0_____1_, ex.Message, ex.StackTrace);
            }
        }