public CodeDOMDocumentServiceAHK(ProjectItemCodeDocument document)
            : base(document) {


                #region Create Language Master Root

                _root = new CodeTypeDeclarationEx(null, "Global") { CodeDocumentItem = document };


                #region Create  auto exec method for AHK Scripts

                _root.Members.Add(_autoexec = new CodeMemberMethodExAHK(true)
                {
                    Name = "AutoExec",
                    Attributes = MemberAttributes.Public | MemberAttributes.Static,
                    DefiningType = _languageRoot,
                    ReturnType = new CodeTypeReference(typeof(void)),
                    LinePragma = new CodeLinePragma("all", 0),
                    IsHidden = true,
                    CodeDocumentItem = document
                });

                #endregion

                #region Setup Base Object

                var baseobj = new CodeTypeDeclarationEx(null, "Object")
                {
                    CodeDocumentItem = document,
                    IsClass = true,
                    IsBuildInType = true
                };
                baseobj.Comments.Add(new CodeCommentStatement("Base Object of all other Custom Objects", true));

                CodeMemberMethodExAHK method;

                #region Object.Insert

                method = new CodeMemberMethodExAHK(true)
                {
                    Name = "Insert",
                    CodeDocumentItem = document,
                    IsDefaultMethodInvoke = true,
                    IsTraditionalCommand = false,
                };
                method.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(object)), "key"));
                method.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(object)), "value"));
                method.Comments.Add(new CodeCommentStatement("Inserts key-value pairs into the object, automatically adjusting existing keys if appropriate.", true));
                method.ReturnType = new CodeTypeReference(typeof(bool));
                baseobj.Members.Add(method);

                #endregion

                #region Object.Remove

                method = new CodeMemberMethodExAHK(true)
                {
                    Name = "Remove",
                    Project = document.Project,
                    IsDefaultMethodInvoke = true,
                    IsTraditionalCommand = false
                };
                method.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(object)), "key"));
                method.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(object)), "value"));
                method.Comments.Add(new CodeCommentStatement("Removes key-value pairs from an object.", true));
                method.ReturnType = new CodeTypeReference(typeof(bool));
                baseobj.Members.Add(method);

                #endregion

                #region Object.Clone

                method = new CodeMemberMethodExAHK(true)
                {
                    Name = "Clone",
                    CodeDocumentItem = document,
                    IsDefaultMethodInvoke = true,
                    IsTraditionalCommand = false
                };
                method.Comments.Add(new CodeCommentStatement("Returns a shallow copy of the object.", true));
                method.ReturnType = new CodeTypeReference(typeof(object));
                baseobj.Members.Add(method);

                #endregion

                #region Object.MinIndex

                method = new CodeMemberMethodExAHK(true)
                {
                    Name = "MinIndex",
                    CodeDocumentItem = document,
                    IsDefaultMethodInvoke = true,
                    IsTraditionalCommand = false
                };
                method.Comments.Add(new CodeCommentStatement("If any integer keys are present, MinIndex returns the lowest and MaxIndex returns the highest. Otherwise an empty string is returned.", true));
                method.ReturnType = new CodeTypeReference(typeof(int));
                baseobj.Members.Add(method);

                #endregion

                #region Object.MaxIndex

                method = new CodeMemberMethodExAHK(true)
                {
                    Name = "MaxIndex",
                    CodeDocumentItem = document,
                    IsDefaultMethodInvoke = true,
                    IsTraditionalCommand = false
                };
                method.Comments.Add(new CodeCommentStatement("If any integer keys are present, MinIndex returns the lowest and MaxIndex returns the highest. Otherwise an empty string is returned.", true));
                method.ReturnType = new CodeTypeReference(typeof(int));
                baseobj.Members.Add(method);

                #endregion

                #region Object.SetCapacity

                method = new CodeMemberMethodExAHK(true)
                {
                    Name = "SetCapacity",
                    CodeDocumentItem = document,
                    IsDefaultMethodInvoke = true,
                    IsTraditionalCommand = false
                };
                method.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "MaxItemsOrKey"));
                method.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "ByteSize"));
                method.Comments.Add(new CodeCommentStatement("If any integer keys are present, MinIndex returns the lowest and MaxIndex returns the highest. Otherwise an empty string is returned.", true));
                method.ReturnType = new CodeTypeReference(typeof(int));
                baseobj.Members.Add(method);

                #endregion

                #region Object.GetCapacity

                method = new CodeMemberMethodExAHK(true)
                {
                    Name = "GetCapacity",
                    CodeDocumentItem = document,
                    IsDefaultMethodInvoke = true,
                    IsTraditionalCommand = false
                };
                method.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "Key"));
                method.Comments.Add(new CodeCommentStatement("Returns the current capacity of an object or one of its fields.", true));
                method.ReturnType = new CodeTypeReference(typeof(int));
                baseobj.Members.Add(method);

                #endregion

                #region Object.HasKey

                method = new CodeMemberMethodExAHK(true)
                {
                    Name = "HasKey",
                    CodeDocumentItem = document,
                    IsDefaultMethodInvoke = true,
                    IsTraditionalCommand = false
                };
                method.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "Key"));
                method.Comments.Add(new CodeCommentStatement("Returns true if Key is associated with a value (even '') within Object, otherwise false.", true));
                method.ReturnType = new CodeTypeReference(typeof(bool));
                baseobj.Members.Add(method);

                #endregion

                #region Object._NewEnum

                method = new CodeMemberMethodExAHK(true)
                {
                    Name = "_NewEnum",
                    CodeDocumentItem = document,
                    IsDefaultMethodInvoke = true,
                    IsTraditionalCommand = false
                };

                method.Comments.Add(new CodeCommentStatement("Returns a new enumerator to enumerate this object's key-value pairs.", true));
                method.ReturnType = new CodeTypeReference(typeof(IEnumerator));
                baseobj.Members.Add(method);

                #endregion


                _root.Members.Add(baseobj);

                #endregion

                // Import build-in members
                foreach(var m in document.CodeLanguage.BuildInMembers) {
                    var codeobj = m as ICodeMemberEx;
                    if(codeobj != null) {
                        codeobj.Project = document.Project;
                    }
                    _root.Members.Add(m);
                }

                #endregion

                _rootLanguageSnapshot = _root;
        }
        protected async Task CompileTokenFile(CancellationToken cancellationToken) {
            try {
                await TaskEx.Run(() => {
                    _languageRoot = new CodeTypeDeclarationRoot() { Project = _document.Project };
                    CodeTypeDeclarationEx initialparent = _languageRoot;


                    cancellationToken.ThrowIfCancellationRequested();

                    _dependingOnSave = this.DependingOn;

                    #region Clean Up

                    _document.Project.Solution.ErrorService.ClearAllErrorsFrom(_document, Errors.ErrorSource.ASTParser);
                    _codeRangeManager.Clear();

                    #endregion

                    #region Merge DependingOn Members

                    if(_dependingOnSave == null) {
                        // merge super base members
                        _languageRoot.Members.AddRange(_root.Members);
                        firstAfterNull = true;
                    } else {

                        //if(!_project.IsInUpdate) {
                        //    if(firstAfterNull) {
                        //        ignoreDependingOnce = true;
                        //        _dependingOnSave.CompileTokenFileAsync();
                        //        firstAfterNull = false;
                        //    }
                        //    _dependingOnSave.WaitUntilUpdated(200);
                        //}
                        
                        _languageRoot.Members.AddRange(_dependingOnSave.GetRootTypeSnapshot().Members);
                    }

                    #endregion

                    var codeLineMap = _document.SegmentService.GetCodeSegmentLinesMap();
                    CodeTypeDeclaration parent = initialparent;
                    Stack<CodeSegment> paramstack = new Stack<CodeSegment>();
                    int linecnt = 0;
                    if(codeLineMap.Keys.Any())
                        linecnt = codeLineMap.Keys.Max();

                    CodeTokenLine line;

                    Stack<CodeTypeDeclarationEx> parentHirarchy = new Stack<CodeTypeDeclarationEx>();
                    int bcc = 0;
                    parentHirarchy.Push(initialparent);

                    cancellationToken.ThrowIfCancellationRequested();

                    #region Parse

                    for(int i = 0; i <= linecnt; i++) {

                        cancellationToken.ThrowIfCancellationRequested();

                        if(codeLineMap.ContainsKey(i))
                            line = codeLineMap[i];
                        else
                            continue;

                        // is class definition?:

                        #region Parse Class Definition

                        var classkeywordSegment = line.CodeSegments[0].ThisOrNextOmit(whitespacetokenNewLines);
                        if(classkeywordSegment != null && classkeywordSegment.Token == Token.KeyWord && classkeywordSegment.TokenString.Equals("class", StringComparison.CurrentCultureIgnoreCase)) {
                            var classNameSegment = classkeywordSegment.FindNextOnSameLine(Token.Identifier);
                            if(classNameSegment != null) {

                                var next = classNameSegment.NextOmit(whitespacetokenNewLines);
                                if(next != null) {
                                    CodeTypeDeclarationEx thisparent = parentHirarchy.Any() ? parentHirarchy.Peek() : _languageRoot;
                                    CodeTypeReferenceEx basecls = null;
                                    CodeSegment refBaseClass = null;
                                    if(next.Token == Token.KeyWord && next.TokenString.Equals("extends", StringComparison.InvariantCultureIgnoreCase)) {
                                        refBaseClass = next.NextOmit(whitespacetokenNewLines);

                                        if(refBaseClass != null) {
                                            if(refBaseClass.Token == Token.Identifier) {
                                                refBaseClass.CodeDOMObject = basecls = new CodeTypeReferenceEx(_document, refBaseClass.TokenString, thisparent);
                                                next = refBaseClass.NextOmit(whitespacetokenNewLines);
                                            } else {
                                                RegisterError(_document, next.Next, "Expected: Class Name Identifier");
                                                next = next.NextOmit(whitespacetokenNewLines);
                                            }
                                        } else {
                                            if(next.Next != null && next.Next.Token != Token.BlockOpen) {
                                                RegisterError(_document, next.Next, "Expected: Class Name Identifier");
                                                next = next.NextOmit(whitespacetokenNewLines);
                                            }
                                        }
                                    }

                                    if(next != null) {
                                        if(next.Token == Token.BlockOpen) {

                                            #region Add Class Declaration

                                            CodeSegment classBodyStart = next;

                                            var type = new CodeTypeDeclarationEx(_document, classNameSegment.TokenString)
                                            {
                                                IsClass = true,
                                                LinePragma = CreatePragma(classNameSegment, _document.FilePath),
                                                CodeDocumentItem = _document
                                            };
                                            classNameSegment.CodeDOMObject = type;


                                            // check if this type was alread defined in this scope
                                            if(thisparent.GetInheritedMembers().Contains(type)) {
                                                RegisterError(_document, classNameSegment, "oh my dear, this class already exisits in the current scope!");
                                            } else {

                                                #region Check & Resolve Baseclass

                                                if(basecls != null) {
                                                    //check if we have a circual interhance tree
                                                    var baseclassImpl = basecls.ResolveTypeDeclarationCache();
                                                    if(baseclassImpl != null && baseclassImpl.IsSubclassOf(new CodeTypeReferenceEx(_document, classNameSegment.TokenString, thisparent))) {
                                                        //circular dependency detected!!
                                                        RegisterError(_document, refBaseClass, "Woops you just produced a circular dependency in your inheritance tree!");
                                                    } else {
                                                        if(basecls != null)
                                                            type.BaseTypes.Add(basecls);
                                                        else
                                                            type.BaseTypes.Add(new CodeTypeReferenceEx(_document, "Object", thisparent) { ResolvedTypeDeclaration = _superBase });
                                                    }
                                                }

                                                #endregion


                                                // extract class documentation Comment
                                                var comment = ExtractComment(classkeywordSegment);
                                                if(comment != null)
                                                    type.Comments.Add(comment);


                                                // Add it to the CodeDOM Tree
                                                thisparent.Members.Add(type);
                                                type.Parent = thisparent;
                                            }

                                            // Create a CodeRange Item
                                            int startOffset = classBodyStart.Range.Offset;
                                            var classBodyEnd = classBodyStart.FindClosingBracked(true);
                                            if(classBodyEnd != null) {
                                                int length = (classBodyEnd.Range.Offset - startOffset);
                                                _codeRangeManager.Add(new CodeRange(new SimpleSegment(startOffset, length), type));
                                            } else {
                                                RegisterError(_document, classBodyStart, "Expected: " + Token.BlockClosed);
                                            }

                                            parentHirarchy.Push(type);
                                            bcc++;

                                            i = classBodyStart.LineNumber; // jumt to:  class Foo { * <---|
                                            continue;

                                            #endregion

                                        } else {
                                            RegisterError(_document, next, "Expected: " + Token.BlockOpen);
                                            i = (next.Next != null) ? next.Next.LineNumber : next.LineNumber;
                                        }
                                    }
                                }
                            }
                        }

                        #endregion

                        // adjust some asumptions the tokenizer has made

                        if(parentHirarchy.Count > 1) {
                            // if we are in a class body, we can't have a traditional command invoke
                            foreach(var s in line.CodeSegments)
                                if(s.Token == Token.TraditionalCommandInvoke) {
                                    s.Token = Token.Identifier;
                                    break;
                                }
                        }


                        // is method definition?:

                        #region Analyze for Method Definition

                        var methodSegment = line.CodeSegments[0].ThisOrNextOmit(whitespacetokenNewLines);
                        if(methodSegment != null && methodSegment.Token == Token.Identifier) {
                            var methodSignatureStart = methodSegment.Next;
                            if(methodSignatureStart != null && methodSignatureStart.Token == Token.LiteralBracketOpen) {
                                var methodSignatureEnd = methodSignatureStart.FindClosingBracked(false);
                                if(methodSignatureEnd != null) {
                                    var startMethodBody = methodSignatureEnd.NextOmit(whitespacetokenNewLinesComments);
                                    if(startMethodBody != null && startMethodBody.Token == Token.BlockOpen) {
                                        // jup we have a method definition here.
                                        // Method body starts at startMethodBody


                                        CodeTypeDeclarationEx thisparent = parentHirarchy.Any() ? parentHirarchy.Peek() : _languageRoot;
                                        bool hasDeclarationError = false;

                                        #region Generate Method Definition DOM

                                        var method = new CodeMemberMethodExAHK(_document)
                                        {
                                            Name = methodSegment.TokenString,
                                            LinePragma = CreatePragma(methodSegment, _document.FilePath),
                                            CodeDocumentItem = _document,
                                            ReturnType = new CodeTypeReferenceEx(_document, typeof(object))
                                        };
                                        methodSegment.CodeDOMObject = method;

                                        //check if this method is not already defined elsewere in current scope

                                        var equalmethods = from m in thisparent.Members.Cast<CodeTypeMember>()
                                                           let meth = m as CodeMemberMethodExAHK
                                                           where meth != null && !meth.IsBuildInType && meth.Equals(method)
                                                           select meth;


                                        if(equalmethods.Any()) {
                                            RegisterError(_document, methodSegment,
                                                string.Format("The Methodename '{0}' is already used in the current scope!", method.Name));
                                            hasDeclarationError = true;
                                        } else {


                                            // extract Method Comment
                                            var comment = ExtractComment(methodSegment);
                                            if(comment != null)
                                                method.Comments.Add(comment);

                                            // extract method params
                                            paramstack.Clear();
                                            CodeSegment previous = methodSignatureStart;

                                            // get method params:
                                            while(true) {
                                                var current = previous.Next;
                                                if(current.Token == Token.Identifier || current.Token == Token.KeyWord) {
                                                    paramstack.Push(current);
                                                } else if(current.Token == Token.ParameterDelemiter || current.Token == Token.LiteralBracketClosed) {
                                                    // end of param reached:
                                                    if(paramstack.Count == 1) {
                                                        // thread one param as the untyped argument, type of Object
                                                        method.Parameters.Add(new CodeParameterDeclarationExpressionEx(typeof(object), paramstack.Pop().TokenString)
                                                            {
                                                                Direction = FieldDirection.In
                                                            });
                                                    } else if(paramstack.Count == 2) {

                                                        CodeParameterDeclarationExpressionEx param;

                                                        var second = paramstack.Pop();
                                                        var first = paramstack.Pop();

                                                        //handle byref ->
                                                        if(first.Token == Token.KeyWord && first.TokenString.Equals(BY_REF, StringComparison.InvariantCultureIgnoreCase)) {
                                                            param = new CodeParameterDeclarationExpressionEx(typeof(object), second.TokenString);
                                                            param.Direction = FieldDirection.Ref;
                                                        } else {
                                                            param = new CodeParameterDeclarationExpressionEx(
                                                                new CodeTypeReferenceEx(_document, first.TokenString, thisparent),
                                                                paramstack.Pop().TokenString);
                                                        }

                                                        // thread two param as the type and argument
                                                        method.Parameters.Add(param);
                                                    }
                                                    if(current.Token == Token.LiteralBracketClosed)
                                                        break;
                                                } else if(current.Token == Token.NewLine){
                                                    break;
                                                }
                                                previous = current;
                                            }
                                        }
                                        #endregion

                                        // Method body ends at
                                        var endMethodBody = startMethodBody.FindClosingBracked(true);
                                        if(endMethodBody != null) {

                                            // get method statements
                                            method.Statements.AddRange(
                                                CollectAllCodeStatements(cancellationToken, thisparent, codeLineMap, startMethodBody.LineNumber + 1, endMethodBody.LineNumber));


                                            // add it to the code DOM Tree
                                            if(!hasDeclarationError) {
                                                thisparent.Members.Add(method);
                                                method.DefiningType = thisparent;
                                            }


                                            // Create a CodeRange Item
                                            int startOffset = startMethodBody.Range.Offset;
                                            int length = (endMethodBody.Range.Offset - startOffset);

                                            _codeRangeManager.Add(new CodeRange(new SimpleSegment(startOffset, length), method));

                                            // move the scanpointer to the method end:
                                            i = endMethodBody.LineNumber;
                                            continue;
                                        } else {
                                            RegisterError(_document, startMethodBody, "Missing: " + Token.BlockClosed);


                                        }
                                    }
                                }
                            }
                        }

                        #endregion


                        // is class property / field

                        #region Parse Class Properties / Fields

                        if(parentHirarchy.Count > 1) {
                            // we must be in a class to have method properties
                            // extract keywords & Identifiers untill we reach
                            // any otherToken - omit whitespaces 

                            List<CodeSegment> declarationStack = new List<CodeSegment>();

                            CodeSegment current = line.CodeSegments[0].ThisOrNextOmit(whitespacetokens);

                            while(current != null) {
                                if(current.Token == Token.WhiteSpace) {
                                    //ignore white spaces
                                } else if(current.Token == Token.Identifier || current.Token == Token.KeyWord) {
                                    declarationStack.Add(current);
                                } else {
                                    break;
                                }
                                current = current.Next;
                            }

                            switch(declarationStack.Count) {


                                case 0:
                                    break;
                                case 1:
                                    // instance field definition
                                    if(declarationStack[0].Token == Token.Identifier) {

                                        // this is an untyped instance class field declaration

                                        var propertyType = new CodeTypeReference(typeof(object));
                                        var memberprop = new CodeMemberPropertyEx(_document)
                                        {
                                            Name = declarationStack[0].TokenString,
                                            Attributes = MemberAttributes.Public,
                                            Type = propertyType,
                                            LinePragma = CreatePragma(declarationStack[0], _document.FilePath)
                                        };
                                        declarationStack[0].CodeDOMObject = memberprop;
                                        parentHirarchy.Peek().Members.Add(memberprop);

                                    } else {
                                        RegisterError(_document, declarationStack[0], string.Format("Unexpected Token: {0}", declarationStack[0].Token));
                                    }

                                    break;

                                case 2:
                                    // we have two members in the decalration stack
                                    // expected token flows
                                    // keyword - identifier:  static Field, int Field
                                    // identifier - identifier: Car myTypedCarField

                                    // for the time beeing, AHK just supports static Field

                                    if(declarationStack[0].Token == Token.KeyWord
                                        && declarationStack[0].TokenString.Equals(MODIFIER_STATIC, StringComparison.InvariantCultureIgnoreCase)) {

                                        if(declarationStack[1].Token == Token.Identifier) {

                                            // this is an untyped static class field declaration

                                            var propertyType = new CodeTypeReference(typeof(object));
                                            var memberprop = new CodeMemberPropertyEx(_document)
                                            {
                                                Name = declarationStack[1].TokenString,
                                                Attributes = MemberAttributes.Public | MemberAttributes.Static,
                                                Type = propertyType,
                                                LinePragma = CreatePragma(declarationStack[1], _document.FilePath)
                                            };
                                            declarationStack[1].CodeDOMObject = memberprop;
                                            parentHirarchy.Peek().Members.Add(memberprop);
                                            

                                        } else {
                                            RegisterError(_document, declarationStack[0], string.Format("Expected: {0}", Token.Identifier));

                                        }

                                    } else {
                                        RegisterError(_document, declarationStack[0], string.Format("Unexpected '{0}' in Class Body", declarationStack[0].TokenString));
                                    }
                                    break;

                                default:
                                    for(int ci = 0; ci < declarationStack.Count; ci++) {
                                        RegisterError(_document, declarationStack[ci], string.Format("To much declaration Members", declarationStack[0].Token));
                                    }
                                    break;

                            }

                        }

                        #endregion


                        #region Parse Remaining Tokens

                        if(codeLineMap.ContainsKey(i)) {
                            var lineBlock = codeLineMap[i];
                            CodeTypeDeclarationEx thisparent = parentHirarchy.Any() ? parentHirarchy.Peek() : _languageRoot;

                            foreach(var segment in lineBlock.CodeSegments) {

                                cancellationToken.ThrowIfCancellationRequested();

                                if(segment.Token == Token.BlockOpen) {
                                    bcc++;
                                } else if(segment.Token == Token.BlockClosed) {
                                    bcc--;
                                    if(parentHirarchy.Count - 2 == bcc) {
                                        if(parentHirarchy.Any())
                                            parentHirarchy.Pop();
                                    }
                                }
                            }
                            _autoexec.Statements.AddRange(
                                            CollectAllCodeStatements(cancellationToken, thisparent, codeLineMap, i, i));

                        } else
                            continue;

                        #endregion
                    }

                    #endregion

                    AnalyzeAST(cancellationToken);

                    lock(_rootLanguageSnapshotLOCK) {
                        _rootLanguageSnapshot = _languageRoot;
                    }
                });
            } catch(OperationCanceledException) {
                throw;
            }
        }