/// <summary>
        /// Process a given interchange element (chunk).
        /// </summary>
        /// <param name="processor"></param>
        /// <param name="node">Last node that was parsed. This is used for annotations.</param>
        /// <param name="chunk">Interchange chunk to be processed.</param>
        /// <returns>Returns the new interchange parse node (or null in case of error).</returns>
        protected virtual InterchangeUnitNode ProcessInterchangeElement(InterchangeFormatProcessor processor, InterchangeUnitNode node, InterchangeChunk chunk)
        {
            InterchangeFormatParser parser            = this.GetInterchangeParser(chunk);
            InterchangeElementNode  nodeForAnnotation = (node == null) ? null : node.GetAnnotatedNode();

            node = parser.ParseInterchangeElement(nodeForAnnotation);
            if (node == null)
            {
                return(null);
            }
            return(node.FileIn(processor, chunk, chunk));
        }
        protected virtual AnnotationNode ParseAnnotation(InterchangeElementNode nodeForAnnotation)
        {
            // TODO : Move constants out of code into a the InterchangeFormatConstants class
            // TODO : Move error messages out of code into a the InterchangeFormatErrors class

            // PARSE: <annotation> ::= ’Annotation’ ’key:’ quotedString ’value:’ quotedString <elementSeparator>
            AnnotationNode result = this.CreateAnnotationNode(nodeForAnnotation);
            Token          token  = this.GetNextTokenxx();
            StringToken    str    = token as StringToken;

            if (str == null)
            {
                this.ReportParserError(result, "Missing annotation key.", token);
            }
            result.Key = str;

            token = this.GetNextTokenxx();
            KeywordToken cmd = token as KeywordToken;

            if ((cmd == null) || (cmd.Value != "value:"))
            {
                this.ReportParserError("Missing annotation #value: keyword.", token);
            }

            token = this.GetNextTokenxx();
            str   = token as StringToken;
            if (str == null)
            {
                this.ReportParserError(result, "Missing annotation value.", token);
            }
            result.Value = str;

            token = this.GetNextTokenxx();
            if (!(token is EofToken))
            {
                this.ReportParserError(result, "Unexpected code found after annotation value.", token);
                result.Key   = null; // This is to avoid something like: Annotation key: 'x' value: 'y' crash: 'yes'.
                result.Value = null; // This is to avoid something like: Annotation key: 'x' value: 'y' crash: 'yes'.
                return(result);
            }

            return(result);
        }
        protected internal virtual InterchangeUnitNode ParseInterchangeElement(InterchangeElementNode nodeForAnnotation)
        {
            // TODO : Move constants out of code into a the InterchangeFormatConstants class
            // TODO : Move error messages out of code into a the InterchangeFormatErrors class

            // PARSE: <interchangeElement> ::= <classDefinition> | <classInitialization> | <globalDefinition> |
            //      <globalValueInitialization> | <poolDefinition> | <poolVariableDefinition> | <poolValueInitialization> |
            //      <methodDefinition> | <classMethodDefinition> | <programInitialization> | comment <elementSeparator>

            // PARSE: The above definitions expand to:
            // ’Class’ ’named:’ <classNameString> .... <elementSeparator>
            // <className> ’initializer’ <elementSeparator>
            // ’Global’ ’variable:’ <globalNameString> <elementSeparator>
            // ’Global’ ’constant:’ <globalNameString> <elementSeparator>
            // <globalName> ’initializer’ <elementSeparator>
            // ’Pool’ ’named:’ <poolNameString> <elementSeparator>
            // <poolName> ’variable:’ <poolVariableNameString> <elementSeparator>
            // <poolName> ’constant:’ <poolVariableNameString> <elementSeparator>
            // <poolName> ’initializerFor:’ <poolVariableNameString> <elementSeparator>
            // <className> ’method’ <elementSeparator>
            // <className> ’classMethod’ <elementSeparator>
            // ’Global’ ’initializer’ <elementSeparator>
            // comment <elementSeparator> ... NB: This will NEVER be returned by GetNextTokenxx().

            Token token = this.GetNextTokenxx();

            if (token is EofToken)
            {
                return(null); // Most probably just a comment ...
            }
            // The abode syntax shows us that we are dealing with the following pattern:
            //      identifier indetifier_or_keyword undefined_token*
            // Comments are ignored and discarded by GetNextTokenxx().
            IdentifierToken id = token as IdentifierToken;

            if (id == null)
            {
                this.ReportParserError("Expected identifier.", token);
                return(null);
            }

            token = this.GetNextTokenxx();
            IdentifierOrKeywordToken cmd = token as IdentifierOrKeywordToken;

            if (cmd == null)
            {
                this.ReportParserError("Expected identifier or keyword.", token);
                return(null);
            }

            // <classDefinition> ::= ’Class’ ’named:’ <classNameString> .... <elementSeparator>
            if ((id.Value == "Class") && (cmd.Value == "named:"))
            {
                return(this.ParseClassDefinition()); // Discard <id> and <cmd>
            }
            // <globalDefinition> ::= ’Global’ ’variable:’ <globalNameString> <elementSeparator>
            if ((id.Value == "Global") && (cmd.Value == "variable:"))
            {
                return(this.ParseGlobalVariableDefinition()); // Discard <id> and <cmd>
            }
            // <globalDefinition> ::= ’Global’ ’constant:’ <globalNameString> <elementSeparator>
            if ((id.Value == "Global") && (cmd.Value == "constant:"))
            {
                return(this.ParseGlobalConstantDefinition()); // Discard <id> and <cmd>
            }
            // <poolDefinition> ::= ’Pool’ ’named:’ <poolNameString> <elementSeparator>
            if ((id.Value == "Pool") && (cmd.Value == "named:"))
            {
                return(this.ParsePoolDefinition()); // Discard <id> and <cmd>
            }
            // <programInitialization> ::= ’Global’ ’initializer’ <elementSeparator>
            if ((id.Value == "Global") && (cmd.Value == "initializer"))
            {
                return(this.ParseProgramInitialization()); // Discard <id> and <cmd>
            }
            // <methodDefinition> ::= <className> ’method’ <elementSeparator>
            if (cmd.Value == "method")
            {
                return(this.ParseInstanceMethodDefinition(id)); // Discard <cmd>
            }
            // <classMethodDefinition> ::= <className> ’classMethod’ <elementSeparator>
            if (cmd.Value == "classMethod")
            {
                return(this.ParseClassMethodDefinition(id)); // Discard <cmd>
            }
            // <classInitialization> ::= <className> ’initializer’ <elementSeparator>
            // <globalValueInitialization> ::= <globalName> ’initializer’ <elementSeparator>
            if (cmd.Value == "initializer")
            {
                return(this.ParseGlobalInitialization(id)); // Discard <cmd>
            }
            // <poolVariableDefinition> ::= <poolName> ’variable:’ <poolVariableNameString> <elementSeparator>
            if (cmd.Value == "variable:")
            {
                return(this.ParsePoolVariableDefinition(id)); // Discard <cmd>
            }
            // <poolVariableDefinition> ::= <poolName> ’constant:’ <poolVariableNameString> <elementSeparator>
            if (cmd.Value == "constant:")
            {
                return(this.ParsePoolConstantDefinition(id)); // Discard <cmd>
            }
            // <poolValueInitialization> ::= <poolName> ’initializerFor:’ <poolVariableNameString> <elementSeparator>
            if (cmd.Value == "initializerFor:")
            {
                return(this.ParsePoolValueInitialization(id));
            }

            // SPECIAL CASE .... Not really interchange element, but handled like one for simplicity.
            // <annotation> ::= ’Annotation’ ’key:’ quotedString ’value:’ quotedString <elementSeparator>
            if ((id.Value == "Annotation") && (cmd.Value == "key:"))
            {
                if (nodeForAnnotation == null)
                {
                    this.ReportParserError("Annotation must follow an interchange element", cmd);
                }
                return(this.ParseAnnotation(nodeForAnnotation));
            }

            this.ReportParserError("Unrecognized interchange element.", token);
            return(null);
        }
 protected virtual AnnotationNode CreateAnnotationNode(InterchangeElementNode nodeForAnnotation)
 {
     return(new AnnotationNode(nodeForAnnotation));
 }