private async Task AddFilesToProjectAsync(string configFilePath, Project project, IEnumerable <ILibraryOperationResult> results, CancellationToken cancellationToken)
        {
            string workingDirectory = Path.GetDirectoryName(configFilePath);
            var    files            = new List <string>();

            if (project != null)
            {
                foreach (ILibraryOperationResult state in results)
                {
                    if (state.Success && !state.UpToDate && state.InstallationState.Files != null)
                    {
                        IEnumerable <string> absoluteFiles = state.InstallationState.Files
                                                             .Select(file => Path.Combine(workingDirectory, state.InstallationState.DestinationPath, file)
                                                                     .Replace('/', Path.DirectorySeparatorChar));
                        files.AddRange(absoluteFiles);
                    }
                }

                if (files.Count > 0)
                {
                    var logAction = new Action <string, LogLevel>((message, level) => { Logger.LogEvent(message, level); });
                    await VsHelpers.AddFilesToProjectAsync(project, files, logAction, cancellationToken);
                }
            }
        }
        private async Task RestoreInternalAsync(IDictionary <string, Manifest> manifests, CancellationToken cancellationToken)
        {
            Logger.LogEventsHeader(OperationType.Restore, string.Empty);

            try
            {
                Stopwatch swTotal = new Stopwatch();
                swTotal.Start();

                foreach (KeyValuePair <string, Manifest> manifest in manifests)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    Stopwatch swLocal = new Stopwatch();
                    swLocal.Start();
                    IDependencies dependencies = _dependenciesFactory.FromConfigFile(manifest.Key);
                    Project       project      = VsHelpers.GetDTEProjectFromConfig(manifest.Key);

                    Logger.LogEvent(string.Format(LibraryManager.Resources.Text.Restore_LibrariesForProject, project?.Name), LogLevel.Operation);

                    IEnumerable <ILibraryOperationResult> validationResults = await LibrariesValidator.GetManifestErrorsAsync(manifest.Value, dependencies, cancellationToken).ConfigureAwait(false);

                    if (!validationResults.All(r => r.Success))
                    {
                        swLocal.Stop();
                        AddErrorsToErrorList(project?.Name, manifest.Key, validationResults);
                        Logger.LogErrorsSummary(validationResults, OperationType.Restore, false);
                        Telemetry.LogErrors($"FailValidation_{OperationType.Restore}", validationResults);
                    }
                    else
                    {
                        IEnumerable <ILibraryOperationResult> results = await RestoreLibrariesAsync(manifest.Value, cancellationToken).ConfigureAwait(false);
                        await AddFilesToProjectAsync(manifest.Key, project, results.Where(r => r.Success && !r.UpToDate), cancellationToken).ConfigureAwait(false);

                        swLocal.Stop();
                        AddErrorsToErrorList(project?.Name, manifest.Key, results);
                        Logger.LogEventsSummary(results, OperationType.Restore, swLocal.Elapsed, false);
                        Telemetry.LogEventsSummary(results, OperationType.Restore, swLocal.Elapsed);
                    }
                }

                swTotal.Stop();
                Logger.LogEventsFooter(OperationType.Restore, swTotal.Elapsed);
            }
            catch (OperationCanceledException ex)
            {
                Logger.LogEvent(LibraryManager.Resources.Text.Restore_OperationCancelled, LogLevel.Task);
                Telemetry.TrackException($@"{OperationType.Restore}Cancelled", ex);
            }
        }
        private async Task CleanLibrariesAsync(ProjectItem configProjectItem, CancellationToken cancellationToken)
        {
            Logger.LogEventsHeader(OperationType.Clean, string.Empty);

            try
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();

                string  configFileName = configProjectItem.FileNames[1];
                var     dependencies   = _dependenciesFactory.FromConfigFile(configFileName);
                Project project        = VsHelpers.GetDTEProjectFromConfig(configFileName);

                Manifest manifest = await Manifest.FromFileAsync(configFileName, dependencies, CancellationToken.None).ConfigureAwait(false);

                IEnumerable <ILibraryOperationResult> results = new List <ILibraryOperationResult>();

                if (manifest != null)
                {
                    IEnumerable <ILibraryOperationResult> validationResults = await LibrariesValidator.GetManifestErrorsAsync(manifest, dependencies, cancellationToken).ConfigureAwait(false);

                    if (!validationResults.All(r => r.Success))
                    {
                        sw.Stop();
                        AddErrorsToErrorList(project?.Name, configFileName, validationResults);
                        Logger.LogErrorsSummary(validationResults, OperationType.Clean);
                        Telemetry.LogErrors($"FailValidation_{OperationType.Clean}", validationResults);
                    }
                    else
                    {
                        IHostInteraction hostInteraction = dependencies.GetHostInteractions();
                        results = await manifest.CleanAsync(async (filesPaths) => await hostInteraction.DeleteFilesAsync(filesPaths, cancellationToken), cancellationToken);

                        sw.Stop();
                        AddErrorsToErrorList(project?.Name, configFileName, results);
                        Logger.LogEventsSummary(results, OperationType.Clean, sw.Elapsed);
                        Telemetry.LogEventsSummary(results, OperationType.Clean, sw.Elapsed);
                    }
                }
            }
            catch (OperationCanceledException ex)
            {
                Logger.LogEvent(LibraryManager.Resources.Text.Clean_OperationCancelled, LogLevel.Task);
                Telemetry.TrackException($@"{OperationType.Clean}Cancelled", ex);
            }
        }