protected override Dictionary <string, string> Validate(Dictionary <string, object> inputValues)
        {
            if (inputValues.ContainsKey(ApplicationIDKey))
            {
                SetAccountWizardSettingsByApllicationID(Convert.ToInt32(inputValues[ApplicationIDKey]));
            }
            Dictionary <string, string>     errors      = null;
            Dictionary <string, string>     measures    = new Dictionary <string, string>();
            Dictionary <string, Replacment> allReplaces = new Dictionary <string, Replacment>();
            string pattern;

            foreach (KeyValuePair <string, object> input in inputValues)
            {
                try
                {
                    switch (input.Key)
                    {
                    case "AccountSettings.CubeName":     //same as cube id
                    {
                        pattern = @"\W";
                        if (Regex.IsMatch(input.Value.ToString(), pattern))
                        {
                            if (errors == null)
                            {
                                errors = new Dictionary <string, string>();
                            }
                            errors.Add(input.Key, string.Format(@"The ScopeName\CubeName\CubeID: ""{0}"" contains non alphnumeric charechter", input.Value.ToString()));
                        }


                        break;
                    }

                    case "AccountSettings.CreateMeasure":
                    {
                        if (Convert.ToBoolean(input.Value) == true)
                        {
                            if (!inputValues.ContainsKey("AccountSettings.MeasureAccountID") || inputValues["AccountSettings.MeasureAccountID"] == null || inputValues["AccountSettings.MeasureAccountID"].ToString() == string.Empty)
                            {
                                if (errors == null)
                                {
                                    errors = new Dictionary <string, string>();
                                }
                                errors.Add(input.Key, "If Create measure is checked then measure account ID must be supplied!");
                            }
                        }
                        break;
                    }

                    case "AccountSettings.BI_Scope_ID":
                    {
                        int i = 0;
                        if (!int.TryParse(input.Value.ToString(), out i))
                        {
                            if (errors == null)
                            {
                                errors = new Dictionary <string, string>();
                            }
                            errors.Add(input.Key, string.Format(@"Scope Id must be int", input.Value.ToString()));
                        }
                        break;
                    }

                    case "AccountSettings.AddContentCube":
                    case "AccountSettings.ProcessCubes":
                    case "AccountSettings.CubeID":
                    case "AccountSettings.BI_Scope_Name":
                    case "AccountSettings.MeasureAccountID":
                    case ApplicationIDKey:
                    {
                        break;
                    }

                    case "AccountSettings.TargetValue1":
                    case "AccountSettings.TargetValue2":
                    {
                        double temp;
                        if (!inputValues.ContainsKey("AccountSettings.MeasureAccountID") || string.IsNullOrEmpty(inputValues["AccountSettings.MeasureAccountID"].ToString()))
                        {
                            if (errors == null)
                            {
                                errors = new Dictionary <string, string>();
                            }
                            errors.Add(input.Key, "if you typed target cpa you must type an account ID");
                        }
                        if (!double.TryParse(input.Value.ToString(), out temp))
                        {
                            if (!string.IsNullOrEmpty(input.Value.ToString()))
                            {
                                if (errors == null)
                                {
                                    errors = new Dictionary <string, string>();
                                }
                                errors.Add(input.Key, "AccountSettings.TargetValue1 CPA MUST BE NUMERIC!");
                            }
                        }

                        break;
                    }

                    default:     //all replacements
                    {
                        Replacment replacment = (Replacment)input.Value;

                        if (replacment.CalcMembersOnly == false)
                        {
                            if (measures.ContainsKey(replacment.ReplaceTo))
                            {
                                if (errors == null)
                                {
                                    errors = new Dictionary <string, string>();
                                }
                                errors.Add(input.Key, string.Format("You are trying to change two measure name to the same name:{0}", replacment.ReplaceTo));
                            }
                            else
                            {
                                measures.Add(replacment.ReplaceTo, replacment.ReplaceTo);
                            }



                            if (IsMeasureNameExists(replacment.ReplaceTo))
                            {
                                if (errors == null)
                                {
                                    errors = new Dictionary <string, string>();
                                }
                                errors.Add(input.Key, string.Format(" Measure Name or calc name: {0} already exists in the cube", replacment.ReplaceTo));
                            }
                        }



                        allReplaces.Add(replacment.ReplaceFrom, replacment);

                        break;
                    }
                    }
                }
                catch (Exception ex)
                {
                    if (errors == null)
                    {
                        errors = new Dictionary <string, string>();
                    }
                    errors.Add(input.Key, ex.Message);
                }
            }

            foreach (string key in allReplaces.Keys)
            {
                string replaceValue     = allReplaces[key].ReplaceTo;
                int    sameValueCounted = 0;
                foreach (Replacment val in allReplaces.Values)
                {
                    if (key == val.ReplaceTo) //trying to changed value to a changed value
                    {
                        if (errors == null)
                        {
                            errors = new Dictionary <string, string>();
                        }
                        errors.Add(key, string.Format("You have already changed the key {0} to {1} , you can not used it again.", key, replaceValue));
                    }
                    if (replaceValue == val.ReplaceTo)
                    {
                        if (val.CalcMembersOnly == false)
                        {
                            sameValueCounted += 1;
                        }
                    }
                }
                if (sameValueCounted > 1)
                {
                    if (errors == null)
                    {
                        errors = new Dictionary <string, string>();
                    }
                    errors.Add(key, string.Format("Yo can't change two object to the same name , value: {0}", key, replaceValue));
                }
            }
            //Check SSIS PATHS
            if (!File.Exists(accountWizardSettings.Get("SSIS.TemplateAllBoPackagePath")))
            {
                if (errors == null)
                {
                    errors = new Dictionary <string, string>();
                }
                errors.Add("SSIS.TemplateAllBoPackagePath", "Path not exists");
            }
            if (!File.Exists(accountWizardSettings.Get("SSIS.TemplateAllContentPackagePath")))
            {
                if (errors == null)
                {
                    errors = new Dictionary <string, string>();
                }
                errors.Add("SSIS.TemplateAllContentPackagePath", "Path not exists");
            }
            if (!File.Exists(accountWizardSettings.Get("SSIS.TemplateBoSpecific")))
            {
                if (errors == null)
                {
                    errors = new Dictionary <string, string>();
                }
                errors.Add("SSIS.TemplateBoSpecific", "Path not exists");
            }
            if (!Directory.Exists(accountWizardSettings.Get("SSIS.SSISNewTaskPath")))
            {
                if (errors == null)
                {
                    errors = new Dictionary <string, string>();
                }
                errors.Add("SSIS.AllBoPackageBackupPath", "Path not exists");
            }


            return(errors);
        }
        private void CreateCube(Dictionary <string, object> collectedData)
        {
            //Connect To analysisServer
            using (Server analysisServer = new Server())
            {
                Dictionary <string, object> executorData = new Dictionary <string, object>();  //dictionary for save executors data for next steps
                if (!collectedData.ContainsKey(ApplicationIDKey))
                {
                    executorData.Add(ApplicationIDKey, collectedData[ApplicationIDKey]);
                }

                analysisServer.Connect(accountWizardSettings.Get("AnalysisServer.ConnectionString"));

                //Get the database
                Database analysisDatabase = analysisServer.Databases.GetByName(accountWizardSettings.Get("AnalysisServer.Database"));

                #region CreateBoCube
                //Create bo cube
                Cube boCubeTemplate = analysisDatabase.Cubes[accountWizardSettings.Get("Cube.Templates.BOTemplate")];


                Cube newBOCube = boCubeTemplate.Clone();



                ////change cube name and id
                newBOCube.Name = accountWizardSettings.Get("Cube.BO.Name.Perfix") + collectedData["AccountSettings.CubeName"].ToString();


                executorData.Add("AccountSettings.CubeName", collectedData["AccountSettings.CubeName"].ToString()); //for next step
                newBOCube.ID = accountWizardSettings.Get("Cube.BO.Name.Perfix") + collectedData["AccountSettings.CubeID"].ToString();

                //change  measures
                foreach (MeasureGroup measureGroup in newBOCube.MeasureGroups)
                {
                    foreach (KeyValuePair <string, object> input in collectedData)
                    {
                        if (input.Value is Replacment)
                        {
                            Replacment replacement = (Replacment)input.Value;
                            //AcquisitionS
                            if (input.Key.ToUpper().StartsWith(C_AccSettACQ.ToUpper()))
                            {
                                string[] acquisitions = accountWizardSettings.Get(input.Key).Split(',');
                                foreach (string acquisition in acquisitions)
                                {
                                    Measure measure = measureGroup.Measures.FindByName(acquisition);
                                    if (measure != null)
                                    {                                                                     //perfix of new useres /regs
                                        if (!replacement.CalcMembersOnly)
                                        {
                                            if (measureGroup.Measures.FindByName(replacement.ReplaceTo) == null) //check if their is no measure with the same name
                                            {
                                                measure.Name = replacement.ReplaceTo;
                                            }
                                        }
                                    }
                                }
                            }
                            //Target AcquisitionS
                            else if (input.Key.ToUpper().StartsWith(C_AccSettTargetACQ.ToUpper()))
                            {
                                string[] targetAcquisitions = accountWizardSettings.Get(input.Key).Split(',');
                                foreach (string targetAcquisition in targetAcquisitions)
                                {
                                    Measure measure = measureGroup.Measures.FindByName(targetAcquisition);
                                    if (measure != null)
                                    {                                                                        //key of new active useres /actives
                                        if (measureGroup.Measures.FindByName(replacement.ReplaceTo) == null) //check if their is no measure with the same name
                                        {
                                            measure.Name = replacement.ReplaceTo;
                                        }
                                    }
                                }
                            }
                            // CLIENT SPECIFIC
                            else if (input.Key.StartsWith(C_AccSettClientSpecific, true, null))
                            {
                                if (!replacement.CalcMembersOnly)
                                {
                                    Measure measure = measureGroup.Measures.FindByName(replacement.ReplaceFrom);
                                    if (measure != null)
                                    {
                                        if (measureGroup.Measures.FindByName(replacement.ReplaceTo) == null) //check if their is no measure with the same name
                                        {
                                            measure.Name = replacement.ReplaceTo;
                                        }
                                    }
                                }
                            }
                            else if (input.Key.StartsWith(C_AccSettStringReplacemnet))// string replacment (measure -google values)
                            {
                                if (!replacement.CalcMembersOnly)
                                {
                                    Measure measure = measureGroup.Measures.FindByName(replacement.ReplaceFrom);
                                    if (measure != null)
                                    {
                                        if (measureGroup.Measures.FindByName(replacement.ReplaceTo) == null) //check if their is no measure with the same name
                                        {
                                            measure.Name = replacement.ReplaceTo;
                                        }
                                    }
                                }
                            }
                            //Copy All Data to the next step Panorama cube
                            if (!executorData.ContainsKey(input.Key))
                            {
                                executorData.Add(input.Key, input.Value);
                            }
                        }
                    }

                    //Change scope_id
                    foreach (Partition partition in measureGroup.Partitions)
                    {
                        QueryBinding queryBinding = partition.Source as QueryBinding;

                        if (queryBinding != null)
                        {
                            //since the "scopee_id" must be on the end of the query according to amit
                            //get last index of scope_id
                            int indexScope_id          = queryBinding.QueryDefinition.LastIndexOf("scope_id", StringComparison.OrdinalIgnoreCase);
                            int spacesUntillEndOfQuery = queryBinding.QueryDefinition.Length - indexScope_id;
                            //remove all scope_id
                            queryBinding.QueryDefinition = queryBinding.QueryDefinition.Remove(indexScope_id, spacesUntillEndOfQuery);
                            //insert new scope_id
                            queryBinding.QueryDefinition = queryBinding.QueryDefinition.Insert(queryBinding.QueryDefinition.Length, string.Format(" Scope_ID={0}", collectedData["AccountSettings.BI_Scope_ID"].ToString()));
                            //
                        }
                    }
                }

                //change client specific measures/STRING REPLACEMENT/ in calculated members

                foreach (MdxScript script in newBOCube.MdxScripts)
                {
                    foreach (Command command in script.Commands)
                    {
                        CalculatedMembersCollection CalculatedMembersCollection = new CalculatedMembersCollection(command.Text);
                        foreach (KeyValuePair <string, object> input in collectedData)
                        {
                            if (input.Value is Replacment)
                            {
                                Replacment replacment = (Replacment)input.Value;
                                if (input.Key.StartsWith(C_AccSettClientSpecific, true, null))
                                {
                                    CalculatedMembersCollection.ReplaceCalculatedMembersStrings(replacment.ReplaceFrom, replacment.ReplaceTo);
                                }
                                else if (input.Key.ToUpper().StartsWith(C_AccSettACQ.ToUpper())) //acquisitions
                                {
                                    string[] acquisitions = accountWizardSettings.Get(input.Key).Split(',');

                                    foreach (string acquisition in acquisitions)
                                    {
                                        CalculatedMembersCollection.ReplaceCalculatedMembersStrings(acquisition, replacment.ReplaceTo);
                                    }
                                }
                                else if (input.Key.ToUpper().StartsWith(C_AccSettTargetACQ.ToUpper())) //target acquisitions
                                {
                                    string[] targetAcquisitions = accountWizardSettings.Get(input.Key).Split(',');

                                    foreach (string targetAcquisition in targetAcquisitions)
                                    {
                                        CalculatedMembersCollection.ReplaceCalculatedMembersStrings(targetAcquisition, replacment.ReplaceTo);
                                    }
                                }
                                else if (input.Key.StartsWith(C_AccSettStringReplacemnet)) //string replacement
                                {
                                    CalculatedMembersCollection.ReplaceCalculatedMembersStrings(replacment.ReplaceFrom, replacment.ReplaceTo);
                                }
                            }
                        }
                        command.Text = CalculatedMembersCollection.GetText();
                    }
                }


                //Add last step created role (for this test some existing  role role 8 which not exist in the template)

                //Get the roleID from last step collector
                //Dictionary<string, object> roleData = GetCollectedData();

                CubePermission cubePermission = new CubePermission(collectedData["AccountSettings.RoleID"].ToString(), accountWizardSettings.Get("Cube.CubePermission.ID"), accountWizardSettings.Get("Cube.CubePermission.Name"));
                cubePermission.Read = ReadAccess.Allowed;
                newBOCube.CubePermissions.Add(cubePermission);



                ///Add the new BO cube
                try
                {
                    int result = analysisDatabase.Cubes.Add(newBOCube);
                    newBOCube.Update(UpdateOptions.ExpandFull, UpdateMode.Create);
                }
                catch (Exception ex)
                {
                    Log.Write("Error adding BO cube", ex);
                }
                #endregion
                #region ContentCube
                //check if content cube should be add too-------------------------------------
                //---------------------------------------------------------------------------
                executorData.Add("AccountSettings.AddContentCube", collectedData["AccountSettings.AddContentCube"]);
                executorData.Add("AccountSettings.ProcessCubes", collectedData["AccountSettings.ProcessCubes"]);
                if (bool.Parse(collectedData["AccountSettings.AddContentCube"].ToString()) == true)
                {
                    //Add Content Cube
                    //Create bo cube
                    Cube ContentCubeTemplate = analysisDatabase.Cubes[accountWizardSettings.Get("Cube.Templates.ContentTemplate")];


                    Cube newContentCube = ContentCubeTemplate.Clone();



                    ////change cube name and id
                    newContentCube.Name = accountWizardSettings.Get("Cube.Content.Name.Perfix") + collectedData["AccountSettings.CubeName"].ToString();
                    newContentCube.ID   = accountWizardSettings.Get("Cube.Content.Name.Perfix") + collectedData["AccountSettings.CubeID"].ToString();
                    //Get google values for replacments;
                    string[] googleConversions = accountWizardSettings.Get("EdgeBI.Wizards.GoogleConversions").Split(',');

                    foreach (MeasureGroup measureGroup in newContentCube.MeasureGroups)
                    {
                        //Replace Google Value
                        foreach (KeyValuePair <string, object> input in collectedData)
                        {
                            if (input.Value is Replacment)
                            {
                                Replacment replacement = (Replacment)input.Value;
                                if (!replacement.CalcMembersOnly)
                                {
                                    foreach (string googleConversion in googleConversions)
                                    {
                                        if (replacement.ReplaceFrom == googleConversion)
                                        {
                                            Measure measure = measureGroup.Measures.FindByName(replacement.ReplaceFrom);
                                            if (measure != null)
                                            {
                                                if (measureGroup.Measures.FindByName(replacement.ReplaceTo) == null) //check if their is no measure with the same name
                                                {
                                                    measure.Name = replacement.ReplaceTo.Replace(accountWizardSettings.Get("Cube.BO.Name.Perfix"), accountWizardSettings.Get("Cube.Content.Name.Perfix"));
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        //Replace the scope_id
                        foreach (Partition partition in measureGroup.Partitions)
                        {
                            QueryBinding queryBinding = partition.Source as QueryBinding;

                            if (queryBinding != null)
                            {
                                //since the "scopee_id" must be on the end of the query according to amit
                                //get last index of scope_id
                                int indexScope_id          = queryBinding.QueryDefinition.LastIndexOf("scope_id", StringComparison.OrdinalIgnoreCase);
                                int spacesUntillEndOfQuery = queryBinding.QueryDefinition.Length - indexScope_id;
                                //remove all scope_id
                                queryBinding.QueryDefinition = queryBinding.QueryDefinition.Remove(indexScope_id, spacesUntillEndOfQuery);
                                //insert new scope_id
                                queryBinding.QueryDefinition = queryBinding.QueryDefinition.Insert(queryBinding.QueryDefinition.Length, string.Format(" Scope_ID={0}", collectedData["AccountSettings.BI_Scope_ID"].ToString()));
                            }
                        }
                    }
                    //Replace google conversion on calculated members
                    foreach (MdxScript script in newBOCube.MdxScripts)
                    {
                        foreach (Command command in script.Commands)
                        {
                            CalculatedMembersCollection CalculatedMembersCollection = new CalculatedMembersCollection(command.Text);
                            foreach (KeyValuePair <string, object> input in collectedData)
                            {
                                if (input.Value is Replacment)
                                {
                                    Replacment replacment = (Replacment)input.Value;
                                    foreach (string googleConversion in googleConversions)
                                    {
                                        if (replacment.ReplaceFrom == googleConversion)
                                        {
                                            CalculatedMembersCollection.ReplaceCalculatedMembersStrings(replacment.ReplaceFrom, replacment.ReplaceTo);
                                        }
                                    }
                                }
                            }
                            command.Text = CalculatedMembersCollection.GetText();
                        }
                    }

                    //add last step role (cube permission
                    cubePermission      = new CubePermission(collectedData["AccountSettings.RoleID"].ToString(), accountWizardSettings.Get("Cube.CubePermission.ID"), accountWizardSettings.Get("Cube.CubePermission.Name"));
                    cubePermission.Read = ReadAccess.Allowed;
                    newContentCube.CubePermissions.Add(cubePermission);


                    ///Add the new Content cube
                    try
                    {
                        int result = analysisDatabase.Cubes.Add(newContentCube);
                        newContentCube.Update(UpdateOptions.ExpandFull, UpdateMode.Create);
                    }
                    catch (Exception ex)
                    {
                        Log.Write("Error adding BO cube", ex);
                    }
                }
                #endregion
                SaveExecutorData(executorData);
            }
        }
        private void UpdateRelevantPropertiesOnXml(DirectoryInfo targetDirectory, Dictionary <string, object> lastExecutorStepData)
        {
            string pattern;

            foreach (FileInfo file in targetDirectory.GetFiles())
            {
                if (file.Name.ToLower() == "schema.xml" || file.Name.ToLower() == "properties.xml" || file.Name.ToLower() == "refreshbook")
                {
                    continue;
                }
                else
                {
                    string fileString = string.Empty;
                    using (StreamReader reader = new StreamReader(file.FullName))
                    {
                        fileString = reader.ReadToEnd();
                        //channge CubeAdress,CubeName,CubeDB atributes
                    }
                    pattern = RegxUtils.CreateExactMatchWholeWordRegExpression(accountWizardSettings.Get("Panorama.ServerToReplace")); //replace server
                    //CubeAdress
                    fileString = Regex.Replace(fileString, pattern, accountWizardSettings.Get("AnalysisServer.ConnectionString").Replace("DataSource=", string.Empty), RegexOptions.IgnoreCase);
                    //CubeName //few options here

                    pattern = RegxUtils.CreateExactMatchWholeWordRegExpression(accountWizardSettings.Get("Panorama.ContentCubeToReplace"));//ContentCubeToReplace

                    fileString = Regex.Replace(fileString, pattern, accountWizardSettings.Get("Cube.Content.Name.Perfix") + lastExecutorStepData["AccountSettings.CubeName"].ToString(), RegexOptions.IgnoreCase);

                    pattern    = RegxUtils.CreateExactMatchWholeWordRegExpression(accountWizardSettings.Get("Panorama.BoCubeToReplace")); //BoCubeToReplace
                    fileString = Regex.Replace(fileString, pattern, accountWizardSettings.Get("Cube.BO.Name.Perfix") + lastExecutorStepData["AccountSettings.CubeName"].ToString(), RegexOptions.IgnoreCase);


                    pattern    = RegxUtils.CreateExactMatchWholeWordRegExpression(accountWizardSettings.Get("Panorama.CubeDbtoReplace"));//CubeDbtoReplace
                    fileString = Regex.Replace(fileString, pattern, accountWizardSettings.Get("AnalysisServer.Database"), RegexOptions.IgnoreCase);

                    //Replace client specific measures +Acquisitions +target AcquisitionS

                    foreach (KeyValuePair <string, object> input in lastExecutorStepData)
                    {
                        if (input.Value is Replacment)
                        {
                            Replacment replacment = (Replacment)input.Value;
                            if (input.Key.StartsWith(AccSettClientSpecific, true, null))//measures
                            {
                                pattern    = RegxUtils.CreateExactMatchWholeWordRegExpression(replacment.ReplaceFrom);
                                fileString = Regex.Replace(fileString, pattern, replacment.ReplaceTo, RegexOptions.IgnoreCase);
                            }
                            else if (input.Key.StartsWith("AccountSettings.StringReplacment."))//String ReplaceMent
                            {
                                pattern    = RegxUtils.CreateExactMatchWholeWordRegExpression(replacment.ReplaceFrom);
                                fileString = Regex.Replace(fileString, pattern, replacment.ReplaceTo, RegexOptions.IgnoreCase);
                            }
                            else if (input.Key.StartsWith(C_AccSettACQ))// Acquisitions
                            {
                                if (input.Value.ToString() != " ")
                                {
                                    string[] acquisitions = accountWizardSettings.Get(input.Key).Split(',');
                                    foreach (string acquisition in acquisitions)
                                    {
                                        pattern    = @"\b" + acquisition + @"\b";
                                        fileString = Regex.Replace(fileString, pattern, replacment.ReplaceTo, RegexOptions.IgnoreCase);
                                    }
                                }
                            }
                            else if (input.Key.StartsWith(C_AccSettTargetACQ)) //TARGET Acquisitions
                            {
                                if (input.Value.ToString() != " ")
                                {
                                    string[] targetAcquisitions = accountWizardSettings.Get(input.Key).Split(',');
                                    foreach (string targetAcquisition in targetAcquisitions)
                                    {
                                        pattern    = @"\b" + targetAcquisition + @"\b";
                                        fileString = Regex.Replace(fileString, pattern, replacment.ReplaceTo, RegexOptions.IgnoreCase);
                                    }
                                }
                            }
                        }
                    }

                    using (StreamWriter writer = new StreamWriter(file.FullName, false))
                    {
                        writer.Write(fileString);
                    }
                }
            }
        }
        private IReadOnlyList <IOperationProvider> ProcessOperations(IParameterSet parameters, ITemplateSourceFolder templateRoot, IReadOnlyDictionary <string, JObject> operations, out VariableCollection variables)
        {
            List <IOperationProvider> result = new List <IOperationProvider>();
            JObject variablesSection         = operations["variables"];

            JObject data;

            if (operations.TryGetValue("macros", out data))
            {
                foreach (JProperty property in data.Properties())
                {
                    RunMacros(property, variablesSection, parameters);
                }
            }

            if (operations.TryGetValue("include", out data))
            {
                string startToken = data["start"].ToString();
                string endToken   = data["end"].ToString();
                result.Add(new Include(startToken, endToken, templateRoot.OpenFile));
            }

            if (operations.TryGetValue("regions", out data))
            {
                JArray regionSettings = (JArray)data["settings"];
                foreach (JToken child in regionSettings.Children())
                {
                    JObject setting         = (JObject)child;
                    string  start           = setting["start"].ToString();
                    string  end             = setting["end"].ToString();
                    bool    include         = setting["include"]?.ToObject <bool>() ?? false;
                    bool    regionTrim      = setting["trim"]?.ToObject <bool>() ?? false;
                    bool    regionWholeLine = setting["wholeLine"]?.ToObject <bool>() ?? false;
                    result.Add(new Region(start, end, include, regionWholeLine, regionTrim));
                }
            }

            if (operations.TryGetValue("conditionals", out data))
            {
                string             ifToken       = data["if"].ToString();
                string             elseToken     = data["else"].ToString();
                string             elseIfToken   = data["elseif"].ToString();
                string             endIfToken    = data["endif"].ToString();
                string             evaluatorName = data["evaluator"].ToString();
                bool               trim          = data["trim"]?.ToObject <bool>() ?? false;
                bool               wholeLine     = data["wholeLine"]?.ToObject <bool>() ?? false;
                ConditionEvaluator evaluator     = CppStyleEvaluatorDefinition.CppStyleEvaluator;

                switch (evaluatorName)
                {
                case "C++":
                    evaluator = CppStyleEvaluatorDefinition.CppStyleEvaluator;
                    break;
                }

                result.Add(new Conditional(ifToken, elseToken, elseIfToken, endIfToken, wholeLine, trim, evaluator));
            }

            if (operations.TryGetValue("flags", out data))
            {
                foreach (JProperty property in data.Properties())
                {
                    JObject innerData  = (JObject)property.Value;
                    string  flag       = property.Name;
                    string  on         = innerData["on"]?.ToString() ?? string.Empty;
                    string  off        = innerData["off"]?.ToString() ?? string.Empty;
                    string  onNoEmit   = innerData["onNoEmit"]?.ToString() ?? string.Empty;
                    string  offNoEmit  = innerData["offNoEmit"]?.ToString() ?? string.Empty;
                    string  defaultStr = innerData["default"]?.ToString();
                    bool?   @default   = null;

                    if (defaultStr != null)
                    {
                        @default = bool.Parse(defaultStr);
                    }

                    result.Add(new SetFlag(flag, on, off, onNoEmit, offNoEmit, @default));
                }
            }

            if (operations.TryGetValue("replacements", out data))
            {
                foreach (JProperty property in data.Properties())
                {
                    ITemplateParameter param;
                    if (parameters.TryGetParameter(property.Value.ToString(), out param))
                    {
                        string val;
                        try
                        {
                            val = parameters.ParameterValues[param];
                        }
                        catch (KeyNotFoundException ex)
                        {
                            throw new Exception($"Unable to find a parameter value called \"{param.Name}\"", ex);
                        }

                        Replacment r = new Replacment(property.Name, val);
                        result.Add(r);
                    }
                }
            }

            variables = HandleVariables(parameters, variablesSection, result);
            return(result);
        }