private Solution CreateSolution(SolutionDocument document)
        {
            var solution = new Solution()
            {
                Version = document.FileVersion,
                VisualStudioVersion = document.VisualStudioVersion
            };

            if (document.Info.Any())
            {
                solution.Headers = new List<NameValue>();
                foreach (var info in document.Info)
                    solution.Headers.Add(new NameValue { Name = info.Key, Value = info.Value });
            }

            var ignored = new[] { "ProjectConfigurationPlatforms", "NestedProjects" };

            foreach (var globalSection in document.GlobalSections.Where(p => !ignored.Contains(p.Name)))
            {
                if (!globalSection.Info.Any())
                    continue;

                var sectionItem = new NameValueItem { Name = globalSection.Name, When = globalSection.When };

                foreach (var item in globalSection.Info)
                    sectionItem.AddItem(item.Key, item.Value);

                solution.Sections.Add(sectionItem);
            }
            
            return solution;
        }
        private void OutputNestedProjects(Solution solution, StringBuilder output)
        {
            var pairs = new List<Tuple<SolutionItem, SolutionItem>>();
            AddPairs(pairs, solution.Items);

            if (!pairs.Any())
                return;

            output.AppendLine("\tGlobalSection(NestedProjects) = preSolution");
            foreach (var pair in pairs.Where(p => p.Item2.Id != null))
            {
                output.AppendFormat("\t\t{0} = {1}\n", pair.Item1.Id, pair.Item2.Id);
            }
            output.AppendLine("\tEndGlobalSection");
        }
        private void OutputProjectsConfigurations(Solution solution, StringBuilder output)
        {
            var projects = solution.Items.Folders
                .Recurse(p => p.Folders)
                .SelectMany(f => f.Projects)
                .Union(solution.Items.Projects)
                .ToList();

            if (!projects.Any())
                return;

            output.AppendLine("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution");
            foreach (SolutionProject project in projects)
            {
                foreach (var config in project.Configuration.Items)
                {
                    output.AppendFormat("\t\t{0}.{1} = {2}\n", project.Id, config.Name, config.Value);
                }
            }
            output.AppendLine("\tEndGlobalSection");
        }
        private string GetSectionsOutput(Solution solution)
        {
            var output = new StringBuilder();

            output.AppendLine("Global");

            foreach (var item in solution.Sections)
            {
                output.AppendFormat("\tGlobalSection({0}) = {1}\n", item.Name, item.When);
                foreach (NameValue configuration in item.Items)
                {
                    output.AppendFormat("\t\t{0} = {1}\n", configuration.Name, configuration.Value);
                }
                output.AppendLine("\tEndGlobalSection");
            }

            OutputNestedProjects(solution, output);
            OutputProjectsConfigurations(solution, output);

            output.Append("EndGlobal");

            return output.ToString();
        }
        public void WriteDocument(string path, string outputName)
        {
            var xml = File.ReadAllText(path);
            _document = xml.FromXml<Solution>();

            var lines = new List<string>();

            lines.Add(String.Format("Microsoft Visual Studio Solution File, Format Version {0}", _document.Version));
            lines.Add(String.Format("# {0}", _document.VisualStudioVersion));
            if (_document.Headers != null)
                lines.AddRange(_document.Headers.Select(h => String.Format("{0} = {1}", h.Name, h.Value)));

            var all = _document.Items.Folders.Recurse(si => si.Folders).ToList();
            var items = _document.Items.Projects.Union(all.SelectMany(a => a.Projects)).OfType<SolutionItem>().ToList();

            lines.AddRange(items.Union(all).Select(f => GetProjectsOutput(f)));

            lines.Add(GetSectionsOutput(_document));

            File.WriteAllLines(outputName, lines.ToArray());
        }