/// <summary>
        /// Loads the configuration file
        /// </summary>
        /// <param name="testSuiteName">The name of the test suite.</param>
        /// <param name="testSuiteVersion">The version of test suite</param>
        /// <param name="testSuiteDir">The working directory for the test suite.</param>
        /// <param name="installDir">The install directory of PTM.</param>
        /// <returns>An instance of AppConfig class.</returns>
        public static AppConfig LoadConfig(string testSuiteName, string testSuiteVersion, string testSuiteDir, string installDir)
        {
            AppConfig config = new AppConfig();

            config.TestSuiteName    = testSuiteName;
            config.TestSuiteVersion = testSuiteVersion;
            config.InitFolders(testSuiteDir, installDir);
            config.PipeName = StringResource.PipeName;

            XmlDocument doc = new XmlDocument();

            doc.XmlResolver = null;
            XmlReaderSettings settings = new XmlReaderSettings();

            settings.XmlResolver   = null;
            settings.DtdProcessing = DtdProcessing.Prohibit;
            XmlReader xmlReader = XmlReader.Create(System.IO.Path.Combine(config.EtcDirectory, StringResource.ConfigFilename), settings);

            doc.Load(xmlReader);
            //Config File
            XmlNode ptfFileNamesNode = doc.DocumentElement.SelectSingleNode("PtfFileNames");

            config.PtfConfigFiles = new List <string>();
            List <string> PtfConfigFileNames = new List <string>();

            foreach (XmlNode xn in ptfFileNamesNode.SelectNodes("PtfFileName"))
            {
                PtfConfigFileNames.Add(xn.InnerText.Trim());
            }
            //Config file in source code
            XmlNode ConfigFilePathNode = doc.DocumentElement.SelectSingleNode("ConfigFilePath");

            config.PtfConfigFilesInSource = new List <string>();
            if (ConfigFilePathNode != null)
            {
                foreach (XmlNode xn in ConfigFilePathNode.SelectNodes("PtfFileName"))
                {
                    config.PtfConfigFilesInSource.Add(
                        Path.Combine(testSuiteDir, xn.InnerText.Trim()));
                }
            }
            // Group Order
            config.PropertyGroupOrder = null;
            XmlNode groupOrder = doc.DocumentElement.SelectSingleNode("PropertyGroupOrder");

            if (groupOrder != null)
            {
                config.PropertyGroupOrder = new Dictionary <string, int>();
                foreach (XmlNode xn in groupOrder.SelectNodes("PropertyGroup"))
                {
                    string name  = xn.Attributes["name"].Value;
                    int    order = int.Parse(xn.Attributes["order"].Value);
                    config.PropertyGroupOrder.Add(name, order);
                }
            }

            // Detector
            string detectorAssembly = doc.DocumentElement.SelectSingleNode("AutoDetectionDllName").InnerText.Trim();

            config.DetectorAssemblyPath = Path.Combine(installDir, "lib", detectorAssembly);
            //Config Case
            config.TestSuiteAssembly = new List <string>();
            XmlNode DllFileNamesNode = doc.DocumentElement.SelectSingleNode("DllFileNames");

            foreach (XmlNode xn in DllFileNamesNode.SelectNodes("DllFileName"))
            {
                string name = xn.InnerText.Trim();
                config.TestSuiteAssembly.Add(System.IO.Path.Combine(testSuiteDir, name));
            }

            //TestSetting
            config.TestSetting = doc.DocumentElement.SelectSingleNode("TestSetting").InnerText.Trim();

            //Config Test Engine
            string vspath;

            if (Environment.GetEnvironmentVariable("VS110COMNTOOLS") != null &&
                File.Exists(vspath = Path.Combine(Environment.GetEnvironmentVariable("VS110COMNTOOLS"), StringResource.VSTestLocation)))
            {
                config.VSTestPath = vspath;
            }
            else if (Environment.GetEnvironmentVariable("VS120COMNTOOLS") != null &&
                     File.Exists(vspath = Path.Combine(Environment.GetEnvironmentVariable("VS120COMNTOOLS"), StringResource.VSTestLocation)))
            {
                config.VSTestPath = vspath;
            }
            else if (Environment.GetEnvironmentVariable("VS140COMNTOOLS") != null &&
                     File.Exists(vspath = Path.Combine(Environment.GetEnvironmentVariable("VS140COMNTOOLS"), StringResource.VSTestLocation)))
            {
                config.VSTestPath = vspath;
            }
            else
            {
                throw new Exception(StringResource.VSTestNotInstalled);
            }
            config.VSTestArguments = "";
            foreach (string singleDllpath in config.TestSuiteAssembly)
            {
                config.VSTestArguments += " " + singleDllpath;
            }
            config.VSTestArguments += " /Settings:\"" + config.TestSetting + "\"";

            // TestCategories
            var testCategoryNode = doc.DocumentElement.SelectSingleNode("TestCategories");

            if (testCategoryNode != null)
            {
                string categoryConfigFile = System.IO.Path.Combine(config.EtcDirectory, testCategoryNode.InnerText.Trim());
                config.TestCategory = GetTestCategoryFromConfig(categoryConfigFile);
            }
            else
            {
                config.TestCategory = null;
            }

            //Welcome Page
            config.TestSuiteIntroduction = new List <string>();

            foreach (XmlNode xn in doc.DocumentElement.SelectNodes("WelcomePage"))
            {
                foreach (XmlNode paragraphNode in xn.SelectNodes("Paragraph"))
                {
                    config.TestSuiteIntroduction.Add(paragraphNode.InnerText.Trim());
                }
            }

            //User Guide
            config.UserGuide = System.IO.Path.Combine(config.DocDirectory, "index.html");

            for (int i = 0; i < PtfConfigFileNames.Count; i++)
            {
                config.PtfConfigFiles.Add(System.IO.Path.Combine(testSuiteDir, "Bin", PtfConfigFileNames[i]));
            }

            config.RuleDefinitions = doc.DocumentElement.SelectSingleNode("ConfigCaseRule");
            config.FeatureMapping  = doc.DocumentElement.SelectSingleNode("FeatureMapping");

            // Adapters
            config.AdapterDefinitions = doc.DocumentElement.SelectSingleNode("Adapters");
            config.PredefinedAdapters = new List <PtfAdapterView>();
            if (config.AdapterDefinitions != null)
            {
                foreach (XmlNode node in config.AdapterDefinitions)
                {
                    string         displayName = node.Attributes["displayname"].Value;
                    string         name        = node.Attributes["name"].Value;
                    PtfAdapterView adapterView = new PtfAdapterView()
                    {
                        Name         = name,
                        FriendlyName = displayName
                    };

                    foreach (XmlNode subnode in node.SelectNodes("Adapter"))
                    {
                        string type = subnode.Attributes["type"].Value;
                        switch (type)
                        {
                        case "powershell":
                        {
                            string scriptDir = subnode.Attributes["scriptdir"].Value;
                            adapterView.PowerShellAdapter = new PowerShellAdapterNode(name, displayName, scriptDir);
                        }
                        break;

                        case "interactive":
                            adapterView.InteractiveAdapter = new InteractiveAdapterNode(name, displayName);
                            break;

                        case "managed":
                        {
                            string adapterType = subnode.Attributes["adaptertype"].Value;
                            adapterView.ManagedAdapter = new ManagedAdapterNode(name, displayName, adapterType);
                        }
                        break;

                        case "script":
                        {
                            string scriptDir = subnode.Attributes["scriptdir"].Value;
                            adapterView.ScriptAdapter = new ScriptAdapterNode(name, displayName, scriptDir);
                        }
                        break;
                        }
                    }
                    config.PredefinedAdapters.Add(adapterView);
                }
            }
            return(config);
        }
        /// <summary>
        /// Loads the configuration file
        /// </summary>
        /// <param name="testSuiteName">The name of the test suite.</param>
        /// <param name="testSuiteVersion">The version of test suite</param>
        /// <param name="testSuiteDir">The working directory for the test suite.</param>
        /// <param name="installDir">The install directory of PTM.</param>
        /// <returns>An instance of AppConfig class.</returns>
        public static AppConfig LoadConfig(string testSuiteName, string testSuiteVersion, string testSuiteDir, string installDir)
        {
            AppConfig config = new AppConfig();
            config.TestSuiteName = testSuiteName;
            config.TestSuiteVersion = testSuiteVersion;
            config.InitFolders(testSuiteDir, installDir);

            XmlDocument doc = new XmlDocument();
            doc.XmlResolver = null;
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.XmlResolver = null;
            settings.DtdProcessing = DtdProcessing.Prohibit;
            XmlReader xmlReader = XmlReader.Create(System.IO.Path.Combine(config.EtcDirectory, StringResource.ConfigFilename), settings);
            doc.Load(xmlReader);
            //Config File
            XmlNode ptfFileNamesNode = doc.DocumentElement.SelectSingleNode("PtfFileNames");
            config.PtfConfigFiles = new List<string>();
            List<string> PtfConfigFileNames = new List<string>();
            foreach (XmlNode xn in ptfFileNamesNode.SelectNodes("PtfFileName"))
            {
                PtfConfigFileNames.Add(xn.InnerText.Trim());
            }
            //Config file in source code
            XmlNode ConfigFilePathNode = doc.DocumentElement.SelectSingleNode("ConfigFilePath");
            config.PtfConfigFilesInSource = new List<string>();
            if (ConfigFilePathNode != null)
            {
                foreach (XmlNode xn in ConfigFilePathNode.SelectNodes("PtfFileName"))
                {
                    config.PtfConfigFilesInSource.Add(
                        Path.Combine(testSuiteDir, xn.InnerText.Trim()));
                }
            }
            // Group Order
            config.PropertyGroupOrder = null;
            XmlNode groupOrder = doc.DocumentElement.SelectSingleNode("PropertyGroupOrder");
            if (groupOrder != null)
            {
                config.PropertyGroupOrder = new Dictionary<string, int>();
                foreach (XmlNode xn in groupOrder.SelectNodes("PropertyGroup"))
                {
                    string name = xn.Attributes["name"].Value;
                    int order = int.Parse(xn.Attributes["order"].Value);
                    config.PropertyGroupOrder.Add(name, order);
                }
            }

            // Detector
            string detectorAssembly = doc.DocumentElement.SelectSingleNode("AutoDetectionDllName").InnerText.Trim();

            config.DetectorAssemblyPath = Path.Combine(installDir, "lib", detectorAssembly);
            //Config Case
            config.TestSuiteAssembly = new List<string>();
            XmlNode DllFileNamesNode = doc.DocumentElement.SelectSingleNode("DllFileNames");
            foreach (XmlNode xn in DllFileNamesNode.SelectNodes("DllFileName"))
            {
                string name = xn.InnerText.Trim();
                config.TestSuiteAssembly.Add(System.IO.Path.Combine(testSuiteDir, name));
            }

            //TestSetting
            config.TestSetting = doc.DocumentElement.SelectSingleNode("TestSetting").InnerText.Trim();

            //Config Test Engine
            string vspath;
            if (Environment.GetEnvironmentVariable("VS110COMNTOOLS") != null &&
                File.Exists(vspath = Path.Combine(Environment.GetEnvironmentVariable("VS110COMNTOOLS"), StringResource.VSTestLocation)))
            {
                config.VSTestPath = vspath;
            }
            else if (Environment.GetEnvironmentVariable("VS120COMNTOOLS") != null &&
                File.Exists(vspath = Path.Combine(Environment.GetEnvironmentVariable("VS120COMNTOOLS"), StringResource.VSTestLocation)))
            {
                config.VSTestPath = vspath;
            }
            else if (Environment.GetEnvironmentVariable("VS140COMNTOOLS") != null &&
                File.Exists(vspath = Path.Combine(Environment.GetEnvironmentVariable("VS140COMNTOOLS"), StringResource.VSTestLocation)))
            {
                config.VSTestPath = vspath;
            }
            else
            {
                throw new Exception(StringResource.VSTestNotInstalled);
            }
            config.VSTestArguments = "";
            foreach (string singleDllpath in config.TestSuiteAssembly)
            {
                config.VSTestArguments += " " + singleDllpath;
            }
            config.VSTestArguments += " /Settings:\"" + config.TestSetting + "\"";

            // TestCategories
            var testCategoryNode = doc.DocumentElement.SelectSingleNode("TestCategories");
            if (testCategoryNode != null)
            {
                string categoryConfigFile = System.IO.Path.Combine(config.EtcDirectory, testCategoryNode.InnerText.Trim());
                config.TestCategory = GetTestCategoryFromConfig(categoryConfigFile);
            }
            else
            {
                config.TestCategory = null;
            }

            //Welcome Page
            config.TestSuiteIntroduction = new List<string>();

            foreach (XmlNode xn in doc.DocumentElement.SelectNodes("WelcomePage"))
            {
                foreach (XmlNode paragraphNode in xn.SelectNodes("Paragraph"))
                {
                    config.TestSuiteIntroduction.Add(paragraphNode.InnerText.Trim());
                }
            }

            //User Guide
            config.UserGuide = System.IO.Path.Combine(config.DocDirectory, "index.html");

            for (int i = 0; i < PtfConfigFileNames.Count; i++)
            {
                config.PtfConfigFiles.Add(System.IO.Path.Combine(testSuiteDir, "Bin", PtfConfigFileNames[i]));
            }

            config.RuleDefinitions = doc.DocumentElement.SelectSingleNode("ConfigCaseRule");

            // Adapters
            config.AdapterDefinitions = doc.DocumentElement.SelectSingleNode("Adapters");
            config.PredefinedAdapters = new List<PtfAdapterView>();
            if (config.AdapterDefinitions != null)
            {
                foreach (XmlNode node in config.AdapterDefinitions)
                {
                    string displayName = node.Attributes["displayname"].Value;
                    string name = node.Attributes["name"].Value;
                    PtfAdapterView adapterView = new PtfAdapterView()
                    {
                        Name = name,
                        FriendlyName = displayName
                    };

                    foreach (XmlNode subnode in node.SelectNodes("Adapter"))
                    {
                        string type = subnode.Attributes["type"].Value;
                        switch (type)
                        {
                            case "powershell":
                                {
                                    string scriptDir = subnode.Attributes["scriptdir"].Value;
                                    adapterView.PowerShellAdapter = new PowerShellAdapterNode(name, displayName, scriptDir);
                                }
                                break;
                            case "interactive":
                                adapterView.InteractiveAdapter = new InteractiveAdapterNode(name, displayName);
                                break;
                            case "managed":
                                {
                                    string adapterType = subnode.Attributes["adaptertype"].Value;
                                    adapterView.ManagedAdapter = new ManagedAdapterNode(name, displayName, adapterType);
                                }
                                break;
                            case "script":
                                {
                                    string scriptDir = subnode.Attributes["scriptdir"].Value;
                                    adapterView.ScriptAdapter = new ScriptAdapterNode(name, displayName, scriptDir);
                                }
                                break;
                        }
                    }
                    config.PredefinedAdapters.Add(adapterView);
                }
            }
            return config;
        }