public static Dictionary<string, IList<File>> CreateLayoutFileMap(IEnumerable<File> files)
        {
            var fileMap = new Dictionary<string, IList<File>>
            {
                {"None", new List<File>()}
            };

            foreach (var file in files)
            {
                if (file.Name.ToLower().StartsWith("_viewstart."))
                {
                    fileMap["None"].Add(file);
                }
                else
                {
                    var result = new TemplateParser().Parse(file);
                    var idx = "None";

                    if (!string.IsNullOrWhiteSpace(result.Layout))
                    {
                        idx = ResolveLayoutPath(result.Layout, file);
                    }

                    if (!fileMap.ContainsKey(idx))
                        fileMap.Add(idx, new List<File>());

                    fileMap[idx].Add(file);
                }
            }

            return fileMap;
        }
        public void TemplateParserTests_Pares_Success()
        {
            // Arrange
            var file = new File
            {
                ContentBytes = Encoding.UTF8.GetBytes(@"
                @{
                    Layout = ""_Layout.cshtml"";
                }
                <html>
                    <head>
                        @RenderSection(""Head"")
                    </head>
                    <body>
                        @RenderSection(""Test"", true)
                        @RenderBody()
                    </body>
                </html>
                ")
            };

            // Act
            var result = new TemplateParser().Parse(file);

            // Assert
            Assert.IsTrue(result.Layout == "_Layout.cshtml");
            Assert.IsTrue(result.Sections.Count() == 3);
            Assert.IsTrue(result.Sections.Contains("Head"));
            Assert.IsTrue(result.Sections.Contains("Test"));
            Assert.IsTrue(result.Sections.Contains("Body"));
        }
        //public override ActionResult Create(string fileName, HiveId parentId, HiveId stubFileId = default(HiveId))
        //{
        //    var model = CreateNewEditorModel(fileName, parentId, stubFileId);

        //    return View("Edit", model);
        //}

        protected override EntityPathCollection CreatePaths(File file)
        {
            //return base.CreatePath(file);

            if (file.IsContainer)
                return base.CreatePaths(file);

            var parser = new TemplateParser();
            var result = parser.Parse(file);

            if (string.IsNullOrWhiteSpace(result.Layout))
                return base.CreatePaths(file);

            var path = new List<HiveId>
            {
                file.Id
            };

            using (var uow = Hive.Create())
            {
                // Get parent paths from layout
                //TODO: Need to fetch from the current folder if we want to support folders
                var files = uow.Repositories.GetAll<File>().Where(x => !x.IsContainer && x.Id != file.Id);

                var currentLayout = TemplateHelper.ResolveLayoutPath(result.Layout, file);
                while(!string.IsNullOrWhiteSpace(currentLayout))
                {
                    var parent = files.SingleOrDefault(x => TemplateHelper.ResolveLayoutPath(x.RootRelativePath, x) == currentLayout);
                    if(parent != null)
                    {
                        path.Add(parent.Id);
                        currentLayout = parser.Parse(parent).Layout;
                    }
                    else
                    {
                        currentLayout = "";
                    }
                }

                path.Reverse();

                // Insert the actual parents path at the begining
                var actualParent = uow.Repositories.GetLazyParentRelations(file.Id, FixedRelationTypes.DefaultRelationType)
                    .Select(x => x.Source as File)
                    .SingleOrDefault();

                if (actualParent != null)
                    path.InsertRange(0, base.CreatePaths(actualParent)[0]); // Assumes a template will only ever be available at one location
            }

            return new EntityPathCollection(file.Id, new[]{ new EntityPath(path) });
        }
        public ActionResult Index(HiveId id)
        {
            var model = new ImplementSectionModel { AvailableSections = Enumerable.Empty<string>() };

            using (var uow = _templateStore.CreateReadonly())
            {
                var template = uow.Repositories.Get<File>(id);
                if(template != null)
                {
                    var parser = new TemplateParser();
                    var result = parser.Parse(template);
                    if (!string.IsNullOrWhiteSpace(result.Layout))
                    {
                        var layoutFilePath = TemplateHelper.ResolveLayoutPath(result.Layout, template);
                        var layoutFile = uow.Repositories.GetAll<File>().Where(x => x.RootedPath == layoutFilePath).FirstOrDefault();
                        var layoutResult = parser.Parse(layoutFile);

                        model.AvailableSections = layoutResult.Sections.Where(x => x != "Body").ToArray();
                    }
                }
            }

            return View(model);
        }
        protected override void PopulateFileContentFromStub(FileEditorModel model, HiveId stubFileId, IDictionary<string, string> replacements)
        {
            var parentId = model.ParentId;

            model.ParentId = FixedHiveIds.SystemRoot;

            replacements = new Dictionary<string, string> { { "$layout$", "" }, { "$sections$", "" } };

            if (!stubFileId.IsNullValueOrEmpty())
            {
                if (!parentId.IsNullValueOrEmpty() && parentId != FixedHiveIds.SystemRoot)
                {
                    using (var uow = Hive.Create())
                    {
                        var parentFile = uow.Repositories.Get<File>(parentId);
                        if (parentFile == null)
                            throw new ArgumentException("No file could be found for the parent id specified");

                        replacements["$layout$"] = parentFile.Name;
                        replacements["$sections$"] = new TemplateParser().Parse(parentFile).Sections.Where(x => x != "Body")
                            .Aggregate("", (current, section) => current + ("\n@section " + section + "\n{\n\n}\n"));
                    }
                }
            }
            
            base.PopulateFileContentFromStub(model, stubFileId, replacements);
        }
        protected override void EnsureViewData(FileEditorModel model, File file)
        {
            // Setup UIElements
            model.UIElements.Add(new SeperatorUIElement());
            model.UIElements.Add(new ButtonUIElement
            {
                Alias = "InsertField",
                Title = "Insert an umbraco page field",
                CssClass = "insert-field-button toolbar-button",
                AdditionalData = new Dictionary<string, string>
                {
                    { "id", "submit_InsertField" },
                    { "name", "submit.InsertField" }
                }
            });
            model.UIElements.Add(new ButtonUIElement
            {
                Alias = "InsertPartial",
                Title = "Insert a partial view",
                CssClass = "insert-partial-button toolbar-button",
                AdditionalData = new Dictionary<string, string>
                {
                    { "id", "submit_InsertPartial" },
                    { "name", "submit.InsertPartial" }
                }
            });
            model.UIElements.Add(new ButtonUIElement
            {
                Alias = "InsertMacro",
                Title = "Insert a macro",
                CssClass = "insert-macro-button toolbar-button",
                AdditionalData = new Dictionary<string, string>
                {
                    { "id", "submit_InsertMacro" },
                    { "name", "submit.InsertMacro" }
                }
            });
            model.UIElements.Add(new SeperatorUIElement());
            model.UIElements.Add(new ButtonUIElement
            {
                Alias = "DefineSection",
                Title = "Define a Section",
                CssClass = "define-section-button toolbar-button",
                AdditionalData = new Dictionary<string, string>
                {
                    { "id", "submit_DefineSection" },
                    { "name", "submit.DefineSection" }
                }
            });
            model.UIElements.Add(new ButtonUIElement
            {
                Alias = "ImplementSection",
                Title = "Implement a Section",
                CssClass = "implement-section-button toolbar-button",
                AdditionalData = new Dictionary<string, string>
                {
                    { "id", "submit_ImplementSection" },
                    { "name", "submit.ImplementSection" }
                }
            });
            model.UIElements.Add(new SeperatorUIElement());
            model.UIElements.Add(new SelectListUIElement
            {
                Alias = "Layout",
                Title = "Layout",
                CssClass = "layout-select-list",
                AdditionalData = new Dictionary<string, string>
                {
                    { "id", "select_Layout" },
                    { "name", "select.Layout" }
                }
            });

            // Setup data
            var parser = new TemplateParser();
            ViewBag.CurrentLayout = file != null ? parser.Parse(file).Layout : "";
            using (var uow = BackOfficeRequestContext.Application.Hive.OpenReader<IFileStore>(new Uri("storage://templates")))
            {
                //create the allowed templates check box list
                ViewBag.AvailableTemplates = new List<SelectListItem>(
                    uow.Repositories.GetAllNonContainerFiles()
                    .OrderBy(x => x.Name)
                    .Select(x =>
                        new SelectListItem
                        {
                            Text = x.GetFileNameForDisplay(),
                            Value = x.Name
                        })).ToArray();
            }
        }