void VisitPreprocessorDirective (ParsedDocument result, SpecialsBag.PreProcessorDirective directive)
		{
			DomLocation loc = new DomLocation (directive.Line, directive.Col);
			switch (directive.Cmd) {
			case Tokenizer.PreprocessorDirective.If:
				conditionalRegions.Push (new ConditionalRegion (visitor.Text));
				ifBlocks.Push (directive);
				ConditionalRegion.Start = loc;
				break;
			case Tokenizer.PreprocessorDirective.Elif:
				CloseConditionBlock (new DomLocation (directive.EndLine, directive.EndCol));
				if (ConditionalRegion != null)
					ConditionalRegion.ConditionBlocks.Add (new ConditionBlock (visitor.Text, loc));
				break;
			case Tokenizer.PreprocessorDirective.Else:
				CloseConditionBlock (new DomLocation (directive.EndLine, directive.EndCol));
				if (ConditionalRegion != null)
					ConditionalRegion.ElseBlock = new DomRegion (loc, DomLocation.Empty);
				break;
			case Tokenizer.PreprocessorDirective.Endif:
				DomLocation endLoc = new DomLocation (directive.EndLine, directive.EndCol);
				CloseConditionBlock (endLoc);
				if (ConditionalRegion != null && !ConditionalRegion.ElseBlock.Start.IsEmpty)
					ConditionalRegion.ElseBlock = new DomRegion (ConditionalRegion.ElseBlock.Start, endLoc);
				AddCurRegion (result, directive.EndLine, directive.EndCol);
				if (ifBlocks.Count > 0) {
					var ifBlock = ifBlocks.Pop ();
					DomRegion dr = new DomRegion (ifBlock.Line, ifBlock.Col, directive.EndLine, directive.EndCol);
					result.Add (new FoldingRegion ("#if " + ifBlock.Arg.Trim (), dr, FoldType.UserRegion, false));
					foreach (var d in elifBlocks) {
						dr.Start = new DomLocation (d.Line, d.Col);
						result.Add (new FoldingRegion ("#elif " + ifBlock.Arg.Trim (), dr, FoldType.UserRegion, false));
					}
					if (elseBlock != null) {
						dr.Start = new DomLocation (elseBlock.Line, elseBlock.Col);
						result.Add (new FoldingRegion ("#else", dr, FoldType.UserRegion, false));
					}
				}
				elseBlock = null;
				break;
			case Tokenizer.PreprocessorDirective.Define:
				result.Add (new PreProcessorDefine (directive.Arg, loc));
				break;
			case Tokenizer.PreprocessorDirective.Region:
				regions.Push (directive);
				break;
			case Tokenizer.PreprocessorDirective.Endregion:
				if (regions.Count > 0) {
					var start = regions.Pop ();
					DomRegion dr = new DomRegion (start.Line, start.Col, directive.EndLine, directive.EndCol);
					result.Add (new FoldingRegion (start.Arg, dr, FoldType.UserRegion, true));
				}
				break;
			}
		}
        void VisitPreprocessorDirective(ParsedDocument result, SpecialsBag.PreProcessorDirective directive)
        {
            TextLocation loc = new TextLocation(directive.Line, directive.Col);

            switch (directive.Cmd)
            {
            case Tokenizer.PreprocessorDirective.If:
                conditionalRegions.Push(new ConditionalRegion(directive.Arg));
                ifBlocks.Push(directive);
                ConditionalRegion.Start = loc;
                break;

            case Tokenizer.PreprocessorDirective.Elif:
                CloseConditionBlock(new TextLocation(directive.EndLine, directive.EndCol));
                if (ConditionalRegion != null)
                {
                    ConditionalRegion.ConditionBlocks.Add(new ConditionBlock(directive.Arg, loc));
                }
                break;

            case Tokenizer.PreprocessorDirective.Else:
                CloseConditionBlock(new TextLocation(directive.EndLine, directive.EndCol));
                if (ConditionalRegion != null)
                {
                    ConditionalRegion.ElseBlock = new DomRegion(loc, TextLocation.Empty);
                }
                break;

            case Tokenizer.PreprocessorDirective.Endif:
                TextLocation endLoc = new TextLocation(directive.EndLine, directive.EndCol);
                CloseConditionBlock(endLoc);
                if (ConditionalRegion != null && !ConditionalRegion.ElseBlock.Begin.IsEmpty)
                {
                    ConditionalRegion.ElseBlock = new DomRegion(ConditionalRegion.ElseBlock.Begin, endLoc);
                }
                AddCurRegion(result, directive.EndLine, directive.EndCol);
                if (ifBlocks.Count > 0)
                {
                    var ifBlock  = ifBlocks.Pop();
                    var ifRegion = new DomRegion(ifBlock.Line, ifBlock.Col, directive.EndLine, directive.EndCol);
                    result.Add(new FoldingRegion("#if " + ifBlock.Arg.Trim(), ifRegion, FoldType.UserRegion, false));
                    foreach (var d in elifBlocks)
                    {
                        var elIlfRegion = new DomRegion(d.Line, d.Col, directive.EndLine, directive.EndCol);
                        result.Add(new FoldingRegion("#elif " + ifBlock.Arg.Trim(), elIlfRegion, FoldType.UserRegion, false));
                    }
                    if (elseBlock != null)
                    {
                        var elseBlockRegion = new DomRegion(elseBlock.Line, elseBlock.Col, elseBlock.Line, elseBlock.Col);
                        result.Add(new FoldingRegion("#else", elseBlockRegion, FoldType.UserRegion, false));
                    }
                }
                elseBlock = null;
                break;

            case Tokenizer.PreprocessorDirective.Define:
                result.Add(new PreProcessorDefine(directive.Arg, loc));
                break;

            case Tokenizer.PreprocessorDirective.Region:
                regions.Push(directive);
                break;

            case Tokenizer.PreprocessorDirective.Endregion:
                if (regions.Count > 0)
                {
                    var       start = regions.Pop();
                    DomRegion dr    = new DomRegion(start.Line, loc.Column, directive.EndLine, directive.EndCol);
                    result.Add(new FoldingRegion(start.Arg, dr, FoldType.UserRegion, true));
                }
                break;
            }
        }