/// <summary>
        ///     Add a sub-project.
        /// </summary>
        /// <param name="subProjectDocument">
        ///     The sub-project.
        /// </param>
        public void AddSubProject(SubProjectDocument subProjectDocument)
        {
            if (subProjectDocument == null)
            {
                throw new ArgumentNullException(nameof(subProjectDocument));
            }

            _subProjects.Add(subProjectDocument.DocumentUri, subProjectDocument);
        }
        /// <summary>
        ///     Try to retrieve the current state for the specified project document.
        /// </summary>
        /// <param name="documentUri">
        ///     The project document URI.
        /// </param>
        /// <param name="reload">
        ///     Reload the project if it is already loaded?
        /// </param>
        /// <returns>
        ///     The project document.
        /// </returns>
        public async Task <ProjectDocument> GetProjectDocument(Uri documentUri, bool reload = false)
        {
            string projectFilePath = VSCodeDocumentUri.GetFileSystemPath(documentUri);

            bool            isNewProject    = false;
            ProjectDocument projectDocument = _projectDocuments.GetOrAdd(documentUri, _ =>
            {
                isNewProject = true;

                if (MasterProject == null)
                {
                    return(MasterProject = new MasterProjectDocument(this, documentUri, Log));
                }

                SubProjectDocument subProject = new SubProjectDocument(this, documentUri, Log, MasterProject);
                MasterProject.AddSubProject(subProject);

                return(subProject);
            });

            try
            {
                if (isNewProject || reload)
                {
                    using (await projectDocument.Lock.WriterLockAsync())
                    {
                        await projectDocument.Load();
                    }
                }
            }
            catch (XmlException invalidXml)
            {
                Log.Error("Error parsing project file {ProjectFilePath}: {ErrorMessage:l}",
                          projectFilePath,
                          invalidXml.Message
                          );
            }
            catch (Exception loadError)
            {
                Log.Error(loadError, "Unexpected error loading file {ProjectFilePath}.", projectFilePath);
            }

            return(projectDocument);
        }
        /// <summary>
        ///     Try to retrieve the current state for the specified project document.
        /// </summary>
        /// <param name="documentUri">
        ///     The project document URI.
        /// </param>
        /// <param name="reload">
        ///     Reload the project if it is already loaded?
        /// </param>
        /// <returns>
        ///     The project document.
        /// </returns>
        public async Task <ProjectDocument> GetProjectDocument(Uri documentUri, bool reload = false)
        {
            string projectFilePath = VSCodeDocumentUri.GetFileSystemPath(documentUri);

            bool            isNewProject    = false;
            ProjectDocument projectDocument = _projectDocuments.GetOrAdd(documentUri, _ =>
            {
                isNewProject = true;

                if (MasterProject == null)
                {
                    return(MasterProject = new MasterProjectDocument(this, documentUri, Log));
                }

                SubProjectDocument subProject = new SubProjectDocument(this, documentUri, Log, MasterProject);
                MasterProject.AddSubProject(subProject);

                return(subProject);
            });

            if (!_msbuildVersionLogged)
            {
                if (MSBuildHelper.HaveMSBuild)
                {
                    Log.Information("Using MSBuild engine v{MSBuildVersion:l} from {MSBuildPath}.",
                                    MSBuildHelper.MSBuildVersion,
                                    MSBuildHelper.MSBuildPath
                                    );
                }
                else
                {
                    Log.Warning("Failed to find any version of MSBuild compatible with the current .NET SDK (respecting global.json).");
                }

                _msbuildVersionLogged = true;
            }

            try
            {
                if (isNewProject || reload)
                {
                    using (await projectDocument.Lock.WriterLockAsync())
                    {
                        await projectDocument.Load();
                    }
                }
            }
            catch (XmlException invalidXml)
            {
                Log.Error("Error parsing project file {ProjectFilePath}: {ErrorMessage:l}",
                          projectFilePath,
                          invalidXml.Message
                          );
            }
            catch (Exception loadError)
            {
                Log.Error(loadError, "Unexpected error loading file {ProjectFilePath}.", projectFilePath);
            }

            return(projectDocument);
        }