/// <summary>
 /// Add a signature to a package.
 /// </summary>
 public static Task SignAsync(SigningOptions options, SignPackageRequest signRequest, CancellationToken token) => throw new NotImplementedException();
        /// <summary>
        /// Add a signature to a package.
        /// </summary>
        public static async Task SignAsync(SigningOptions options, SignPackageRequest signRequest, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            Verify(signRequest, options.Logger);

            var    tempPackageFile       = new FileInfo(Path.GetTempFileName());
            Stream unsignedPackageStream = null;
            var    signaturePlacement    = SignaturePlacement.PrimarySignature;

            try
            {
                PrimarySignature primarySignature;
                var isSigned = false;

                using (var package = new SignedPackageArchive(options.InputPackageStream, Stream.Null))
                {
                    if (await package.IsZip64Async(token))
                    {
                        throw new SignatureException(NuGetLogCode.NU3006, Strings.ErrorZip64NotSupported);
                    }

                    primarySignature = await package.GetPrimarySignatureAsync(token);

                    isSigned = primarySignature != null;

                    if (signRequest.SignatureType == SignatureType.Repository && primarySignature != null)
                    {
                        if (primarySignature.Type == SignatureType.Repository)
                        {
                            throw new SignatureException(NuGetLogCode.NU3033, Strings.Error_RepositorySignatureMustNotHaveARepositoryCountersignature);
                        }

                        if (SignatureUtility.HasRepositoryCountersignature(primarySignature))
                        {
                            throw new SignatureException(NuGetLogCode.NU3032, Strings.SignedPackagePackageAlreadyCountersigned);
                        }

                        signaturePlacement = SignaturePlacement.Countersignature;
                    }

                    if (isSigned && !options.Overwrite && signaturePlacement != SignaturePlacement.Countersignature)
                    {
                        throw new SignatureException(NuGetLogCode.NU3001, Strings.SignedPackageAlreadySigned);
                    }
                }

                var inputPackageStream = options.InputPackageStream;
                if (isSigned)
                {
                    unsignedPackageStream = tempPackageFile.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite);

                    using (var package = new SignedPackageArchive(options.InputPackageStream, unsignedPackageStream))
                    {
                        await package.RemoveSignatureAsync(token);
                    }

                    inputPackageStream = unsignedPackageStream;
                }

                using (var package = new SignedPackageArchive(inputPackageStream, options.OutputPackageStream))
                {
                    PrimarySignature signature;
                    if (signaturePlacement == SignaturePlacement.Countersignature)
                    {
                        signature = await options.SignatureProvider.CreateRepositoryCountersignatureAsync(
                            signRequest as RepositorySignPackageRequest,
                            primarySignature,
                            options.Logger,
                            token);
                    }
                    else
                    {
                        var hashAlgorithm  = signRequest.SignatureHashAlgorithm;
                        var zipArchiveHash = await package.GetArchiveHashAsync(hashAlgorithm, token);

                        var signatureContent = GenerateSignatureContent(hashAlgorithm, zipArchiveHash);
                        signature = await options.SignatureProvider.CreatePrimarySignatureAsync(signRequest, signatureContent, options.Logger, token);
                    }

                    using (var stream = new MemoryStream(signature.GetBytes()))
                    {
                        await package.AddSignatureAsync(stream, token);
                    }
                }
            }
            finally
            {
                if (unsignedPackageStream != null && !ReferenceEquals(unsignedPackageStream, options.InputPackageStream))
                {
                    unsignedPackageStream.Dispose();
                }

                FileUtility.Delete(tempPackageFile.FullName);
            }
        }