/// <summary>
        /// Indicates to this engine that the specified JAR entry was encountered in the input APK.
        /// </summary>
        /// <param name="entryName"></param>
        /// <returns>instructions about how to proceed with this entry</returns>
        public InputJarEntryInstructions InputJarEntry(string entryName)
        {
            var outputPolicy = GetInputJarEntryOutputPolicy(entryName);

            switch (outputPolicy)
            {
            case OutputPolicy.Skip:
                return(new InputJarEntryInstructions(OutputPolicy.Skip));

            case OutputPolicy.Output:
                return(new InputJarEntryInstructions(OutputPolicy.Output));

            case OutputPolicy.OutputByEngine:
                if (V1SchemeSigner.ManifestEntryName.Equals(entryName))
                {
                    // We copy the main section of the JAR manifest from input to output. Thus, this
                    // invalidates v1 signature and we need to see the entry's data.
                    _inputJarManifestEntryDataRequest = new GetJarEntryDataRequest(entryName);
                    return(new InputJarEntryInstructions(OutputPolicy.OutputByEngine, _inputJarManifestEntryDataRequest));
                }
                return(new InputJarEntryInstructions(OutputPolicy.OutputByEngine));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        /// <summary>
        /// Indicates to this engine that the specified JAR entry was output.
        ///
        /// It is unnecessary to invoke this method for entries added to output by this engine (e.g.,
        /// requested by <see cref="OutputJarEntries"/> provided the entries were output with exactly the
        /// data requested by the engine.
        /// </summary>
        /// <param name="entryName"></param>
        /// <returns>
        /// request to inspect the entry or <code>null</code> if the engine does not need to inspect
        /// the entry.The request must be fulfilled before<see cref="OutputJarEntries"/> is invoked.
        /// </returns>
        public IInspectJarEntryRequest OutputJarEntry(string entryName)
        {
            InvalidateV2Signature();

            if (!_v1SigningEnabled)
            {
                // No need to inspect JAR entries when v1 signing is not enabled.
                return(null);
            }


            // v1 signing is enabled
            if (V1SchemeSigner.IsJarEntryDigestNeededInManifest(entryName))
            {
                // This entry is covered by v1 signature. We thus need to inspect the entry's data to
                // compute its digest(s) for v1 signature.
                // TODO: Handle the case where other signer's v1 signatures are present and need to be
                // preserved. In that scenario we can't modify MANIFEST.MF and add/remove JAR entries
                // covered by v1 signature.
                InvalidateV1Signature();
                var dataDigestRequest = new GetJarEntryDataDigestRequest(entryName, _v1ContentDigestAlgorithm);
                _outputJarEntryDigestRequests.Add(entryName, dataDigestRequest);
                _outputJarEntryDigests.Remove(entryName);
                return(dataDigestRequest);
            }
            if (_signatureExpectedOutputJarEntryNames.Contains(entryName))
            {
                // This entry is part of v1 signature generated by this engine. We need to check whether
                // the entry's data is as output by the engine.
                InvalidateV1Signature();
                GetJarEntryDataRequest dataRequest;
                if (V1SchemeSigner.ManifestEntryName.Equals(entryName))
                {
                    dataRequest = new GetJarEntryDataRequest(entryName);
                    _inputJarManifestEntryDataRequest = dataRequest;
                }
                else
                {
                    // If this entry is part of v1 signature which has been emitted by this engine,
                    // check whether the output entry's data matches what the engine emitted.
                    dataRequest = (_emittedSignatureJarEntryData.ContainsKey(entryName))
                                    ? new GetJarEntryDataRequest(entryName) : null;
                }
                if (dataRequest != null)
                {
                    _outputSignatureJarEntryDataRequests.Add(entryName, dataRequest);
                }
                return(dataRequest);
            }
            // This entry is not covered by v1 signature and isn't part of v1 signature.
            return(null);
        }