private static TokenParser ProvisionFeaturesImplementation <T>(T parent, IEnumerable <Feature> features, TokenParser parser, PnPMonitoredScope scope)
        {
            var  activeFeatures = new List <Microsoft.SharePoint.Client.Feature>();
            Web  web            = null;
            Site site           = null;

            if (parent is Site)
            {
                site = parent as Site;
                site.Context.Load(site.Features, fs => fs.Include(f => f.DefinitionId));
                site.Context.ExecuteQueryRetry();
                activeFeatures = site.Features.ToList();
            }
            else
            {
                web = parent as Web;
                web.Context.Load(web.Features, fs => fs.Include(f => f.DefinitionId));
                web.Context.ExecuteQueryRetry();
                activeFeatures = web.Features.ToList();
            }

            if (features != null)
            {
                foreach (var feature in features)
                {
                    if (!feature.Deactivate)
                    {
                        if (activeFeatures.FirstOrDefault(f => f.DefinitionId == feature.Id) == null)
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Features_Activating__0__scoped_feature__1_, site != null ? "site" : "web", feature.Id);
                            if (site != null)
                            {
                                try
                                {
                                    site.ActivateFeature(feature.Id);
                                }
                                catch (ServerException ex)
                                {
                                    scope.LogError("Error activating feature {0}: {1}", feature.Id, ex.Message);
                                }
                            }
                            else
                            {
                                try
                                {
                                    web.ActivateFeature(feature.Id);
                                }
                                catch (ServerException ex)
                                {
                                    scope.LogError("Error activating feature {0}: {1}", feature.Id, ex.Message);
                                }
                            }
                        }
                    }
                    else
                    {
                        if (activeFeatures.FirstOrDefault(f => f.DefinitionId == feature.Id) != null)
                        {
                            scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Features_Deactivating__0__scoped_feature__1_, site != null ? "site" : "web", feature.Id);
                            if (site != null)
                            {
                                try
                                {
                                    site.DeactivateFeature(feature.Id);
                                }
                                catch (ServerException ex)
                                {
                                    scope.LogError("Error deactivating feature {0}: {1}", feature.Id, ex.Message);
                                }
                            }
                            else
                            {
                                try
                                {
                                    web.DeactivateFeature(feature.Id);
                                }
                                catch (ServerException ex)
                                {
                                    scope.LogError("Error deactivating feature {0}: {1}", feature.Id, ex.Message);
                                }
                            }
                        }
                    }
                }
            }
            if (parent is Site)
            {
                parser.AddListTokens((parent as Site).RootWeb);
            }
            else
            {
                parser.AddListTokens(parent as Web);
            }
            return(parser);
        }