public IParseInformation DoParseFile(string fileName, string fileContent)
        {
            IParser parser = parserService.GetParser (fileName);

            if (parser == null) {
                return null;
            }

            parser.LexerTags = new string[] { "HACK", "TODO", "UNDONE", "FIXME" };

            ICompilationUnitBase parserOutput = null;

            if (fileContent == null) {
                lock (databases) {
                    foreach (object ob in databases.Values) {
                        ProjectCodeCompletionDatabase db = ob as ProjectCodeCompletionDatabase;
                        if (db != null) {
                            if (db.Project.IsFileInProject (fileName))
                                fileContent = db.Project.GetParseableFileContent(fileName);
                        }
                    }
                }
            }

            if (fileContent != null) {
                parserOutput = parser.Parse(fileName, fileContent);
            } else {
                parserOutput = parser.Parse(fileName);
            }

            ParseInformation parseInformation = GetCachedParseInformation (fileName);
            bool newInfo = false;

            if (parseInformation == null) {
                parseInformation = new ParseInformation();
                newInfo = true;
            }

            if (parserOutput.ErrorsDuringCompile) {
                parseInformation.DirtyCompilationUnit = parserOutput;
            } else {
                parseInformation.ValidCompilationUnit = parserOutput;
                parseInformation.DirtyCompilationUnit = null;
            }

            if (newInfo) {
                AddToCache (parseInformation, fileName);
            }

            OnParseInformationChanged (new ParseInformationEventArgs (fileName, parseInformation));
            return parseInformation;
        }
        void AddToCache(ParseInformation info, string fileName)
        {
            lock (parsings)
            {
                if (parsings.Count >= MAX_PARSING_CACHE_SIZE)
                {
                    DateTime tim = DateTime.MaxValue;
                    string toDelete = null;
                    foreach (DictionaryEntry pce in parsings)
                    {
                        DateTime ptim = ((ParsingCacheEntry)pce.Value).AccessTime;
                        if (ptim < tim) {
                            tim = ptim;
                            toDelete = pce.Key.ToString();
                        }
                    }
                    parsings.Remove (toDelete);
                }

                ParsingCacheEntry en = new ParsingCacheEntry();
                en.ParseInformation = info;
                en.AccessTime = DateTime.Now;
                parsings [fileName] = en;
            }
        }