public DefaultApkSignerEngine(X509Certificate2 certificate, int minSdkVersion, bool v1SigningEnabled,
                                      bool v2SigningEnabled, DigestAlgorithm digestAlgorithm)
        {
            _v1SigningEnabled   = v1SigningEnabled;
            _v2SigningEnabled   = v2SigningEnabled;
            _v1SignaturePending = v1SigningEnabled;
            _v2SignaturePending = v2SigningEnabled;

            if (v1SigningEnabled)
            {
                var v1SignerName = V1SchemeSigner.GetSafeSignerName(certificate.FriendlyName);
                // Check whether the signer's name is unique among all v1 signers
                var v1SignatureDigestAlgorithm = digestAlgorithm ??
                                                 V1SchemeSigner.GetSuggestedSignatureDigestAlgorithm(
                    certificate.PublicKey, minSdkVersion);
                var v1SignerConfig = new V1SchemeSigner.SignerConfig();
                v1SignerConfig.Name        = v1SignerName;
                v1SignerConfig.Certificate = certificate;
                v1SignerConfig.SignatureDigestAlgorithm = v1SignatureDigestAlgorithm;

                _v1SignerConfigs                      = v1SignerConfig;
                _v1ContentDigestAlgorithm             = v1SignatureDigestAlgorithm;
                _signatureExpectedOutputJarEntryNames = V1SchemeSigner.GetOutputEntryNames(_v1SignerConfigs, minSdkVersion);

                _v1ContentDigestAlgorithm = V1SchemeSigner.GetSuggestedSignatureDigestAlgorithm(certificate.PublicKey, minSdkVersion);
            }

            if (v2SigningEnabled)
            {
                var v2SignerConfig = new V2SchemeSigner.SignerConfig();
                v2SignerConfig.Certificates       = certificate;
                v2SignerConfig.SignatureAlgorithm = V2SchemeSigner.GetSuggestedSignatureAlgorithms(certificate.PublicKey, minSdkVersion, digestAlgorithm);
                _v2SignerConfigs = v2SignerConfig;
            }
        }
        /// <summary>
        /// Indicates to this engine that the ZIP sections comprising the output APK have been output.
        ///
        /// The provided data sources are guaranteed to not be used by the engine after this method terminates.
        /// </summary>
        /// <param name="zipEntries">the section of ZIP archive containing Local File Header records and data of
        /// the ZIP entries.In a well-formed archive, this section starts at the start of the
        /// archive and extends all the way to the ZIP Central Directory.
        /// </param>
        /// <param name="zipCentralDirectory">ZIP Central Directory section</param>
        /// <param name="zipEocd">ZIP End of Central Directory (EoCD) record
        /// </param>
        /// <returns>
        /// request to add an APK Signing Block to the output or {@code null} if the output must
        /// not contain an APK Signing Block.The request must be fulfilled before <see cref="OutputDone"/> is invoked.
        /// </returns>
        public IOutputApkSigningBlockRequest OutputZipSections(Stream zipEntries, Stream zipCentralDirectory, Stream zipEocd)
        {
            CheckV1SigningDoneIfEnabled();
            if (!_v2SigningEnabled)
            {
                return(null);
            }

            InvalidateV2Signature();
            var apkSigningBlock = V2SchemeSigner.GenerateApkSigningBlock(zipEntries, zipCentralDirectory, zipEocd, _v2SignerConfigs);

            _addV2SignatureRequest = new OutputApkSigningBlockRequestImpl(apkSigningBlock);
            return(_addV2SignatureRequest);
        }