private static IEnumerable<Sitecore.Data.ID> GetAllMappedTemplateIds(TemplateInSet templateInSet)
 {
     List<Sitecore.Data.ID> result = new List<Sitecore.Data.ID>();
     if (templateInSet != null)
     {
         result.Add(templateInSet.TemplateItem.ID);
         result.AddRange(GetAllMappedTemplateIds(templateInSet.BaseTemplateInSet));
     }
     return result;
 }
        private static void Determine(IEnumerable<TemplateInSet> allTemplatesInSets, List<TemplateInSet> mappedTemplates, IDictionary<TemplateInSet,IEnumerable<Sitecore.Data.ID>> mappings, TemplateInSet templateInSet)
        {
            IEnumerable<Sitecore.Data.ID> allTemplateIds = allTemplatesInSets.Select(template => template.TemplateItem.ID);

            // Get all mapped templates that are directly beneath the passed in templateInSet
            List<TemplateInSet> newMappedTemplates = (from template in allTemplatesInSets.Except(mappedTemplates)
                                                      where mappings[template].Intersect(allTemplateIds.Except(GetAllMappedTemplateIds(templateInSet))).Count() == 0
                                                     select template).ToList();
            mappedTemplates.AddRange(newMappedTemplates);
            foreach (TemplateInSet newNewMappedTemplate in newMappedTemplates)
            {
                newNewMappedTemplate.BaseTemplateInSet = templateInSet;

                // Recursively determine the next layer directly beneath
                Determine(allTemplatesInSets, mappedTemplates, mappings, newNewMappedTemplate);
            }
        }