/// <returns>Either CurrentScope, a BlockStatement object that is associated with the parent method or a complete new DModule object</returns>
        public static object FindCurrentCaretContext(string code,
			IBlockNode CurrentScope,
			int caretOffset, CodeLocation caretLocation,
			out ParserTrackerVariables TrackerVariables)
        {
            bool ParseDecl = false;

            int blockStart = 0;
            var blockStartLocation = CurrentScope.BlockStartLocation;

            if (CurrentScope is DMethod)
            {
                var block = (CurrentScope as DMethod).GetSubBlockAt(caretLocation);

                if (block != null)
                    blockStart = DocumentHelper.LocationToOffset(code, blockStartLocation = block.Location);
                else
                    return FindCurrentCaretContext(code, CurrentScope.Parent as IBlockNode, caretOffset, caretLocation, out TrackerVariables);
            }
            else if (CurrentScope != null)
            {
                if (CurrentScope.BlockStartLocation.IsEmpty || caretLocation < CurrentScope.BlockStartLocation && caretLocation > CurrentScope.Location)
                {
                    ParseDecl = true;
                    blockStart = DocumentHelper.LocationToOffset(code, blockStartLocation = CurrentScope.Location);
                }
                else
                    blockStart = DocumentHelper.LocationToOffset(code, CurrentScope.BlockStartLocation);
            }

            if (blockStart >= 0 && caretOffset - blockStart > 0)
            {
                var codeToParse = code.Substring(blockStart, caretOffset - blockStart);

                var sr = new StringReader(codeToParse);
                var psr = DParser.Create(sr);

                /* Deadly important! For correct resolution behaviour,
                 * it is required to set the parser virtually to the blockStart position,
                 * so that everything using the returned object is always related to
                 * the original code file, not our code extraction!
                 */
                psr.Lexer.SetInitialLocation(blockStartLocation);

                object ret = null;

                if (CurrentScope == null || CurrentScope is IAbstractSyntaxTree)
                    ret = psr.Parse();
                else if (CurrentScope is DMethod)
                {
                    psr.Step();
                    ret = psr.BlockStatement(CurrentScope);
                }
                else if (CurrentScope is DModule)
                    ret = psr.Root();
                else
                {
                    psr.Step();
                    if (ParseDecl)
                    {
                        var ret2 = psr.Declaration(CurrentScope);

                        if (ret2 != null && ret2.Length > 0)
                            ret = ret2[0];
                    }
                    else
                    {
                        DBlockNode bn = null;
                        if (CurrentScope is DClassLike)
                        {
                            var t = new DClassLike((CurrentScope as DClassLike).ClassType);
                            t.AssignFrom(CurrentScope);
                            bn = t;
                        }
                        else if (CurrentScope is DEnum)
                        {
                            var t = new DEnum();
                            t.AssignFrom(CurrentScope);
                            bn = t;
                        }

                        bn.Clear();

                        psr.ClassBody(bn);
                        ret = bn;
                    }
                }

                TrackerVariables = psr.TrackerVariables;
                sr.Close();

                return ret;
            }

            TrackerVariables = null;

            return null;
        }
        public static ISyntaxRegion FindCurrentCaretContext(IEditorData editor, 
			out ParserTrackerVariables trackerVariables, 
			ref IBlockNode currentScope, 
			out IStatement currentStatement)
        {
            if(currentScope == null)
                currentScope = DResolver.SearchBlockAt (editor.SyntaxTree, editor.CaretLocation, out currentStatement);

            if (currentScope == null) {
                trackerVariables = null;
                currentStatement = null;
                return null;
            }

            bool ParseDecl = false;

            int blockStart = 0;
            var blockStartLocation = currentScope != null ? currentScope.BlockStartLocation : editor.CaretLocation;

            if (currentScope is DMethod)
            {
                var block = (currentScope as DMethod).GetSubBlockAt(editor.CaretLocation);

                if (block != null)
                    blockStart = DocumentHelper.GetOffsetByRelativeLocation (editor.ModuleCode, editor.CaretLocation, editor.CaretOffset, blockStartLocation = block.Location);
                else {
                    currentScope = currentScope.Parent as IBlockNode;
                    return FindCurrentCaretContext (editor, out trackerVariables, ref currentScope, out currentStatement);
                }
            }
            else if (currentScope != null)
            {
                if (currentScope.BlockStartLocation.IsEmpty || (editor.CaretLocation < currentScope.BlockStartLocation && editor.CaretLocation > currentScope.Location))
                {
                    ParseDecl = true;
                    blockStart = DocumentHelper.GetOffsetByRelativeLocation(editor.ModuleCode, editor.CaretLocation, editor.CaretOffset, blockStartLocation = currentScope.Location);
                }
                else
                    blockStart = DocumentHelper.GetOffsetByRelativeLocation(editor.ModuleCode, editor.CaretLocation, editor.CaretOffset, currentScope.BlockStartLocation);
            }

            if (blockStart >= 0 && editor.CaretOffset - blockStart > 0)
                using (var sr = new Misc.StringView(editor.ModuleCode, blockStart, editor.CaretOffset - blockStart))
                {
                    var psr = DParser.Create(sr);

                    /*					 Deadly important! For correct resolution behaviour,
                     * it is required to set the parser virtually to the blockStart position,
                     * so that everything using the returned object is always related to
                     * the original code file, not our code extraction!
                     */
                    psr.Lexer.SetInitialLocation(blockStartLocation);

                    ISyntaxRegion ret = null;

                    if (currentScope == null)
                        ret = psr.Parse();
                    else if (currentScope is DMethod)
                    {
                        psr.Step();
                        var dm = currentScope as DMethod;
                        dm.Clear();

                        if ((dm.SpecialType & DMethod.MethodType.Lambda) != 0 &&
                            psr.Lexer.LookAhead.Kind != DTokens.OpenCurlyBrace) {
                            psr.LambdaSingleStatementBody (dm);
                            ret = dm.Body;
                        } else {
                            var methodRegion = DTokens.Body;

                            if (dm.In != null && blockStartLocation == dm.In.Location)
                                methodRegion = DTokens.In;

                            if (dm.Out != null && blockStartLocation == dm.Out.Location)
                                methodRegion = DTokens.Out;

                            var newBlock = psr.BlockStatement (currentScope);
                            ret = newBlock;

                            switch (methodRegion) {
                                case DTokens.Body:
                                    newBlock.EndLocation = dm.Body.EndLocation;
                                    dm.Body = newBlock;
                                    break;
                                case DTokens.In:
                                    newBlock.EndLocation = dm.In.EndLocation;
                                    dm.In = newBlock;
                                    break;
                                case DTokens.Out:
                                    newBlock.EndLocation = dm.Out.EndLocation;
                                    dm.Out = newBlock;
                                    break;
                            }
                        }
                    }
                    else if (currentScope is DModule)
                        ret = psr.Root();
                    else
                    {
                        psr.Step();
                        if (ParseDecl)
                        {
                            var ret2 = psr.Declaration(currentScope);

                            if (ret2 != null && ret2.Length > 0)
                                ret = ret2[0];
                        }
                        else if (currentScope is DClassLike)
                        {
                            var t = new DClassLike((currentScope as DClassLike).ClassType);
                            t.AssignFrom(currentScope);
                            t.Clear();
                            psr.ClassBody(t);
                            ret = t;
                        }
                        else if (currentScope is DEnum)
                        {
                            var t = new DEnum();
                            t.AssignFrom(currentScope);
                            t.Clear();
                            psr.EnumBody(t);
                            ret = t;
                        }
                    }

                    currentScope = DResolver.SearchBlockAt (currentScope,
                        psr.Lexer.CurrentToken != null ? psr.Lexer.CurrentToken.EndLocation : editor.CaretLocation,
                        out currentStatement);
                    trackerVariables = psr.TrackerVariables;
                    return ret;
                }

            trackerVariables = null;
            currentStatement = null;
            return null;
        }