public void CanCreateEntities()
        {
            using (var ctx = TestCommon.CreateClientContext())
            {
                var template = new ProvisioningTemplate();
                template = new ObjectFeatures().CreateEntities(ctx.Web, template, null);

                Assert.IsTrue(template.Features.SiteFeatures.Any());
                Assert.IsTrue(template.Features.WebFeatures.Any());
                Assert.IsInstanceOfType(template.Features, typeof(Features));
            }
        }
        public void CanCreateEntities()
        {
            using (var ctx = TestCommon.CreateClientContext())
            {
                // Load the base template which will be used for the comparison work
                var creationInfo = new ProvisioningTemplateCreationInformation(ctx.Web) { BaseTemplate = null };

                var template = new ProvisioningTemplate();
                template = new ObjectFeatures().CreateEntities(ctx.Web, template, creationInfo);

                Assert.IsTrue(template.Features.SiteFeatures.Any());
                Assert.IsTrue(template.Features.WebFeatures.Any());
                Assert.IsInstanceOfType(template.Features, typeof(Features));
            }
        }
        /// <summary>
        /// Actual implementation of extracting configuration from existing site.
        /// </summary>
        /// <param name="web"></param>
        /// <param name="baseTemplate"></param>
        /// <returns></returns>
        internal ProvisioningTemplate GetRemoteTemplate(Web web, ProvisioningTemplateCreationInformation creationInfo)
        {
            // Create empty object
            ProvisioningTemplate template = new ProvisioningTemplate();

            // Hookup connector, is handy when the generated template object is used to apply to another site
            template.Connector = creationInfo.FileConnector;

            // Get Security
            template = new ObjectSiteSecurity().CreateEntities(web, template, creationInfo);
            // Site Fields
            template = new ObjectField().CreateEntities(web, template, creationInfo);
            // Content Types
            template = new ObjectContentType().CreateEntities(web, template, creationInfo);
            // Get Lists
            template = new ObjectListInstance().CreateEntities(web, template, creationInfo);
            // Get custom actions
            template = new ObjectCustomActions().CreateEntities(web, template, creationInfo);
            // Get features
            template = new ObjectFeatures().CreateEntities(web, template, creationInfo);
            // Get composite look
            template = new ObjectComposedLook().CreateEntities(web, template, creationInfo);
            // Get files
            template = new ObjectFiles().CreateEntities(web, template, creationInfo);
            // Get Property Bag Entries
            template = new ObjectPropertyBagEntry().CreateEntities(web, template, creationInfo);
            // In future we could just instantiate all objects which are inherited from object handler base dynamically

            // Set default values for Template ID and Version
            template.ID      = String.Format("TEMPLATE-{0:N}", Guid.NewGuid()).ToUpper();
            template.Version = 1;

            // Retrieve original Template ID and remove it from Property Bag Entries
            int provisioningTemplateIdIndex = template.PropertyBagEntries.FindIndex(f => f.Key.Equals("_PnP_ProvisioningTemplateId"));

            if (provisioningTemplateIdIndex > -1)
            {
                var templateId = template.PropertyBagEntries[provisioningTemplateIdIndex].Value;
                if (!String.IsNullOrEmpty(templateId))
                {
                    template.ID = templateId;
                }
                template.PropertyBagEntries.RemoveAt(provisioningTemplateIdIndex);
            }

            // Retrieve original Template Info and remove it from Property Bag Entries
            int provisioningTemplateInfoIndex = template.PropertyBagEntries.FindIndex(f => f.Key.Equals("_PnP_ProvisioningTemplateInfo"));

            if (provisioningTemplateInfoIndex > -1)
            {
                var jsonInfo = template.PropertyBagEntries[provisioningTemplateInfoIndex].Value;

                var s = new JavaScriptSerializer();
                ProvisioningTemplateInfo info = s.Deserialize <ProvisioningTemplateInfo>(jsonInfo);

                // Override any previously defined Template ID, Version, and SitePolicy
                // with the one stored in the Template Info, if any
                if (!String.IsNullOrEmpty(info.TemplateID))
                {
                    template.ID = info.TemplateID;
                }
                if (!String.IsNullOrEmpty(info.TemplateSitePolicy))
                {
                    template.SitePolicy = info.TemplateSitePolicy;
                }
                if (info.TemplateVersion > 0)
                {
                    template.Version = info.TemplateVersion;
                }

                template.PropertyBagEntries.RemoveAt(provisioningTemplateInfoIndex);
            }

            return(template);
        }
        /// <summary>
        /// Actual implementation of extracting configuration from existing site.
        /// </summary>
        /// <param name="web"></param>
        /// <param name="baseTemplate"></param>
        /// <returns></returns>
        internal ProvisioningTemplate GetRemoteTemplate(Web web, ProvisioningTemplateCreationInformation creationInfo)
        {
            // Create empty object
            ProvisioningTemplate template = new ProvisioningTemplate();

            // Hookup connector, is handy when the generated template object is used to apply to another site
            template.Connector = creationInfo.FileConnector;

            // Get Security
            template = new ObjectSiteSecurity().CreateEntities(web, template, creationInfo);
            // Site Fields
            template = new ObjectField().CreateEntities(web, template, creationInfo);
            // Content Types
            template = new ObjectContentType().CreateEntities(web, template, creationInfo);
            // Get Lists 
            template = new ObjectListInstance().CreateEntities(web, template, creationInfo);
            // Get custom actions
            template = new ObjectCustomActions().CreateEntities(web, template, creationInfo);
            // Get features
            template = new ObjectFeatures().CreateEntities(web, template, creationInfo);
            // Get composite look
            template = new ObjectComposedLook().CreateEntities(web, template, creationInfo);
            // Get files
            template = new ObjectFiles().CreateEntities(web, template, creationInfo);
            // Get Property Bag Entries
            template = new ObjectPropertyBagEntry().CreateEntities(web, template, creationInfo);
            // In future we could just instantiate all objects which are inherited from object handler base dynamically 

            // Set default values for Template ID and Version
            template.ID = String.Format("TEMPLATE-{0:N}", Guid.NewGuid()).ToUpper();
            template.Version = 1;

            // Retrieve original Template ID and remove it from Property Bag Entries
            int provisioningTemplateIdIndex = template.PropertyBagEntries.FindIndex(f => f.Key.Equals("_PnP_ProvisioningTemplateId"));
            if (provisioningTemplateIdIndex > -1)
            {
                var templateId = template.PropertyBagEntries[provisioningTemplateIdIndex].Value;
                if (!String.IsNullOrEmpty(templateId))
                {
                    template.ID = templateId;
                }
                template.PropertyBagEntries.RemoveAt(provisioningTemplateIdIndex);
            }

            // Retrieve original Template Info and remove it from Property Bag Entries
            int provisioningTemplateInfoIndex = template.PropertyBagEntries.FindIndex(f => f.Key.Equals("_PnP_ProvisioningTemplateInfo"));
            if (provisioningTemplateInfoIndex > -1)
            {
                var jsonInfo = template.PropertyBagEntries[provisioningTemplateInfoIndex].Value;

                var s = new JavaScriptSerializer();
                ProvisioningTemplateInfo info = s.Deserialize<ProvisioningTemplateInfo>(jsonInfo);

                // Override any previously defined Template ID, Version, and SitePolicy
                // with the one stored in the Template Info, if any
                if (!String.IsNullOrEmpty(info.TemplateID))
                {
                    template.ID = info.TemplateID;
                }
                if (!String.IsNullOrEmpty(info.TemplateSitePolicy))
                {
                    template.SitePolicy = info.TemplateSitePolicy;
                }
                if (info.TemplateVersion > 0)
                {
                    template.Version = info.TemplateVersion;
                }

                template.PropertyBagEntries.RemoveAt(provisioningTemplateInfoIndex);
            }

            return template;
        }