/// <summary>
        /// Converts the given ScriptLanguageTypes enum value to a Languages enum value.
        /// </summary>
        /// <param name="scriptLanguage"></param>
        /// <returns></returns>
        public static TemplateContentLanguage GetScriptingLanguage(ScriptLanguageTypes scriptLanguage)
        {
            // Set the scripting language
            TemplateContentLanguage scriptingLanguage;

            switch (scriptLanguage)
            {
            case ScriptLanguageTypes.CSharp:
                scriptingLanguage = TemplateContentLanguage.CSharp;
                break;

            case ScriptLanguageTypes.VbNet:
                scriptingLanguage = TemplateContentLanguage.VbDotNet;
                break;

            default:
                throw new Exception("ScriptLanguage not catered for yet in CreateDirectiveXmlToCSharpLanguage: " + scriptLanguage);
            }
            return(scriptingLanguage);
        }
        /// <summary>
        /// Loads two languages and creates a state transition from XML to C# within ASP-style directives.
        /// </summary>
        public static void SetupEditorTemplateAndScriptLanguages(SyntaxEditor editor, TemplateContentLanguage textLanguage, ScriptLanguageTypes scriptLanguage, string delimiterStart, string delimiterEnd)
        {
            DynamicSyntaxLanguage language       = GetDynamicLanguage(textLanguage);
            DynamicSyntaxLanguage cSharpLanguage = GetDynamicLanguage(GetScriptingLanguage(scriptLanguage));

            language.AutomaticOutliningBehavior       = AutomaticOutliningBehavior.PostSemanticParse;
            cSharpLanguage.AutomaticOutliningBehavior = AutomaticOutliningBehavior.PostSemanticParse;

            language.Tag       = "TemplateLanguage";
            cSharpLanguage.Tag = "ScriptLanguage";

            // Mark that updating is starting
            language.IsUpdating       = true;
            cSharpLanguage.IsUpdating = true;

            // Add StateTransitions to current language as well nested languages eg: HTML -> JavaScript, VBScript etc.
            for (int i = 0; i <= language.ChildLanguages.Count; i++)
            {
                DynamicSyntaxLanguage lan;

                if (i == language.ChildLanguages.Count)
                {
                    lan = language;
                }
                else
                {
                    lan = (DynamicSyntaxLanguage)language.ChildLanguages[i];
                }
                // Add a highlighting style
                lan.HighlightingStyles.Add(new HighlightingStyle("ASPDirectiveDelimiterStyle", null, Color.Black, ASP_DIRECTIVE_COLOUR));
                lan.AutomaticOutliningBehavior = AutomaticOutliningBehavior.SemanticParseDataChange;

                // Create a new lexical state
                DynamicLexicalState lexicalState = new DynamicLexicalState(0, "ASPDirectiveState");
                lexicalState.DefaultTokenKey                    = "ASPDirectiveDefaultToken";
                lexicalState.DefaultHighlightingStyle           = lan.HighlightingStyles["DefaultStyle"];
                lexicalState.LexicalStateTransitionLexicalState = cSharpLanguage.LexicalStates["DefaultState"];

                lan.LexicalStates.Add(lexicalState);

                // Add the new lexical state at the beginning of the child states...
                // Remember that with an NFA regular expression, the first match is taken...
                // So since a < scope pattern is already in place, we must insert the new one before it
                lan.LexicalStates["DefaultState"].ChildLexicalStates.Insert(0, lexicalState);

                #region Extra Transition points - Eg: comments
                if (lan.LexicalStates.IndexOf("XMLCommentState") >= 0)                               // C#
                {
                    lan.LexicalStates["XMLCommentState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("CommentState") >= 0)                                  // C#
                {
                    lan.LexicalStates["CommentState"].ChildLexicalStates.Insert(0, lexicalState);    // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("StringState") >= 0)                                   // SQL
                {
                    // Note: Had to modify the RegexPatternGroup for StringState in ActiproSoftware.SQL.xml to: <RegexPatternGroup TokenKey="StringDefaultToken" PatternValue="[^&lt;^']+" />
                    lan.LexicalStates["StringState"].ChildLexicalStates.Insert(0, lexicalState);                       // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("SquareStringState") >= 0)                                               // SQL
                {
                    lan.LexicalStates["SquareStringState"].ChildLexicalStates.Insert(0, lexicalState);                 // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("MultiLineCommentState") >= 0)                                           // SQL
                {
                    lan.LexicalStates["MultiLineCommentState"].ChildLexicalStates.Insert(0, lexicalState);             // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("StartTagState") >= 0)                                                   // HTML
                {
                    lan.LexicalStates["StartTagState"].ChildLexicalStates.Insert(0, lexicalState);                     // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("StartTagAttributeStringValueState") >= 0)                               // HTML
                {
                    lan.LexicalStates["StartTagAttributeStringValueState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("StartTagAttributeState") >= 0)                                          // HTML
                {
                    lan.LexicalStates["StartTagAttributeState"].ChildLexicalStates.Insert(0, lexicalState);            // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("StartTagAttributeValueState") >= 0)                                     // HTML
                {
                    lan.LexicalStates["StartTagAttributeValueState"].ChildLexicalStates.Insert(0, lexicalState);       // Added this to ensure that transitions can occur in XML Comments
                }
                // Create a lexical scope with a lexical state transition
                DynamicLexicalScope lexicalScope = new DynamicLexicalScope();
                lexicalState.LexicalScopes.Add(lexicalScope);
                lexicalScope.StartLexicalPatternGroup = new LexicalPatternGroup(LexicalPatternType.Explicit, "ASPDirectiveStartToken", lan.HighlightingStyles["ASPDirectiveDelimiterStyle"], delimiterStart);
                lexicalScope.StartLexicalPatternGroup.LookBehindPattern = @"\\{2}|([^\\]|^)";                // @"\\{2}|[^\\]";
                lexicalScope.EndLexicalPatternGroup       = new LexicalPatternGroup(LexicalPatternType.Explicit, "ASPDirectiveEndToken", lan.HighlightingStyles["ASPDirectiveDelimiterStyle"], delimiterEnd);
                lexicalScope.AncestorEndScopeCheckEnabled = false;
            }
            #endregion

            // Mark that updating is complete (since linking is complete, the flag setting
            // will filter from the XML language into the C# language)
            language.IsUpdating      = false;
            editor.Document.Language = language;
        }
        /// <summary>
        /// Loads two languages and creates a state transition from XML to C# within ASP-style directives.
        /// </summary>
        public static void SetupEditorTemplateAndScriptLanguages(SyntaxEditor editor, TemplateContentLanguage textLanguage, ScriptLanguageTypes scriptLanguage, string delimiterStart, string delimiterEnd)
        {
            DynamicSyntaxLanguage language = GetDynamicLanguage(textLanguage);
            DynamicSyntaxLanguage cSharpLanguage = GetDynamicLanguage(GetScriptingLanguage(scriptLanguage));

            language.AutomaticOutliningBehavior = AutomaticOutliningBehavior.PostSemanticParse;
            cSharpLanguage.AutomaticOutliningBehavior = AutomaticOutliningBehavior.PostSemanticParse;

            language.Tag = "TemplateLanguage";
            cSharpLanguage.Tag = "ScriptLanguage";

            // Mark that updating is starting
            language.IsUpdating = true;
            cSharpLanguage.IsUpdating = true;

            // Add StateTransitions to current language as well nested languages eg: HTML -> JavaScript, VBScript etc.
            for (int i = 0; i <= language.ChildLanguages.Count; i++)
            {
                DynamicSyntaxLanguage lan;

                if (i == language.ChildLanguages.Count)
                {
                    lan = language;
                }
                else
                {
                    lan = (DynamicSyntaxLanguage)language.ChildLanguages[i];
                }
                // Add a highlighting style
                lan.HighlightingStyles.Add(new HighlightingStyle("ASPDirectiveDelimiterStyle", null, Color.Black, ASP_DIRECTIVE_COLOUR));
                lan.AutomaticOutliningBehavior = AutomaticOutliningBehavior.SemanticParseDataChange;

                // Create a new lexical state
                DynamicLexicalState lexicalState = new DynamicLexicalState(0, "ASPDirectiveState");
                lexicalState.DefaultTokenKey = "ASPDirectiveDefaultToken";
                lexicalState.DefaultHighlightingStyle = lan.HighlightingStyles["DefaultStyle"];
                lexicalState.LexicalStateTransitionLexicalState = cSharpLanguage.LexicalStates["DefaultState"];

                lan.LexicalStates.Add(lexicalState);

                // Add the new lexical state at the beginning of the child states...
                // Remember that with an NFA regular expression, the first match is taken...
                // So since a < scope pattern is already in place, we must insert the new one before it
                lan.LexicalStates["DefaultState"].ChildLexicalStates.Insert(0, lexicalState);

                #region Extra Transition points - Eg: comments
                if (lan.LexicalStates.IndexOf("XMLCommentState") >= 0) // C#
                {
                    lan.LexicalStates["XMLCommentState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("CommentState") >= 0) // C#
                {
                    lan.LexicalStates["CommentState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("StringState") >= 0) // SQL
                {
                    // Note: Had to modify the RegexPatternGroup for StringState in ActiproSoftware.SQL.xml to: <RegexPatternGroup TokenKey="StringDefaultToken" PatternValue="[^&lt;^']+" />
                    lan.LexicalStates["StringState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("SquareStringState") >= 0) // SQL
                {
                    lan.LexicalStates["SquareStringState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("MultiLineCommentState") >= 0) // SQL
                {
                    lan.LexicalStates["MultiLineCommentState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("StartTagState") >= 0) // HTML
                {
                    lan.LexicalStates["StartTagState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("StartTagAttributeStringValueState") >= 0) // HTML
                {
                    lan.LexicalStates["StartTagAttributeStringValueState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("StartTagAttributeState") >= 0) // HTML
                {
                    lan.LexicalStates["StartTagAttributeState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments
                }
                if (lan.LexicalStates.IndexOf("StartTagAttributeValueState") >= 0) // HTML
                {
                    lan.LexicalStates["StartTagAttributeValueState"].ChildLexicalStates.Insert(0, lexicalState); // Added this to ensure that transitions can occur in XML Comments
                }
                // Create a lexical scope with a lexical state transition
                DynamicLexicalScope lexicalScope = new DynamicLexicalScope();
                lexicalState.LexicalScopes.Add(lexicalScope);
                lexicalScope.StartLexicalPatternGroup = new LexicalPatternGroup(LexicalPatternType.Explicit, "ASPDirectiveStartToken", lan.HighlightingStyles["ASPDirectiveDelimiterStyle"], delimiterStart);
                lexicalScope.StartLexicalPatternGroup.LookBehindPattern = @"\\{2}|([^\\]|^)";// @"\\{2}|[^\\]";
                lexicalScope.EndLexicalPatternGroup = new LexicalPatternGroup(LexicalPatternType.Explicit, "ASPDirectiveEndToken", lan.HighlightingStyles["ASPDirectiveDelimiterStyle"], delimiterEnd);
                lexicalScope.AncestorEndScopeCheckEnabled = false;
            }
                #endregion

            // Mark that updating is complete (since linking is complete, the flag setting
            // will filter from the XML language into the C# language)
            language.IsUpdating = false;
            editor.Document.Language = language;
        }
 /// <summary>
 /// Converts the given ScriptLanguageTypes enum value to a Languages enum value.
 /// </summary>
 /// <param name="scriptLanguage"></param>
 /// <returns></returns>
 public static TemplateContentLanguage GetScriptingLanguage(ScriptLanguageTypes scriptLanguage)
 {
     // Set the scripting language
     TemplateContentLanguage scriptingLanguage;
     switch (scriptLanguage)
     {
         case ScriptLanguageTypes.CSharp:
             scriptingLanguage = TemplateContentLanguage.CSharp;
             break;
         case ScriptLanguageTypes.VbNet:
             scriptingLanguage = TemplateContentLanguage.VbDotNet;
             break;
         default:
             throw new Exception("ScriptLanguage not catered for yet in CreateDirectiveXmlToCSharpLanguage: " + scriptLanguage);
     }
     return scriptingLanguage;
 }