public ActionResult Create(HiveId id)
        {
            var model = new PackageDefinitionEditorModel {ParentId = id};

            PopulateCollections(model);

            return View("Edit", model);
        }
        public ActionResult CreateForm(PackageDefinitionEditorModel model)
        {
            PopulateCollections(model);

            return ProcessSubmit(model, Request.Form.ContainsKey("submit.Publish"));
        }
        protected ActionResult ProcessSubmit(PackageDefinitionEditorModel model, bool publish)
        {
            Mandate.ParameterNotNull(model, "model");

            //if there's model errors, return the view
            if (!ModelState.IsValid)
            {
                AddValidationErrorsNotification();
                return View("Edit", model);
            }

            //persist the data
            using (var uow = _hive.Create())
            {
                var entity = BackOfficeRequestContext.Application.FrameworkContext.TypeMappers.Map
                            <PackageDefinitionEditorModel, PackageDefinition>(model);

                var randomId = Guid.NewGuid().ToString();

                if(!model.Id.IsNullValueOrEmpty())
                {
                    var oldFolder = uow.Repositories.Get<Umbraco.Framework.Persistence.Model.IO.File>(model.Id);
                    if (oldFolder != null)
                    {
                        uow.Repositories.Delete<Umbraco.Framework.Persistence.Model.IO.File>(oldFolder.Id);
                        randomId = oldFolder.Id.Value.ToString();
                    }
                }

                // Create folder
                var folder = new Umbraco.Framework.Persistence.Model.IO.File(
                    randomId, "") { IsContainer = true };

                uow.Repositories.AddOrUpdate(folder);

                // Create definition file
                var file = new Umbraco.Framework.Persistence.Model.IO.File(
                    randomId + "/package.definition",
                    Encoding.UTF8.GetBytes(entity.ToJsonString()));

                uow.Repositories.AddOrUpdate(file);

                model.Id = folder.Id;

                uow.Complete();

                //add path for entity for SupportsPathGeneration (tree syncing) to work
                GeneratePathsForCurrentEntity(new EntityPathCollection(model.Id, new[]{ new EntityPath(new[]
                    {
                        new HiveId(FixedSchemaTypes.SystemRoot, null, new HiveIdValue(new Guid("802282F2-134E-4165-82B5-6DB2AFDDD135"))),
                        new HiveId(3), 
                        model.Id, 
                    })
                }));

                if(publish)
                {
                    // Generate the package file
                    var result = PackageBuilderHelper.CreatePackage(randomId, entity);
                    if(!result.Success)
                    {
                        ModelState.AddModelError("", "An error occured whilst trying to create the package file:\n"+ result.ErrorMessage);
                        return View("Edit", model);
                    }
                }

                Notifications.Add(new NotificationMessage(
                    "Package.Save.Message".Localize(this),
                    "Package.Save.Title".Localize(this),
                    NotificationType.Success));

                return RedirectToAction("Edit", new { id = model.Id });
            }
        }
        private void PopulateCollections(PackageDefinitionEditorModel model)
        {
            using (var uow = BackOfficeRequestContext.Application.Hive.OpenReader<IContentStore>())
            {
                // Doc types
                var docTypeIds = uow.Repositories.Schemas.GetDescendentRelations(FixedHiveIds.ContentRootSchema, FixedRelationTypes.DefaultRelationType)
                    .Where(x => !x.DestinationId.IsSystem())
                    .DistinctBy(x => x.DestinationId)
                    .Select(x => x.DestinationId).ToArray();
                var docTypes = uow.Repositories.Schemas.Get<EntitySchema>(true, docTypeIds)
                    .OrderBy(x => x.Name.Value);

                model.AvailableDocumentTypes = docTypes.Select(x => new HierarchicalSelectListItem
                {
                    Text = x.Name,
                    Value = x.Id.ToString(),
                    ParentValues = x.RelationProxies.GetParentRelations(FixedRelationTypes.DefaultRelationType)
                        .Where(y => y.Item.SourceId.Value != FixedHiveIds.ContentRootSchema.Value)
                        .Select(y => y.Item.SourceId.ToString()).ToArray(),
                    Selected = model.DocumentTypeIds != null && model.DocumentTypeIds.Contains(x.Id, new HiveIdComparer(true))
                }).ToArray();

                // Media types
                var mediaTypeIds = uow.Repositories.Schemas.GetDescendentRelations(FixedHiveIds.MediaRootSchema, FixedRelationTypes.DefaultRelationType)
                    .Where(x => !x.DestinationId.IsSystem())
                    .DistinctBy(x => x.DestinationId)
                    .Select(x => x.DestinationId).ToArray();
                var mediaTypes = uow.Repositories.Schemas.Get<EntitySchema>(true, mediaTypeIds)
                    .OrderBy(x => x.Name.Value);

                model.AvailableMediaTypes = mediaTypes.Select(x => new HierarchicalSelectListItem
                {
                    Text = x.Name,
                    Value = x.Id.ToString(),
                    ParentValues = x.RelationProxies.GetParentRelations(FixedRelationTypes.DefaultRelationType)
                        .Where(y => y.Item.SourceId.Value != FixedHiveIds.MediaRootSchema.Value)
                        .Select(y => y.Item.SourceId.ToString()).ToArray(),
                    Selected = model.MediaTypeIds != null && model.MediaTypeIds.Contains(x.Id, new HiveIdComparer(true))
                }).ToArray();

                // Data Types
                var dataTypes = uow.Repositories.Schemas.GetAll<AttributeType>()
                        .Where(x => !x.Id.IsSystem())
                        .OrderBy(x => x.Name.Value);

                model.AvailableDataTypes = dataTypes.Select(x => new SelectListItem
                {
                    Text = x.Name,
                    Value = x.Id.ToString(),
                    Selected = model.DataTypeIds != null && model.DataTypeIds.Contains(x.Id, new HiveIdComparer(true))
                });

                // Dictionary items
                var dictionaryItemIds = uow.Repositories.GetDescendentRelations(FixedHiveIds.DictionaryVirtualRoot, FixedRelationTypes.DefaultRelationType)
                    .Where(x => !x.DestinationId.IsSystem())
                    .DistinctBy(x => x.DestinationId)
                    .Select(x => x.DestinationId).ToArray();
                var dictionaryItems = uow.Repositories.Get<TypedEntity>(true, dictionaryItemIds)
                    .OrderBy(x => x.InnerAttribute<string>(NodeNameAttributeDefinition.AliasValue, "Name"));

                model.AvailableDictionaryItems = dictionaryItems.Select(x => new HierarchicalSelectListItem
                {
                    Text = x.InnerAttribute<string>(NodeNameAttributeDefinition.AliasValue, "Name"),
                    Value = x.Id.ToString(),
                    ParentValues = x.RelationProxies.GetParentRelations(FixedRelationTypes.DefaultRelationType)
                        .Where(y => y.Item.SourceId.Value != FixedHiveIds.DictionaryVirtualRoot.Value)
                        .Select(y => y.Item.SourceId.ToString()).ToArray(),
                    Selected = model.DictionaryItemIds != null && model.DictionaryItemIds.Contains(x.Id, new HiveIdComparer(true))
                }).ToArray();
            }

            using (var uow = BackOfficeRequestContext.Application.Hive.OpenReader<IFileStore>(new Uri("storage://templates/")))
            {
                // Templates
                var templates = uow.Repositories.GetAllNonContainerFiles()
                    .OrderBy(x => x.Name);

                model.AvailableTemplates = templates.Select(x => new SelectListItem
                {
                    Text = x.GetFileNameForDisplay(), 
                    Value = x.Id.ToString(),
                    Selected = model.TemplateIds != null && model.TemplateIds.Contains(x.Id, new HiveIdComparer(true))
                });
            }

            using (var uow = BackOfficeRequestContext.Application.Hive.OpenReader<IFileStore>(new Uri("storage://partials/")))
            {
                // Partials
                var partialsRoot = uow.Repositories.Get(new HiveId("/"));
                var partialIds = uow.Repositories.GetDescendentRelations(partialsRoot.Id, FixedRelationTypes.DefaultRelationType)
                    .Where(x => !x.DestinationId.IsSystem())
                    .DistinctBy(x => x.DestinationId)
                    .Select(x => x.DestinationId).ToArray();
                var partials = uow.Repositories.Get<Umbraco.Framework.Persistence.Model.IO.File>(true, partialIds)
                    .OrderBy(x => x.Name);

                model.AvailablePartials = partials.Select(x => new HierarchicalSelectListItem
                {
                    Text = x.GetFileNameForDisplay(),
                    Value = x.Id.ToString(),
                    ParentValues = x.RelationProxies.GetParentRelations(FixedRelationTypes.DefaultRelationType)
                        .Where(y => y.Item.SourceId.Value != partialsRoot.Id.Value)
                        .Select(y => y.Item.SourceId.ToString()).ToArray(),
                    Selected = model.PartialIds != null && model.PartialIds.Contains(x.Id, new HiveIdComparer(true))
                });
            }

            using (var uow = BackOfficeRequestContext.Application.Hive.OpenReader<IFileStore>(new Uri("storage://stylesheets/")))
            {
                // Stylesheets
                var stylesheetsRoot = uow.Repositories.Get(new HiveId("/"));
                var stylesheetIds = uow.Repositories.GetDescendentRelations(stylesheetsRoot.Id, FixedRelationTypes.DefaultRelationType)
                    .Where(x => !x.DestinationId.IsSystem())
                    .DistinctBy(x => x.DestinationId)
                    .Select(x => x.DestinationId).ToArray();
                var stylesheets = uow.Repositories.Get<Umbraco.Framework.Persistence.Model.IO.File>(true, stylesheetIds)
                    .OrderBy(x => x.Name);

                model.AvailableStylesheets = stylesheets.Select(x => new HierarchicalSelectListItem
                {
                    Text = x.GetFileNameForDisplay(),
                    Value = x.Id.ToString(),
                    ParentValues = x.RelationProxies.GetParentRelations(FixedRelationTypes.DefaultRelationType)
                        .Where(y => y.Item.SourceId.Value != stylesheetsRoot.Id.Value)
                        .Select(y => y.Item.SourceId.ToString()).ToArray(),
                    Selected = model.StylesheetIds != null && model.StylesheetIds.Contains(x.Id, new HiveIdComparer(true))
                });
            }

            using (var uow = BackOfficeRequestContext.Application.Hive.OpenReader<IFileStore>(new Uri("storage://scripts/")))
            {
                // Scripts
                var scriptsRoot = uow.Repositories.Get(new HiveId("/"));
                var scriptIds = uow.Repositories.GetDescendentRelations(scriptsRoot.Id, FixedRelationTypes.DefaultRelationType)
                    .Where(x => !x.DestinationId.IsSystem())
                    .DistinctBy(x => x.DestinationId)
                    .Select(x => x.DestinationId).ToArray();
                var scripts = uow.Repositories.Get<Umbraco.Framework.Persistence.Model.IO.File>(true, scriptIds)
                    .OrderBy(x => x.Name);

                model.AvailableScripts = scripts.Select(x => new HierarchicalSelectListItem
                {
                    Text = x.GetFileNameForDisplay(),
                    Value = x.Id.ToString(),
                    ParentValues = x.RelationProxies.GetParentRelations(FixedRelationTypes.DefaultRelationType)
                        .Where(y => y.Item.SourceId.Value != scriptsRoot.Id.Value)
                        .Select(y => y.Item.SourceId.ToString()).ToArray(),
                    Selected = model.ScriptIds != null && model.ScriptIds.Contains(x.Id, new HiveIdComparer(true))
                });
            }

            using (var uow = BackOfficeRequestContext.Application.Hive.OpenReader<IFileStore>(new Uri("storage://macros/")))
            {
                // Macros
                var partials = uow.Repositories.GetAllNonContainerFiles()
                    .OrderBy(x => x.Name);

                model.AvailableMacros = partials.Select(x => new SelectListItem
                {
                    Text = x.GetFileNameForDisplay(),
                    Value = x.Id.ToString(),
                    Selected = model.MacroIds != null && model.MacroIds.Contains(x.Id, new HiveIdComparer(true))
                });
            }

            // Languages
            var languages = BackOfficeRequestContext.Application.Settings.Languages
                .OrderBy(x => x.Name);

            model.AvailableLanguages = languages.Select(x => new SelectListItem
            {
                Text = x.Name,
                Value = x.IsoCode,
                Selected = model.LanguageIds != null && model.LanguageIds.Contains(x.IsoCode)
            });
        }
        public ActionResult EditForm(PackageDefinitionEditorModel model)
        {
            Mandate.ParameterNotNull(model, "model");

            PopulateCollections(model);

            return ProcessSubmit(model, Request.Form.ContainsKey("submit.Publish"));
        }