public static string InstallMSI(SetupConfig setupConfig, string msiFilePath, bool useAddLocal, bool useParameters)
        {
            if (setupConfig == null)
            {
                throw new ArgumentNullException("setupConfig");
            }

            var parameter = string.Empty;
            if (useAddLocal)
            {
                parameter += "ADDLOCAL=";
                parameter = setupConfig.ComponentList.Where(feature => feature.Installed).Aggregate(parameter, (current, feature) => current + (feature.Id + ","));
                parameter = parameter.TrimEnd(',');
            }

            if (useParameters)
            {
                parameter = setupConfig.ParameterList.Aggregate(parameter, (current, parm) => current + (" " + parm.Id + "=\"" + parm.Value + "\""));
            }

            parameter = parameter.TrimStart(' ');

            var logFile = Path.GetTempFileName();
            ApplicationTool.InstallMSI(msiFilePath, new TimeSpan(0, timeoutMinutes, 0), parameter, logFile);
            return logFile;
        }
        private static Collection<Parameter> GetParameters(SetupConfig setupConfig)
        {
            var parameters = new Collection<Parameter>();
            foreach (var baseData in setupConfig.ParameterList)
            {
                var configParameter = baseData;
                var param = new Parameter
                {
                    Id = configParameter.Id,
                    Value = configParameter.Value
                };
                parameters.Add(param);
            }

            return parameters;
        }
        private static Collection<BaseTestData> CollectTestDataFromInstallChainerComponents(SetupConfig setupConfig, ICollection<InstallChainerComponent> components)
        {
            if (setupConfig == null)
            {
                throw new InstallerVerificationLibraryException("setupConfiguration can't be null");
            }

            var testDataCollection = new Collection<BaseTestData>();

            foreach (var setupConfigcomponentData in setupConfig.ComponentList)
            {
                InstallChainerComponent component;

                try
                {
                    component = components.SingleOrDefault(x => x.Id == setupConfigcomponentData.Id);
                }
                catch (Exception)
                {
                    throw new InstallerVerificationLibraryException("Multiple components with name '" + setupConfigcomponentData.Id + "' found. Component name need to be uniqe.");
                }

                if (component == null)
                {
                    throw new InstallerVerificationLibraryException("Could not find data for component '" + setupConfigcomponentData.Id + "'. This could be because miss spelling of component name.");
                }

                if (component.TestData.Count == 0)
                {
                    throw new InstallerVerificationLibraryException("Component '" + setupConfigcomponentData.Id + "' doesn't have any testdata data. This could be because miss spelling of component name.");
                }

                if (!setupConfigcomponentData.Installed)
                {
                    continue;
                }

                foreach (var data in component.TestData)
                {
                    if (setupConfig.TypeOfInstallation == TypeOfInstallation.Install ||
                        setupConfig.TypeOfInstallation == TypeOfInstallation.Repair)
                    {
                        AddTestData(true, data, testDataCollection);
                    }
                    else if (setupConfig.TypeOfInstallation == TypeOfInstallation.UnInstall)
                    {
                        AddTestData(false, data, testDataCollection);
                    }
                }
            }

            return testDataCollection;
        }
        private static Collection<BaseTestData> CollectTestDataFromFeatures(SetupConfig setupConfig, ICollection<Feature> features)
        {
            if (setupConfig == null)
            {
                throw new InstallerVerificationLibraryException("setupConfiguration can't be null");
            }

            var testDataCollection = new Collection<BaseTestData>();

            foreach (var setupConfigcomponentData in setupConfig.ComponentList)
            {
                Feature feature;

                try
                {
                    feature = features.SingleOrDefault(x => x.FeatureName == setupConfigcomponentData.Id);
                }
                catch (Exception)
                {
                    throw new InstallerVerificationLibraryException("Multiple features with name '" + setupConfigcomponentData.Id + "' found. Feature name need to be uniqe.");
                }

                if (feature == null)
                {
                    throw new InstallerVerificationLibraryException("Could not find data for feature '" + setupConfigcomponentData.Id + "'. This could be because miss spelling of feature name.");
                }

                if (feature.FeatureData.Count == 0)
                {
                    throw new InstallerVerificationLibraryException("Feature '" + feature.FeatureName + "' doesn't have any feature data. This could be because miss spelling of feature name.");
                }

                if (!setupConfigcomponentData.Installed)
                {
                    continue;
                }

                foreach (var data in feature.FeatureData)
                {
                    data.ComponentID = feature.FeatureName;
                    if (setupConfig.TypeOfInstallation == TypeOfInstallation.Install ||
                        setupConfig.TypeOfInstallation == TypeOfInstallation.Repair)
                    {
                        AddTestData(true, data, testDataCollection);
                    }
                    else if (setupConfig.TypeOfInstallation == TypeOfInstallation.UnInstall)
                    {
                        AddTestData(false, data, testDataCollection);
                    }
                }
            }

            return testDataCollection;
        }
        public static void ResolveSetupConfigParameters(string filePathToConfigurationData, SetupConfig setupConfig)
        {
            filePathToConfigurationData = CheckFilePath(filePathToConfigurationData);

            var xdoc = XElement.Load(filePathToConfigurationData);
            ResolveIncludes(filePathToConfigurationData, xdoc, 1);

            var properties = LoadProperties(xdoc, filePathToConfigurationData, GetParameters(setupConfig));

            foreach (var setupConfigParameterData in setupConfig.ParameterList)
            {
                setupConfigParameterData.Value = DataPropertyTool.ResolvePropertiesInString(properties, setupConfigParameterData.Value);
            }
        }
        public static Collection<BaseTestData> LoadTestDataFromFile(string filePathToConfigurationData, SetupConfig setupConfig)
        {
            filePathToConfigurationData = CheckFilePath(filePathToConfigurationData);
            var parameters = GetParameters(setupConfig);

            var xdoc = XElement.Load(filePathToConfigurationData);
            ResolveIncludes(filePathToConfigurationData, xdoc, 1);

            var properties = LoadProperties(xdoc, filePathToConfigurationData, parameters);
            var msifiles = LoadMsiFileData(xdoc, filePathToConfigurationData);
            var plugins = LoadPlugins(xdoc, filePathToConfigurationData);

            switch (xdoc.Name.LocalName.ToLowerInvariant())
            {
                case "msi":
                    var features = new Collection<Feature>();
                    foreach (var feature in LoadFeatureDataFromXmlNode(xdoc, properties, null, msifiles, plugins))
                    {
                        features.Add(feature);
                    }

                    return CollectTestDataFromFeatures(setupConfig, features);
                case "installchainer":
                    var components = LoadInstallChainerComponentData(xdoc, filePathToConfigurationData, msifiles, plugins, properties);
                    return CollectTestDataFromInstallChainerComponents(setupConfig, components);
            }

            return new Collection<BaseTestData>();
        }