public static async Task <IEnumerable <string> > ExtractPackageAsync(
            string source,
            PackageReaderBase packageReader,
            PackagePathResolver packagePathResolver,
            PackageExtractionContext packageExtractionContext,
            CancellationToken token,
            Guid parentId = default(Guid))
        {
            if (packageReader == null)
            {
                throw new ArgumentNullException(nameof(packageReader));
            }

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

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

            token.ThrowIfCancellationRequested();

            var packageSaveMode = packageExtractionContext.PackageSaveMode;
            var extractionId    = Guid.NewGuid();
            var filesAdded      = new List <string>();

            using (var telemetry = TelemetryActivity.CreateTelemetryActivityWithNewOperationId(parentId))
            {
                var packageIdentityFromNuspec = await packageReader.GetIdentityAsync(token);

                try
                {
                    telemetry.StartIntervalMeasure();

                    await VerifyPackageSignatureAsync(
                        source,
                        telemetry.OperationId,
                        packageIdentityFromNuspec,
                        packageExtractionContext,
                        packageReader,
                        token);

                    telemetry.EndIntervalMeasure(PackagingConstants.PackageVerifyDurationName);
                }
                catch (SignatureException)
                {
                    telemetry.TelemetryEvent = new PackageExtractionTelemetryEvent(
                        packageExtractionContext.PackageSaveMode,
                        NuGetOperationStatus.Failed,
                        ExtractionSource.NuGetFolderProject,
                        packageIdentityFromNuspec);
                    throw;
                }

                var packageDirectoryInfo = Directory.CreateDirectory(packagePathResolver.GetInstallPath(packageIdentityFromNuspec));
                var packageDirectory     = packageDirectoryInfo.FullName;

                var packageFiles = await packageReader.GetPackageFilesAsync(packageSaveMode, token);

                var packageFileExtractor = new PackageFileExtractor(packageFiles, packageExtractionContext.XmlDocFileSaveMode);

                filesAdded.AddRange(await packageReader.CopyFilesAsync(
                                        packageDirectory,
                                        packageFiles,
                                        packageFileExtractor.ExtractPackageFile,
                                        packageExtractionContext.Logger,
                                        token));

                if (packageSaveMode.HasFlag(PackageSaveMode.Nupkg))
                {
                    var nupkgFilePath = Path.Combine(packageDirectory, packagePathResolver.GetPackageFileName(packageIdentityFromNuspec));
                    var filePath      = await packageReader.CopyNupkgAsync(nupkgFilePath, token);

                    if (!string.IsNullOrEmpty(filePath))
                    {
                        filesAdded.Add(filePath);
                    }
                }

                // Now, copy satellite files unless requested to not copy them
                if (packageExtractionContext.CopySatelliteFiles)
                {
                    filesAdded.AddRange(await CopySatelliteFilesAsync(
                                            packageReader,
                                            packagePathResolver,
                                            packageSaveMode,
                                            packageExtractionContext,
                                            token));
                }

                telemetry.TelemetryEvent = new PackageExtractionTelemetryEvent(
                    packageExtractionContext.PackageSaveMode,
                    NuGetOperationStatus.Succeeded,
                    ExtractionSource.NuGetFolderProject,
                    packageIdentityFromNuspec);
                return(filesAdded);
            }
        }
        public static async Task <IEnumerable <string> > ExtractPackageAsync(
            PackageReaderBase packageReader,
            PackagePathResolver packagePathResolver,
            PackageExtractionContext packageExtractionContext,
            CancellationToken token)
        {
            if (packageReader == null)
            {
                throw new ArgumentNullException(nameof(packageReader));
            }

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

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

            token.ThrowIfCancellationRequested();

            var packageSaveMode = packageExtractionContext.PackageSaveMode;

            var filesAdded = new List <string>();

            var packageIdentityFromNuspec = await packageReader.GetIdentityAsync(token);

            var packageDirectoryInfo = Directory.CreateDirectory(packagePathResolver.GetInstallPath(packageIdentityFromNuspec));
            var packageDirectory     = packageDirectoryInfo.FullName;

            var packageFiles = await packageReader.GetPackageFilesAsync(packageSaveMode, token);

            var packageFileExtractor = new PackageFileExtractor(packageFiles, packageExtractionContext.XmlDocFileSaveMode);

            filesAdded.AddRange(await packageReader.CopyFilesAsync(
                                    packageDirectory,
                                    packageFiles,
                                    packageFileExtractor.ExtractPackageFile,
                                    packageExtractionContext.Logger,
                                    token));

            if (packageSaveMode.HasFlag(PackageSaveMode.Nupkg))
            {
                var nupkgFilePath = Path.Combine(packageDirectory, packagePathResolver.GetPackageFileName(packageIdentityFromNuspec));
                var filePath      = await packageReader.CopyNupkgAsync(nupkgFilePath, token);

                if (!string.IsNullOrEmpty(filePath))
                {
                    filesAdded.Add(filePath);
                }
            }

            // Now, copy satellite files unless requested to not copy them
            if (packageExtractionContext.CopySatelliteFiles)
            {
                filesAdded.AddRange(await CopySatelliteFilesAsync(
                                        packageReader,
                                        packagePathResolver,
                                        packageSaveMode,
                                        packageExtractionContext,
                                        token));
            }

            return(filesAdded);
        }