public void EnteringNode(object sender, XmlTraverseEventArgs e)
 {
     var node = e.Node;
     switch (node.LocalName)
     {
         // Nodes
         case AstConstants.Nodes.Stmt_Interface:
             currentInterface = new Interface(node)
             {
                 StartLine = AstNode.GetStartLine(node),
                 EndLine = AstNode.GetEndLine(node)
             };
             break;
         case AstConstants.Nodes.Stmt_Class:
             currentClass = new Class(node)
             {
                 StartLine = AstNode.GetStartLine(node),
                 EndLine = AstNode.GetEndLine(node)
             };
             break;
         case AstConstants.Nodes.Stmt_ClassMethod:
             ClassMethodEnter(node);
             break;
         case AstConstants.Nodes.Stmt_Property:
             inPropertyDeclarations = true;
             break;
         case AstConstants.Nodes.Stmt_PropertyProperty:
             currentProperty = new Property(node)
             {
                 StartLine = AstNode.GetStartLine(node),
                 EndLine = AstNode.GetEndLine(node),
                 VisibilityModifiers = propertyModifiers,
             };
             break;
         case AstConstants.Nodes.Stmt_Function:
             currentFunctions.Push(new Function(node)
             {
                 StartLine = AstNode.GetStartLine(node),
                 EndLine = AstNode.GetEndLine(node)
             });
             functionClosureOrder.Push(FunctionClosure.Function);
             break;
         case AstConstants.Nodes.Expr_Closure:
             currentClosures.Push(new ExtractorClosureInfo()
             {
                 Closure = new Closure(node)
                           {
                               StartLine = AstNode.GetStartLine(node),
                               EndLine = AstNode.GetEndLine(node)
                           }
             });
             functionClosureOrder.Push(FunctionClosure.Closure);
             break;
         case AstConstants.Nodes.Param:
             currentParameter = new Parameter(node);
             break;
         case AstConstants.Nodes.Expr_ClosureUse:
             currentClosureUse = new ClosureUse(node);
             break;
         // Subnodes
         case AstConstants.Subnodes.Name:
             Name(node);
             break;
         case AstConstants.Subnodes.Params:
             inParamDeclarations = true;
             break;
         case AstConstants.Subnodes.ByRef:
             Subnode_ByRef_Enter(node);
             break;
         case AstConstants.Subnodes.Variadic:
             if (inParamDeclarations && !parameteVariadicIsSet)
             {
                 currentParameter.IsVariadic = Convert.ToBoolean(node.FirstChild.LocalName);
                 parameteVariadicIsSet = true;
             }
             break;
         case AstConstants.Subnodes.Default:
             if (inParamDeclarations && !parameterDefaultIsSet)
             {
                 currentParameter.IsOptional = node.FirstChild.Prefix != AstConstants.Scalar;
                 parameterDefaultIsSet = true;
             }
             break;
         case AstConstants.Subnodes.Uses:
             if (currentClosures.Any() && currentClosures.Peek().ClosureUses == null && !currentClosures.Peek().ClosureUsagesIsSet)
             {
                 currentClosures.Peek().ClosureUses = new Queue<ClosureUse>();
             }
             break;
         case AstConstants.Subnodes.Var:
             if (currentClosureUse != null)
             {
                 currentClosureUse.Name = node.InnerText;
             }
             break;
         case AstConstants.Subnodes.Type:
             if (inPropertyDeclarations && currentProperty == null)
             {
                 propertyModifiers = (AstConstants.VisibilityModifiers) Enum.Parse(typeof (AstConstants.VisibilityModifiers), node.InnerText);
             }
             break;
     }
 }
 public void LeavingNode(object sender, XmlTraverseEventArgs e)
 {
     var node = e.Node;
     switch (node.LocalName)
     {
         // Nodes
         case AstConstants.Nodes.Stmt_Interface:
             _interfaces.Add(currentInterface);
             currentInterface = null;
             break;
         case AstConstants.Nodes.Stmt_Class:
             _classes.Add(currentClass);
             currentClass = null;
             break;
         case AstConstants.Nodes.Stmt_ClassMethod:
             ClassMethodExit();
             break;
         case AstConstants.Nodes.Stmt_Property:
             inPropertyDeclarations = false;
             propertyModifiers = 0;
             break;
         case AstConstants.Nodes.Stmt_PropertyProperty:
             currentClass.Properties.Add(currentProperty);
             currentProperty = null;
             break;
         case AstConstants.Nodes.Stmt_Function:
             _functions.Add(currentFunctions.Pop());
             functionClosureOrder.Pop();
             break;
         case AstConstants.Nodes.Expr_ClosureUse:
             currentClosures.Peek().ClosureUses.Enqueue(currentClosureUse);
             currentClosureUse = null;
             break;
         case AstConstants.Nodes.Expr_Closure:
             _closures.Add(currentClosures.Pop().Closure);
             functionClosureOrder.Pop();
             break;
         case AstConstants.Nodes.Param:
             parameters.Enqueue(currentParameter);
             currentParameter = null;
             parameteVariadicIsSet = false;
             parameterByRefIsSet = false;
             parameterDefaultIsSet = false;
             break;
         // Subnodes
         case AstConstants.Subnodes.Params:
             ParamsExit();
             break;
         case AstConstants.Subnodes.Uses:
             if (currentClosures.Any())
             {
                 ExtractorClosureInfo closureInfo = currentClosures.Peek();
                 if (!closureInfo.ClosureUsagesIsSet && closureInfo.ClosureUses != null)
                 {
                     closureInfo.Closure.UseParameters = closureInfo.ClosureUses.ToArray();
                     closureInfo.ClosureUsagesIsSet = true;
                 }
             }
             break;
     }
 }