private List<CsProjConfigElement> GetProjConfigElementList(ProjectConfigList replacementValues)
        {
            var projXmlDocument = new XmlDocument();
            var xmlNodeList = GetXmlNodeList(_filename, projXmlDocument);

            if (xmlNodeList == null)
            {
                return null;
            }

            var returnValue = xmlNodeList.Cast<XmlNode>()
                .Select(node => CsProjConfigElement.ParseOuterElement(node.OuterXml, this._filename, replacementValues))
                .Where(parseResult => parseResult != null)
                .ToList();

            return returnValue;
            //XDocument xDocument
            //CsProjConfigElement.ParseOuterElement()
        }
        public ProjectConfigList ConvertToBindable()
        {
            var returnValue = new ProjectConfigList();
            returnValue.AddRange(
                this.PropertyGroups.Select(element =>
                    {
                        bool? allowUnsafeBlocks = null;
                        if (element.AllowUnsafeBlocks.IsValueExplicitlySet)
                        {
                            bool allowUnsafeBlocksTmp;
                            allowUnsafeBlocks = bool.TryParse(element.AllowUnsafeBlocks.Value, out allowUnsafeBlocksTmp) ? allowUnsafeBlocksTmp : (bool?)null;
                        }

                        bool? optimize = null;
                        if (element.Optimize.IsValueExplicitlySet)
                        {
                            bool optimizeTmp;
                            optimize = bool.TryParse(element.Optimize.Value, out optimizeTmp) ? optimizeTmp : (bool?)null;
                        }

                        var fileInfo = new FileInfo(element.ProjectFilename);
                        return new ProjectConfig
                               {
                                   ProjectName = fileInfo.Name,
                                   ConfigurationName = element.ConfigurationName,
                                   PlatformName = element.PlatformName,
                                   AllowUnsafeBlocks = allowUnsafeBlocks,
                                   Optimize = optimize,
                                   DebugType = element.DebugType.IsValueExplicitlySet ? element.DebugType.Value : null,
                                   DebugSymbols = element.DebugSymbols.IsValueExplicitlySet ? element.DebugSymbols.Value : null,
                                   DefineConstants = element.DefineConstants.IsValueExplicitlySet ? element.DefineConstants.Value : null,
                                   OutputPath = element.OutputPath.IsValueExplicitlySet ? element.OutputPath.Value : null,
                                   PlatformTarget = element.PlatformTarget.IsValueExplicitlySet ? element.PlatformTarget.Value : null,
                                   ProjectFullFilename = element.ProjectFilename,
                                   Build = true
                               };
                    }));

            return returnValue;
        }
        private void tsmnuOpen_Click(object sender, EventArgs e)
        {
            using (var dialog = new OpenFileDialog())
            {
                dialog.Filter = "(*.sln;*.csproj)|*.sln;*.csproj";

                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    tstrProgressBar.Style = ProgressBarStyle.Marquee;
                    tstrProgressBar.MarqueeAnimationSpeed = 40;
                    tstrProgressBar.Enabled = true;
                    tstrProgressBar.Visible = true;

                    Task.Factory.StartNew(() => FileHelper.LoadFile(dialog.FileName)).ContinueWith(task =>
                        {
                            Thread.Sleep(400);

                            Action invokeGrid = () =>
                                {
                                    _projectConfigList = task.Result;
                                    projectConfigDataGridView1.DataSource = _projectConfigList;

                                    cboConfigurations.DataSource = task.Result.UniqueConfigurations;
                                    cboProjects.DataSource = task.Result.UniqueProjects;
                                    cboPlatforms.DataSource = task.Result.UniquePlatforms;

                                    Console.WriteLine(DateTime.Now.Ticks);

                                    projectConfigDataGridView1.AutoResizeColumn(0, DataGridViewAutoSizeColumnMode.DisplayedCells);
                                    projectConfigDataGridView1.AutoResizeColumn(1, DataGridViewAutoSizeColumnMode.DisplayedCells);
                                    projectConfigDataGridView1.AutoResizeColumn(2, DataGridViewAutoSizeColumnMode.DisplayedCells);

                                    Console.WriteLine(DateTime.Now.Ticks);

                                    tsmnuSave.Enabled = true;

                                    tstrProgressBar.Visible = false;
                                    tstrProgressBar.Enabled = false;
                                    tstrProgressBar.Style = ProgressBarStyle.Continuous;
                                    tstrProgressBar.MarqueeAnimationSpeed = 0;
                                };

                            if (projectConfigDataGridView1.InvokeRequired)
                            {
                                projectConfigDataGridView1.BeginInvoke(new MethodInvoker(invokeGrid));
                            }
                            else
                            {
                                invokeGrid();
                            }
                        });
                }
            }
        }
        public void Save(string oldFilename, string newFilename, ProjectConfigList projectConfigList)
        {
            var backupPath = Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
                "AdvancedProjectConfig\\Backups",
                DateTime.Now.ToString("s").Replace(":", "_"));

            if (!Directory.Exists(backupPath))
            {
                Directory.CreateDirectory(backupPath);
            }

            ForEachProjectInSolution(oldFilename, x => CsProjFile.SaveCsProjFile(x, backupPath, projectConfigList));
        }
        public static CsProjConfigElement ParseOuterElement(string outerXml, string filename, ProjectConfigList replacementValues = null, bool throwWhenMissing = false)
        {
            XDocument xmlFragment = XDocument.Parse(outerXml);

            var outerElement = xmlFragment.Elements().FirstOrDefault();
            if (outerElement == null)
            {
                if (throwWhenMissing)
                {
                    throw new Exception("outerElement is empty");
                }

                return null;
            }

            var conditionAttribute = outerElement.Attribute("Condition");
            if (conditionAttribute == null)
            {
                if (throwWhenMissing)
                {
                    throw new Exception("conditionAttribute is missing");
                }

                return null;
            }

            string condition = outerElement.Value;

            if (string.IsNullOrEmpty(condition))
            {
                return null;
            }

            Match conditionAttrMatch = Regex.Match(conditionAttribute.Value, ProjectConfigList.ConditionAttrRegexMatch);
            if (conditionAttrMatch.Groups.Count > 1)
            {
                string configuration = conditionAttrMatch.Groups[1].Value;
                string platform = conditionAttrMatch.Groups[2].Value;

                ProjectConfig replaceWithValues = null;

                if (replacementValues != null)
                {
                    var filteredReplacementValues = replacementValues.Where(x => 
                        x.ProjectFullFilename.Equals(filename, StringComparison.InvariantCultureIgnoreCase) &&
                        x.PlatformName.Equals(platform, StringComparison.InvariantCultureIgnoreCase) &&
                        x.ConfigurationName.Equals(configuration, StringComparison.InvariantCultureIgnoreCase));

                    var projectConfigs = filteredReplacementValues as ProjectConfig[] ?? filteredReplacementValues.ToArray();
                    if (projectConfigs.Any())
                    {
                        replaceWithValues = projectConfigs.First();
                    }
                }

                var returnValue = new CsProjConfigElement
                    {
                        ProjectFilename                     = filename,
                        ConfigurationName                   = configuration,
                        PlatformName                        = platform,
                        PlatformTarget                      = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("PlatformTarget", StringComparison.CurrentCultureIgnoreCase))),
                        DebugType                           = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("DebugType", StringComparison.CurrentCultureIgnoreCase))),
                        Optimize                            = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("Optimize", StringComparison.CurrentCultureIgnoreCase))),
                        OutputPath                          = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("OutputPath", StringComparison.CurrentCultureIgnoreCase))),
                        DefineConstants                     = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("DefineConstants", StringComparison.CurrentCultureIgnoreCase))),
                        ErrorReport                         = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("ErrorReport", StringComparison.CurrentCultureIgnoreCase))),
                        DebugSymbols                        = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("DebugSymbols", StringComparison.CurrentCultureIgnoreCase))),
                        WarningLevel                        = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("WarningLevel", StringComparison.CurrentCultureIgnoreCase))),
                        TreatWarningsAsErrors               = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("TreatWarningsAsErrors", StringComparison.CurrentCultureIgnoreCase))),
                        DocumentationFile                   = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("DocumentationFile", StringComparison.CurrentCultureIgnoreCase))),
                        GenerateSerializationAssemblies     = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("GenerateSerializationAssemblies", StringComparison.CurrentCultureIgnoreCase))),
                        LangVersion                         = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("LangVersion", StringComparison.CurrentCultureIgnoreCase))),
                        CheckForOverflowUnderflow           = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("CheckForOverflowUnderflow", StringComparison.CurrentCultureIgnoreCase))),
                        FileAlignment                       = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("FileAlignment", StringComparison.CurrentCultureIgnoreCase))),
                        WarningsAsErrors                    = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("WarningsAsErrors", StringComparison.CurrentCultureIgnoreCase))),
                        AllowUnsafeBlocks                   = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("AllowUnsafeBlocks", StringComparison.CurrentCultureIgnoreCase))),
                        NoWarn                              = new CsProjPropertyValue(outerElement.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("NoWarn", StringComparison.CurrentCultureIgnoreCase)))
                    };

                return returnValue;
            }

            return null;
        }
        public static void SaveCsProjFile(string filename, string backupPath, ProjectConfigList project)
        {
            var projXmlDocument = new XmlDocument();
            var xmlNodeList = GetXmlNodeList(filename, projXmlDocument);
            bool changed = false;

            for (int i = xmlNodeList.Count - 1; i >= 0; i--)
            {
                XmlNode node = xmlNodeList[i];
                if (node == null || node.Attributes == null || node.Attributes["Condition"] == null)
                {
                    continue;
                }

                var conditionAttribute = node.Attributes["Condition"];
                var conditionAttrMatch = Regex.Match(conditionAttribute.Value, ProjectConfigList.ConditionAttrRegexMatch);
                if (conditionAttrMatch.Groups.Count <= 1)
                {
                    continue;
                }

                string configuration = conditionAttrMatch.Groups[1].Value;
                string platform = conditionAttrMatch.Groups[2].Value;

                var filteredProjects = project.Where(x =>
                        x.ConfigurationName.Trim().Equals(configuration.Trim(), StringComparison.InvariantCultureIgnoreCase) &&
                        x.PlatformName.Equals(platform, StringComparison.InvariantCultureIgnoreCase) &&
                        x.ProjectFullFilename.Equals(filename, StringComparison.InvariantCultureIgnoreCase));

                foreach (var proj in filteredProjects)
                {
                    if (proj.IsDeleted)
                    {
                        if (node.ParentNode != null)
                        {
                            node.ParentNode.RemoveChild(node);
                        }

                        changed = true;
                    }
                    else
                    {
                        foreach (var field in _fields)
                        {
                            bool found = false;
                            object newValueObj = proj.GetType().GetProperty(field).GetValue(proj, null);
                            if (newValueObj == null)
                            {
                                continue;
                            }

                            string newValue = newValueObj.ToString();
                            if (newValueObj is bool)
                            {
                                newValue = newValue.ToLower();
                            }

                            foreach (XmlNode childNode in node.ChildNodes)
                            {
                                if (field.Trim().Equals(childNode.LocalName.Trim(), StringComparison.InvariantCultureIgnoreCase))
                                {
                                    found = true;
                                    if (childNode.InnerText != newValue)
                                    {
                                        childNode.InnerText = newValue;
                                        changed = true;
                                    }
                                    break;
                                }
                            }

                            if (!found && !string.IsNullOrWhiteSpace(newValue))
                            {
                                XmlElement element = projXmlDocument.CreateElement(field, "http://schemas.microsoft.com/developer/msbuild/2003");
                                element.InnerText = newValue;
                                node.AppendChild(element);
                                changed = true;
                            }
                        }
                    }
                }
            }

            if (changed)
            {
                var fileInfo = new FileInfo(filename);
                var backupFilePath = Path.Combine(backupPath, fileInfo.Name);
                int i = 1;
                while (File.Exists(backupFilePath))
                {
                    string newFile = Path.GetFileNameWithoutExtension(fileInfo.Name) + "_" + i;
                    if (!string.IsNullOrEmpty(fileInfo.Extension))
                    {
                        newFile += fileInfo.Extension;
                    }

                    backupFilePath = Path.Combine(backupPath, newFile);

                    i++;
                }

                File.Copy(filename, backupFilePath, true);

                projXmlDocument.Save(filename);
            }
        }
        public static void SaveFile(string originalFilename, string newFilename, ProjectConfigList projectConfigList)
        {
            projectConfigList.Save(originalFilename, newFilename);

            CurrentFilename = newFilename;

            //CurrentProjectFiles.ForEach(x => x.);

            //CurrentProjectFiles.ForEach(x =>
            //    {

            //    });


            //switch (CurrentFileType)
            //{
            //    case FileTypes.CsProj:

            //        break;

            //    case FileTypes.Sln:
            //        break;

            //    default:
            //        throw new FileLoadException("Filename is incorrect");
            //}
        }