protected virtual void Dispatch(string line)
        {
            //[email protected]( "event: " + line );
            string[] elements = GetEventElements(line);
            if (elements == null || elements[0] == null)
            {
                Console.Error.WriteLine("unknown debug event: " + line);
                return;
            }
            if (elements[0].Equals("enterRule"))
            {
                listener.EnterRule(elements[1], elements[2]);
            }
            else if (elements[0].Equals("exitRule"))
            {
                listener.ExitRule(elements[1], elements[2]);
            }
            else if (elements[0].Equals("enterAlt"))
            {
                listener.EnterAlt(int.Parse(elements[1]));
            }
            else if (elements[0].Equals("enterSubRule"))
            {
                listener.EnterSubRule(int.Parse(elements[1]));
            }
            else if (elements[0].Equals("exitSubRule"))
            {
                listener.ExitSubRule(int.Parse(elements[1]));
            }
            else if (elements[0].Equals("enterDecision"))
            {
                listener.EnterDecision(int.Parse(elements[1]), elements[2].Equals("true"));
            }
            else if (elements[0].Equals("exitDecision"))
            {
                listener.ExitDecision(int.Parse(elements[1]));
            }
            else if (elements[0].Equals("location"))
            {
                listener.Location(int.Parse(elements[1]),
                                  int.Parse(elements[2]));
            }
            else if (elements[0].Equals("consumeToken"))
            {
                ProxyToken t = DeserializeToken(elements, 1);
                if (t.TokenIndex == previousTokenIndex)
                {
                    tokenIndexesInvalid = true;
                }
                previousTokenIndex = t.TokenIndex;
                listener.ConsumeToken(t);
            }
            else if (elements[0].Equals("consumeHiddenToken"))
            {
                ProxyToken t = DeserializeToken(elements, 1);
                if (t.TokenIndex == previousTokenIndex)
                {
                    tokenIndexesInvalid = true;
                }
                previousTokenIndex = t.TokenIndex;
                listener.ConsumeHiddenToken(t);
            }
            else if (elements[0].Equals("LT"))
            {
                IToken t = DeserializeToken(elements, 2);
                listener.LT(int.Parse(elements[1]), t);
            }
            else if (elements[0].Equals("mark"))
            {
                listener.Mark(int.Parse(elements[1]));
            }
            else if (elements[0].Equals("rewind"))
            {
                if (elements[1] != null)
                {
                    listener.Rewind(int.Parse(elements[1]));
                }
                else
                {
                    listener.Rewind();
                }
            }
            else if (elements[0].Equals("beginBacktrack"))
            {
                listener.BeginBacktrack(int.Parse(elements[1]));
            }
            else if (elements[0].Equals("endBacktrack"))
            {
                int level    = int.Parse(elements[1]);
                int successI = int.Parse(elements[2]);
                listener.EndBacktrack(level, successI == DebugEventListenerConstants.True);
            }
            else if (elements[0].Equals("exception"))
            {
#if true
                throw new System.NotImplementedException();
#else
                string excName  = elements[1];
                string indexS   = elements[2];
                string lineS    = elements[3];
                string posS     = elements[4];
                Class  excClass = null;
                try
                {
                    excClass = Class.forName(excName);
                    RecognitionException e =
                        (RecognitionException)excClass.newInstance();
                    e.index = int.Parse(indexS);
                    e.line  = int.Parse(lineS);
                    e.charPositionInLine = int.Parse(posS);
                    listener.recognitionException(e);
                }
                catch (ClassNotFoundException cnfe)
                {
                    Console.Error.println("can't find class " + cnfe);
                    cnfe.printStackTrace(Console.Error);
                }
                catch (InstantiationException ie)
                {
                    Console.Error.println("can't instantiate class " + ie);
                    ie.printStackTrace(Console.Error);
                }
                catch (IllegalAccessException iae)
                {
                    Console.Error.println("can't access class " + iae);
                    iae.printStackTrace(Console.Error);
                }
#endif
            }
            else if (elements[0].Equals("beginResync"))
            {
                listener.BeginResync();
            }
            else if (elements[0].Equals("endResync"))
            {
                listener.EndResync();
            }
            else if (elements[0].Equals("terminate"))
            {
                listener.Terminate();
            }
            else if (elements[0].Equals("semanticPredicate"))
            {
                bool   result        = bool.Parse(elements[1]);
                string predicateText = elements[2];
                predicateText = UnEscapeNewlines(predicateText);
                listener.SemanticPredicate(result,
                                           predicateText);
            }
            else if (elements[0].Equals("consumeNode"))
            {
                ProxyTree node = DeserializeNode(elements, 1);
                listener.ConsumeNode(node);
            }
            else if (elements[0].Equals("LN"))
            {
                int       i    = int.Parse(elements[1]);
                ProxyTree node = DeserializeNode(elements, 2);
                listener.LT(i, node);
            }
            else if (elements[0].Equals("createNodeFromTokenElements"))
            {
                int    ID   = int.Parse(elements[1]);
                int    type = int.Parse(elements[2]);
                string text = elements[3];
                text = UnEscapeNewlines(text);
                ProxyTree node = new ProxyTree(ID, type, -1, -1, -1, text);
                listener.CreateNode(node);
            }
            else if (elements[0].Equals("createNode"))
            {
                int ID         = int.Parse(elements[1]);
                int tokenIndex = int.Parse(elements[2]);
                // create dummy node/token filled with ID, tokenIndex
                ProxyTree  node  = new ProxyTree(ID);
                ProxyToken token = new ProxyToken(tokenIndex);
                listener.CreateNode(node, token);
            }
            else if (elements[0].Equals("nilNode"))
            {
                int       ID   = int.Parse(elements[1]);
                ProxyTree node = new ProxyTree(ID);
                listener.NilNode(node);
            }
            else if (elements[0].Equals("errorNode"))
            {
                // TODO: do we need a special tree here?
                int    ID   = int.Parse(elements[1]);
                int    type = int.Parse(elements[2]);
                string text = elements[3];
                text = UnEscapeNewlines(text);
                ProxyTree node = new ProxyTree(ID, type, -1, -1, -1, text);
                listener.ErrorNode(node);
            }
            else if (elements[0].Equals("becomeRoot"))
            {
                int       newRootID = int.Parse(elements[1]);
                int       oldRootID = int.Parse(elements[2]);
                ProxyTree newRoot   = new ProxyTree(newRootID);
                ProxyTree oldRoot   = new ProxyTree(oldRootID);
                listener.BecomeRoot(newRoot, oldRoot);
            }
            else if (elements[0].Equals("addChild"))
            {
                int       rootID  = int.Parse(elements[1]);
                int       childID = int.Parse(elements[2]);
                ProxyTree root    = new ProxyTree(rootID);
                ProxyTree child   = new ProxyTree(childID);
                listener.AddChild(root, child);
            }
            else if (elements[0].Equals("setTokenBoundaries"))
            {
                int       ID   = int.Parse(elements[1]);
                ProxyTree node = new ProxyTree(ID);
                listener.SetTokenBoundaries(
                    node,
                    int.Parse(elements[2]),
                    int.Parse(elements[3]));
            }
            else
            {
                Console.Error.WriteLine("unknown debug event: " + line);
            }
        }