public override async Task <bool> UninstallPackageAsync(PackageIdentity packageIdentity, INuGetProjectContext nuGetProjectContext, CancellationToken token)
        {
            if (packageIdentity == null)
            {
                throw new ArgumentNullException(nameof(packageIdentity));
            }

            if (nuGetProjectContext == null)
            {
                throw new ArgumentNullException(nameof(nuGetProjectContext));
            }

            // Step-1: Check if the package already exists after setting the nuGetProjectContext
            MSBuildNuGetProjectSystem.SetNuGetProjectContext(nuGetProjectContext);

            var packageReference = (await GetInstalledPackagesAsync(token))
                                   .FirstOrDefault(p => p.PackageIdentity.Equals(packageIdentity));

            if (packageReference == null)
            {
                nuGetProjectContext.Log(MessageLevel.Warning, Strings.PackageDoesNotExistInProject,
                                        packageIdentity, MSBuildNuGetProjectSystem.ProjectName);
                return(false);
            }

            var packageTargetFramework = packageReference.TargetFramework ?? MSBuildNuGetProjectSystem.TargetFramework;
            var packageEventArgs       = new PackageEventArgs(FolderNuGetProject,
                                                              packageIdentity,
                                                              FolderNuGetProject.GetInstalledPath(packageIdentity));

            if (PackageUninstalling != null)
            {
                PackageUninstalling(this, packageEventArgs);
            }

            PackageEventsProvider.Instance.NotifyUninstalling(packageEventArgs);

            using (var packageStream = File.OpenRead(FolderNuGetProject.GetInstalledPackageFilePath(packageIdentity)))
            {
                var zipArchive    = new ZipArchive(packageStream);
                var packageReader = new PackageArchiveReader(zipArchive);

                // Step-2: Execute powershell script - uninstall.ps1
                var toolItemGroups           = packageReader.GetToolItems();
                var compatibleToolItemsGroup = MSBuildNuGetProjectSystemUtility
                                               .GetMostCompatibleGroup(packageTargetFramework, toolItemGroups);
                compatibleToolItemsGroup = MSBuildNuGetProjectSystemUtility.Normalize(compatibleToolItemsGroup);

                if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleToolItemsGroup))
                {
                    var uninstallPS1RelativePath = compatibleToolItemsGroup.Items.FirstOrDefault(
                        p => p.EndsWith(Path.DirectorySeparatorChar + PowerShellScripts.Uninstall,
                                        StringComparison.OrdinalIgnoreCase));

                    if (!string.IsNullOrEmpty(uninstallPS1RelativePath))
                    {
                        var packageInstallPath = FolderNuGetProject.GetInstalledPath(packageIdentity);
                        await MSBuildNuGetProjectSystem.ExecuteScriptAsync(packageIdentity, packageInstallPath, uninstallPS1RelativePath, throwOnFailure : false);
                    }
                }

                // Step-3: Obtain the various item groups
                // Get the package target framework instead of using project targetframework
                var referenceItemGroups = packageReader.GetReferenceItems();
                var contentFileGroups   = packageReader.GetContentItems();
                var buildFileGroups     = packageReader.GetBuildItems();

                // Step-4: Get the most compatible items groups for all items groups
                var compatibleReferenceItemsGroup =
                    MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(packageTargetFramework, referenceItemGroups);

                var compatibleContentFilesGroup =
                    MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(packageTargetFramework, contentFileGroups);

                var compatibleBuildFilesGroup =
                    MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(packageTargetFramework, buildFileGroups);

                compatibleReferenceItemsGroup
                    = MSBuildNuGetProjectSystemUtility.Normalize(compatibleReferenceItemsGroup);
                compatibleContentFilesGroup
                    = MSBuildNuGetProjectSystemUtility.Normalize(compatibleContentFilesGroup);
                compatibleBuildFilesGroup
                    = MSBuildNuGetProjectSystemUtility.Normalize(compatibleBuildFilesGroup);

                try
                {
                    MSBuildNuGetProjectSystem.BeginProcessing();

                    // Step-5: Remove package reference from packages.config
                    await PackagesConfigNuGetProject.UninstallPackageAsync(packageIdentity, nuGetProjectContext, token);

                    // Step-6: Remove packages.config from MSBuildNuGetProject if there are no packages
                    //         OR Add it again (to ensure that Source Control works), when there are some packages
                    if (!(await PackagesConfigNuGetProject.GetInstalledPackagesAsync(token)).Any())
                    {
                        MSBuildNuGetProjectSystem.RemoveFile(Path.GetFileName(PackagesConfigNuGetProject.FullPath));
                    }
                    else
                    {
                        MSBuildNuGetProjectSystem.AddExistingFile(Path.GetFileName(PackagesConfigNuGetProject.FullPath));
                    }

                    // Step-7: Uninstall package from the msbuild project
                    // Step-7.1: Remove references
                    if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleReferenceItemsGroup))
                    {
                        foreach (var item in compatibleReferenceItemsGroup.Items)
                        {
                            if (IsAssemblyReference(item))
                            {
                                MSBuildNuGetProjectSystem.RemoveReference(Path.GetFileName(item));
                            }
                        }
                    }

                    // Step-7.2: Framework references are never removed. This is a no-op

                    // Step-7.3: Remove content files
                    if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleContentFilesGroup))
                    {
                        var packagesPaths = (await GetInstalledPackagesAsync(token))
                                            .Select(pr => FolderNuGetProject.GetInstalledPackageFilePath(pr.PackageIdentity));

                        MSBuildNuGetProjectSystemUtility.DeleteFiles(MSBuildNuGetProjectSystem,
                                                                     zipArchive,
                                                                     packagesPaths,
                                                                     compatibleContentFilesGroup,
                                                                     FileTransformers);
                    }

                    // Step-7.4: Remove build imports
                    if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleBuildFilesGroup))
                    {
                        foreach (var buildImportFile in compatibleBuildFilesGroup.Items)
                        {
                            var fullImportFilePath = Path.Combine(FolderNuGetProject.GetInstalledPath(packageIdentity), buildImportFile);
                            MSBuildNuGetProjectSystem.RemoveImport(fullImportFilePath);
                        }
                    }

                    // Step-7.5: Remove binding redirects. This is a no-op
                    // Binding redirects will be removed when all packages have finished
                    // uninstalling for performance reasons
                }
                finally
                {
                    MSBuildNuGetProjectSystem.EndProcessing();
                }

                // Step-8: Raise PackageReferenceRemoved event
                if (PackageReferenceRemoved != null)
                {
                    PackageReferenceRemoved(this, packageEventArgs);
                }

                PackageEventsProvider.Instance.NotifyReferenceRemoved(packageEventArgs);
            }

            // Step-9: Uninstall package from the folderNuGetProject
            await FolderNuGetProject.UninstallPackageAsync(packageIdentity, nuGetProjectContext, token);

            // Step-10: Raise PackageUninstalled event
            if (PackageUninstalled != null)
            {
                PackageUninstalled(this, packageEventArgs);
            }

            PackageEventsProvider.Instance.NotifyUninstalled(packageEventArgs);

            return(true);
        }
        public async override Task <bool> UninstallPackageAsync(PackageIdentity packageIdentity, INuGetProjectContext nuGetProjectContext, CancellationToken token)
        {
            if (packageIdentity == null)
            {
                throw new ArgumentNullException("packageIdentity");
            }

            if (nuGetProjectContext == null)
            {
                throw new ArgumentNullException("nuGetProjectContext");
            }

            // Step-1: Check if the package already exists after setting the nuGetProjectContext
            MSBuildNuGetProjectSystem.SetNuGetProjectContext(nuGetProjectContext);

            var packageReference = (await GetInstalledPackagesAsync(token)).Where(
                p => p.PackageIdentity.Equals(packageIdentity)).FirstOrDefault();

            if (packageReference == null)
            {
                nuGetProjectContext.Log(MessageLevel.Warning, Strings.PackageDoesNotExistInProject,
                                        packageIdentity, MSBuildNuGetProjectSystem.ProjectName);
                return(false);
            }

            var packageTargetFramework = packageReference.TargetFramework ?? NuGetFramework.UnsupportedFramework;
            var packageEventArgs       = new PackageEventArgs(FolderNuGetProject, packageIdentity, FolderNuGetProject.GetInstalledPath(packageIdentity));

            using (var packageStream = File.OpenRead(FolderNuGetProject.GetInstalledPackageFilePath(packageIdentity)))
            {
                // Step-2: Create PackageReader using the PackageStream and obtain the various item groups
                // Get the package target framework instead of using project targetframework
                var zipArchive    = new ZipArchive(packageStream);
                var packageReader = new PackageReader(zipArchive);

                IEnumerable <FrameworkSpecificGroup> referenceItemGroups      = packageReader.GetReferenceItems();
                IEnumerable <FrameworkSpecificGroup> frameworkReferenceGroups = packageReader.GetFrameworkItems();
                IEnumerable <FrameworkSpecificGroup> contentFileGroups        = packageReader.GetContentItems();
                IEnumerable <FrameworkSpecificGroup> buildFileGroups          = packageReader.GetBuildItems();

                // Step-3: Get the most compatible items groups for all items groups
                FrameworkSpecificGroup compatibleReferenceItemsGroup =
                    MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(packageTargetFramework, referenceItemGroups);
                FrameworkSpecificGroup compatibleFrameworkReferencesGroup =
                    MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(packageTargetFramework, frameworkReferenceGroups);
                FrameworkSpecificGroup compatibleContentFilesGroup =
                    MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(packageTargetFramework, contentFileGroups);
                FrameworkSpecificGroup compatibleBuildFilesGroup =
                    MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(packageTargetFramework, buildFileGroups);

                // TODO: Need to handle References element??

                // Step-4: Raise PackageUninstalling event
                if (PackageUninstalling != null)
                {
                    PackageUninstalling(this, packageEventArgs);
                }
                PackageEventsProvider.Instance.NotifyUninstalling(packageEventArgs);

                // Step-5: Uninstall package from packages.config
                await PackagesConfigNuGetProject.UninstallPackageAsync(packageIdentity, nuGetProjectContext, token);

                // Step-6: Remove packages.config from MSBuildNuGetProject if there are no packages
                //         OR Add it again (to ensure that Source Control works), when there are some packages
                if (!(await PackagesConfigNuGetProject.GetInstalledPackagesAsync(token)).Any())
                {
                    MSBuildNuGetProjectSystem.RemoveFile(Path.GetFileName(PackagesConfigNuGetProject.FullPath));
                }
                else
                {
                    MSBuildNuGetProjectSystem.AddExistingFile(Path.GetFileName(PackagesConfigNuGetProject.FullPath));
                }

                // Step-7: Uninstall package from the msbuild project
                // Step-7.1: Remove references
                if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleReferenceItemsGroup))
                {
                    foreach (var item in compatibleReferenceItemsGroup.Items)
                    {
                        if (IsAssemblyReference(item))
                        {
                            MSBuildNuGetProjectSystem.RemoveReference(Path.GetFileName(item));
                        }
                    }
                }

                // Step-7.2: Framework references are never removed. This is a no-op

                // Step-7.3: Remove content files
                if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleContentFilesGroup))
                {
                    MSBuildNuGetProjectSystemUtility.DeleteFiles(MSBuildNuGetProjectSystem,
                                                                 zipArchive,
                                                                 (await GetInstalledPackagesAsync(token)).Select(pr => FolderNuGetProject.GetInstalledPackageFilePath(pr.PackageIdentity)),
                                                                 compatibleContentFilesGroup,
                                                                 FileTransformers);
                }

                // Step-7.4: Remove build imports
                if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleBuildFilesGroup))
                {
                    foreach (var buildImportFile in compatibleBuildFilesGroup.Items)
                    {
                        string fullImportFilePath = Path.Combine(FolderNuGetProject.GetInstalledPath(packageIdentity), buildImportFile);
                        MSBuildNuGetProjectSystem.RemoveImport(fullImportFilePath);
                    }
                }

                // Step-7.5: Remove binding redirects. This is a no-op

                // Step-8: Raise PackageReferenceRemoved event
                if (PackageReferenceRemoved != null)
                {
                    PackageReferenceRemoved(this, packageEventArgs);
                }
                PackageEventsProvider.Instance.NotifyReferenceRemoved(packageEventArgs);

                // Step-9: Execute powershell script - uninstall.ps1
                IEnumerable <FrameworkSpecificGroup> toolItemGroups = packageReader.GetToolItems();
                FrameworkSpecificGroup compatibleToolItemsGroup     = MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(MSBuildNuGetProjectSystem.TargetFramework,
                                                                                                                              toolItemGroups);
                if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleToolItemsGroup))
                {
                    string uninstallPS1RelativePath = compatibleToolItemsGroup.Items.Where(p =>
                                                                                           p.EndsWith(Path.DirectorySeparatorChar + PowerShellScripts.Uninstall)).FirstOrDefault();
                    if (!String.IsNullOrEmpty(uninstallPS1RelativePath))
                    {
                        string packageInstallPath = FolderNuGetProject.GetInstalledPath(packageIdentity);
                        await MSBuildNuGetProjectSystem.ExecuteScriptAsync(packageInstallPath, uninstallPS1RelativePath, zipArchive, this);
                    }
                }
            }

            // Step-10: Uninstall package from the folderNuGetProject
            await FolderNuGetProject.UninstallPackageAsync(packageIdentity, nuGetProjectContext, token);

            // Step-11: Raise PackageUninstalled event
            if (PackageUninstalled != null)
            {
                PackageUninstalled(this, packageEventArgs);
            }
            PackageEventsProvider.Instance.NotifyUninstalled(packageEventArgs);

            return(true);
        }