private void OnParserResult(IList <SourceFile> sources, ParserResult result)
        {
            string status;

            switch (result.Kind)
            {
            case ParserResultKind.Error:

                status = string.Format("Parsed '{0}' with errors.", sources.Select(s => s.Path).ToCommaDelimitedList());

                SetDiagnosticsStatus(status);

                foreach (var source in sources)
                {
                    var tblHeaderFile = tblSDKHeaderFiles.Single(f => f.HeaderFileName == source.Path);
                    tblHeaderFile.ParsedSuccessfully = false;
                }

                entities.SaveChanges();

                break;

            case ParserResultKind.FileNotFound:

                status = string.Format("File(s) not found '{0}'.", sources.Select(s => s.Path).ToCommaDelimitedList());
                SetDiagnosticsStatus(status);

                break;

            case ParserResultKind.Success:

                status = string.Format("Parsed '{0}' successfully.", sources.Select(s => s.Path).ToCommaDelimitedList());
                SetDiagnosticsStatus(status);

                foreach (var source in sources)
                {
                    var astContext = source.Options.ASTContext;

                    foreach (var unit in astContext.GetUnits())
                    {
                        var notExists     = false;
                        var directoryPair = includeDirectories.SingleOrDefault(p => unit.FileName.AsCaseless().StartsWith(p.Value.FullName));
                        tblSDKHeaderFile tblHeaderFile;
                        tblVendorSDK     similarSdk    = null;
                        bool             hasSimilarSdk = false;

                        if (unit.FileName == "<invalid>")
                        {
                            continue;
                        }

                        if (directoryPair.Key == null)
                        {
                            // has include file from a different version or vendor, attempt to find similar

                            var file = unit.FileName;

                            hasSimilarSdk = tblVendorSDKs.ToList().Any(v =>
                            {
                                if (similarSdk != null)
                                {
                                    return(false);
                                }
                                else if (versionRegex.IsMatch(file))
                                {
                                    var match         = versionRegex.Match(file);
                                    var versionGroup  = match.Groups["version"];
                                    var version       = versionGroup.Value;
                                    var fileBackDated = file.Substitute(versionGroup.Index, versionGroup.Length, v.SdkVersion);

                                    if (includeDirectories.Any(i => fileBackDated.StartsWith(i.Value.FullName)))
                                    {
                                        foreach (var similarPair in includeDirectories.Where(i => fileBackDated.StartsWith(i.Value.FullName)))
                                        {
                                            var tblVendorSdk = similarPair.Key;

                                            if (tblVendorSdk.VendorSdkId == v.VendorSdkId)
                                            {
                                                if (versionRegex.IsMatch(tblVendorSdk.SdkRootFolder))
                                                {
                                                    string newRoot;
                                                    tblVendorSDK tblVendorSdkNew;

                                                    match        = versionRegex.Match(tblVendorSdk.SdkRootFolder);
                                                    versionGroup = match.Groups["version"];
                                                    newRoot      = tblVendorSdk.SdkRootFolder.Substitute(versionGroup.Index, versionGroup.Length, version);

                                                    tblVendorSdkNew = new tblVendorSDK
                                                    {
                                                        VendorSdkId       = Guid.NewGuid(),
                                                        VendorId          = tblVendorSdk.VendorId,
                                                        SdkName           = tblVendorSdk.SdkName,
                                                        SdkVersion        = version,
                                                        SdkRootFolder     = newRoot,
                                                        IncludeFolders    = tblVendorSdk.IncludeFolders,
                                                        SourceFolders     = tblVendorSdk.SourceFolders,
                                                        LibraryFolders    = tblVendorSdk.LibraryFolders,
                                                        ExecutableFolders = tblVendorSdk.ExecutableFolders
                                                    };

                                                    tblVendorSDKs.AddObject(tblVendorSdkNew);
                                                    entities.SaveChanges();

                                                    similarSdk = tblVendorSdkNew;

                                                    return(true);
                                                }
                                            }
                                        }
                                    }
                                }

                                return(false);
                            });
                        }

                        if (hasSimilarSdk)
                        {
                            var sdkId = similarSdk.VendorSdkId;

                            AddIncludes(similarSdk);

                            tblHeaderFile = entities.SaveIfNotExists <tblSDKHeaderFile>(h => h.HeaderFileName == unit.FileName && h.VendorSdkId == sdkId, () =>
                            {
                                notExists = true;

                                return(new tblSDKHeaderFile
                                {
                                    HeaderFileId = Guid.NewGuid(),
                                    HeaderFileName = unit.FileName,
                                    VendorSdkId = similarSdk.VendorSdkId
                                });
                            });
                        }
                        else if (directoryPair.Key == null)
                        {
                            Debugger.Break();

                            tblHeaderFile = entities.SaveIfNotExists <tblSDKHeaderFile>(h => h.HeaderFileName == unit.FileName, () =>
                            {
                                notExists = true;

                                return(new tblSDKHeaderFile
                                {
                                    HeaderFileId = Guid.NewGuid(),
                                    VendorSdkId = null,
                                    HeaderFileName = unit.FileName
                                });
                            });
                        }
                        else
                        {
                            var sdkId = directoryPair.Key.VendorSdkId;

                            tblHeaderFile = entities.SaveIfNotExists <tblSDKHeaderFile>(h => h.HeaderFileName == unit.FileName && h.VendorSdkId == sdkId, () =>
                            {
                                notExists = true;

                                return(new tblSDKHeaderFile
                                {
                                    HeaderFileId = Guid.NewGuid(),
                                    VendorSdkId = directoryPair.Key.VendorSdkId,
                                    HeaderFileName = unit.FileName
                                });
                            });
                        }

                        if (notExists || !tblHeaderFile.IsParsedSuccessfully())
                        {
                            var header       = new Header(unit);
                            var elementCount = header.CacheObjects();
                            var x            = 1;
                            Action <DeclarationContext> recurseAdd = null;

                            recurseAdd = (declarationContext) =>
                            {
                                var tblDeclarationContext = entities.tblSDKHeaderDeclarationContexts.Single(declarationContext.GetWhere(tblHeaderFile));

                                foreach (var _namespace in declarationContext.Namespaces)
                                {
                                    if (declarationContext == header)
                                    {
                                        SetParserProgress(++x, elementCount, "Analyzing {0} with {1} elements", unit.Name, elementCount);
                                    }

                                    _namespace.Save(tblHeaderFile, tblDeclarationContext);

                                    recurseAdd(_namespace);
                                }

                                foreach (var _class in declarationContext.Classes)
                                {
                                    if (declarationContext == header)
                                    {
                                        SetParserProgress(++x, elementCount, "Analyzing {0} with {1} elements", unit.Name, elementCount);
                                    }

                                    _class.Save(tblHeaderFile, tblDeclarationContext);

                                    recurseAdd(_class);
                                }

                                foreach (var template in declarationContext.Templates)
                                {
                                    if (declarationContext == header)
                                    {
                                        SetParserProgress(++x, elementCount, "Analyzing {0} with {1} elements", unit.Name, elementCount);
                                    }

                                    template.Save(tblHeaderFile, tblDeclarationContext);
                                }

                                foreach (var preprocessedEntity in declarationContext.PreprocessedEntities)
                                {
                                    preprocessedEntity.Save(tblHeaderFile, tblDeclarationContext.tblSDKHeaderDeclaration);
                                }

                                foreach (var _enum in declarationContext.Enums)
                                {
                                    if (declarationContext == header)
                                    {
                                        SetParserProgress(++x, elementCount, "Analyzing {0} with {1} elements", unit.Name, elementCount);
                                    }

                                    _enum.Save(tblHeaderFile, tblDeclarationContext);
                                }

                                foreach (var typeAlias in declarationContext.TypeAliases)
                                {
                                    if (declarationContext == header)
                                    {
                                        SetParserProgress(++x, elementCount, "Analyzing {0} with {1} elements", unit.Name, elementCount);
                                    }

                                    typeAlias.Save(tblHeaderFile, tblDeclarationContext);
                                }

                                foreach (var typeDef in declarationContext.TypeDefs)
                                {
                                    if (declarationContext == header)
                                    {
                                        SetParserProgress(++x, elementCount, "Analyzing {0} with {1} elements", unit.Name, elementCount);
                                    }

                                    typeDef.Save(tblHeaderFile, tblDeclarationContext);
                                }

                                foreach (var variable in declarationContext.Variables)
                                {
                                    if (declarationContext == header)
                                    {
                                        SetParserProgress(++x, elementCount, "Analyzing {0} with {1} elements", unit.Name, elementCount);
                                    }

                                    variable.Save(tblHeaderFile, tblDeclarationContext);
                                }

                                foreach (var function in declarationContext.Functions)
                                {
                                    if (declarationContext == header)
                                    {
                                        SetParserProgress(++x, elementCount, "Analyzing {0} with {1} elements", unit.Name, elementCount);
                                    }

                                    function.Save(tblHeaderFile, tblDeclarationContext);
                                }

                                foreach (var friend in declarationContext.Friends)
                                {
                                    if (declarationContext == header)
                                    {
                                        SetParserProgress(++x, elementCount, "Analyzing {0} with {1} elements", unit.Name, elementCount);
                                    }

                                    friend.Save(tblHeaderFile, tblDeclarationContext);
                                }

                                if (declarationContext == header)
                                {
                                    foreach (var macro in header.Macros)
                                    {
                                        if (declarationContext == header)
                                        {
                                            SetParserProgress(++x, elementCount, "Analyzing {0} with {1} elements", unit.Name, elementCount);
                                        }

                                        macro.Save(tblHeaderFile, tblDeclarationContext.tblSDKHeaderDeclaration);
                                    }
                                }
                            };

                            header.Save(tblHeaderFile, true);

                            recurseAdd(header);

                            tblHeaderFile.ParsedSuccessfully = true;

                            entities.SaveChanges();
                        }
                    }
                }

                break;
            }
        }
        private void AddIncludes(tblVendorSDK tblVendorSdk)
        {
            var rootFolder = tblVendorSdk.SdkRootFolder;

            if (tblVendorSdk.IncludeFolders.IsNullOrEmpty())
            {
                DirectoryInfo includeDirectory;

                includeDirectory = new DirectoryInfo(tblVendorSdk.SdkRootFolder);

                if (includeDirectory.Exists)
                {
                    if (!includeDirectories.ContainsKey(tblVendorSdk))
                    {
                        if (!includeDirectories.Any(p => p.Value.FullName == includeDirectory.FullName))
                        {
                            includeDirectories.Add(tblVendorSdk, includeDirectory);
                        }
                    }
                }
            }
            else
            {
                foreach (var includeFolder in tblVendorSdk.IncludeFolders.Split(';', StringSplitOptions.RemoveEmptyEntries))
                {
                    DirectoryInfo includeDirectory;

                    if (Path.IsPathRooted(includeFolder))
                    {
                        includeDirectory = new DirectoryInfo(includeFolder);
                    }
                    else
                    {
                        var path = Path.GetFullPath(Path.Combine(rootFolder, includeFolder));

                        includeDirectory = new DirectoryInfo(Path.GetFullPath(path));
                    }

                    if (includeDirectory.Exists)
                    {
                        if (!includeDirectories.ContainsKey(tblVendorSdk))
                        {
                            if (!includeDirectories.Any(p => p.Value.FullName == includeDirectory.FullName))
                            {
                                includeDirectories.Add(tblVendorSdk, includeDirectory);
                            }
                        }
                    }
                }
            }

            if (tblVendorSdk.LibraryFolders.IsNullOrEmpty())
            {
                DirectoryInfo libDirectory;

                libDirectory = new DirectoryInfo(tblVendorSdk.SdkRootFolder);

                if (libDirectory.Exists)
                {
                    if (!libraryDirectories.ContainsKey(tblVendorSdk))
                    {
                        if (!libraryDirectories.Any(p => p.Value.FullName == libDirectory.FullName))
                        {
                            libraryDirectories.Add(tblVendorSdk, libDirectory);
                        }
                    }
                }
            }
            else
            {
                foreach (var libFolder in tblVendorSdk.LibraryFolders.Split(';', StringSplitOptions.RemoveEmptyEntries))
                {
                    DirectoryInfo libDirectory;

                    if (Path.IsPathRooted(libFolder))
                    {
                        libDirectory = new DirectoryInfo(libFolder);
                    }
                    else
                    {
                        var path = Path.GetFullPath(Path.Combine(rootFolder, libFolder));

                        libDirectory = new DirectoryInfo(Path.GetFullPath(path));
                    }

                    if (libDirectory.Exists)
                    {
                        if (!libraryDirectories.ContainsKey(tblVendorSdk))
                        {
                            if (!libraryDirectories.Any(p => p.Value.FullName == libDirectory.FullName))
                            {
                                libraryDirectories.Add(tblVendorSdk, libDirectory);
                            }
                        }
                    }
                }
            }
        }