diff --git a/tools/apksigner/Android.mk b/tools/apksigner/Android.mk
deleted file mode 100644
index a7b4414..0000000
--- a/tools/apksigner/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/apksigner/core/Android.mk b/tools/apksigner/core/Android.mk
deleted file mode 100644
index 132a6f1..0000000
--- a/tools/apksigner/core/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(call my-dir)
-
-# apksigner library, for signing APKs and verification signatures of APKs
-# ============================================================
-include $(CLEAR_VARS)
-LOCAL_MODULE := apksigner-core
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-# Disable warnnings about our use of internal proprietary OpenJDK API.
-# TODO: Remove this workaround by moving to our own implementation of PKCS #7
-# SignedData block generation, parsing, and verification.
-LOCAL_JAVACFLAGS := -XDignore.symbol.file
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/ApkSigner.java b/tools/apksigner/core/src/com/android/apksigner/core/ApkSigner.java
deleted file mode 100644
index 2491302..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/ApkSigner.java
+++ /dev/null
@@ -1,711 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core;
-
-import java.io.Closeable;
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SignatureException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import com.android.apksigner.core.apk.ApkUtils;
-import com.android.apksigner.core.internal.apk.v2.V2SchemeVerifier;
-import com.android.apksigner.core.internal.util.ByteBufferDataSource;
-import com.android.apksigner.core.internal.util.Pair;
-import com.android.apksigner.core.internal.zip.CentralDirectoryRecord;
-import com.android.apksigner.core.internal.zip.EocdRecord;
-import com.android.apksigner.core.internal.zip.LocalFileRecord;
-import com.android.apksigner.core.internal.zip.ZipUtils;
-import com.android.apksigner.core.util.DataSink;
-import com.android.apksigner.core.util.DataSinks;
-import com.android.apksigner.core.util.DataSource;
-import com.android.apksigner.core.util.DataSources;
-import com.android.apksigner.core.zip.ZipFormatException;
-
-/**
- * APK signer.
- *
- * <p>The signer preserves as much of the input APK as possible. For example, it preserves the
- * order of APK entries and preserves their contents, including compressed form and alignment of
- * data.
- *
- * <p>Use {@link Builder} to obtain instances of this signer.
- */
-public class ApkSigner {
-
-    /**
-     * Extensible data block/field header ID used for storing information about alignment of
-     * uncompressed entries as well as for aligning the entries's data. See ZIP appnote.txt section
-     * 4.5 Extensible data fields.
-     */
-    private static final short ALIGNMENT_ZIP_EXTRA_DATA_FIELD_HEADER_ID = (short) 0xd935;
-
-    /**
-     * Minimum size (in bytes) of the extensible data block/field used for alignment of uncompressed
-     * entries.
-     */
-    private static final short ALIGNMENT_ZIP_EXTRA_DATA_FIELD_MIN_SIZE_BYTES = 6;
-
-    private final ApkSignerEngine mSignerEngine;
-
-    private final File mInputApkFile;
-    private final DataSource mInputApkDataSource;
-
-    private final File mOutputApkFile;
-    private final DataSink mOutputApkDataSink;
-    private final DataSource mOutputApkDataSource;
-
-    private ApkSigner(
-            ApkSignerEngine signerEngine,
-            File inputApkFile,
-            DataSource inputApkDataSource,
-            File outputApkFile,
-            DataSink outputApkDataSink,
-            DataSource outputApkDataSource) {
-        mSignerEngine = signerEngine;
-
-        mInputApkFile = inputApkFile;
-        mInputApkDataSource = inputApkDataSource;
-
-        mOutputApkFile = outputApkFile;
-        mOutputApkDataSink = outputApkDataSink;
-        mOutputApkDataSource = outputApkDataSource;
-    }
-
-    /**
-     * Signs the input APK and outputs the resulting signed APK. The input APK is not modified.
-     *
-     * @throws IOException if an I/O error is encountered while reading or writing the APKs
-     * @throws ZipFormatException if the input APK is malformed at ZIP format level
-     * @throws NoSuchAlgorithmException if the APK signatures cannot be produced or verified because
-     *         a required cryptographic algorithm implementation is missing
-     * @throws InvalidKeyException if a signature could not be generated because a signing key is
-     *         not suitable for generating the signature
-     * @throws SignatureException if an error occurred while generating or verifying a signature
-     * @throws IllegalStateException if this signer's configuration is missing required information
-     *         or if the signing engine is in an invalid state.
-     */
-    public void sign()
-            throws IOException, ZipFormatException, NoSuchAlgorithmException, InvalidKeyException,
-                    SignatureException, IllegalStateException {
-        Closeable in = null;
-        DataSource inputApk;
-        try {
-            if (mInputApkDataSource != null) {
-                inputApk = mInputApkDataSource;
-            } else if (mInputApkFile != null) {
-                RandomAccessFile inputFile = new RandomAccessFile(mInputApkFile, "r");
-                in = inputFile;
-                inputApk = DataSources.asDataSource(inputFile);
-            } else {
-                throw new IllegalStateException("Input APK not specified");
-            }
-
-            Closeable out = null;
-            try {
-                DataSink outputApkOut;
-                DataSource outputApkIn;
-                if (mOutputApkDataSink != null) {
-                    outputApkOut = mOutputApkDataSink;
-                    outputApkIn = mOutputApkDataSource;
-                } else if (mOutputApkFile != null) {
-                    RandomAccessFile outputFile = new RandomAccessFile(mOutputApkFile, "rw");
-                    out = outputFile;
-                    outputFile.setLength(0);
-                    outputApkOut = DataSinks.asDataSink(outputFile);
-                    outputApkIn = DataSources.asDataSource(outputFile);
-                } else {
-                    throw new IllegalStateException("Output APK not specified");
-                }
-
-                sign(mSignerEngine, inputApk, outputApkOut, outputApkIn);
-            } finally {
-                if (out != null) {
-                    out.close();
-                }
-            }
-        } finally {
-            if (in != null) {
-                in.close();
-            }
-        }
-    }
-
-    private static void sign(
-            ApkSignerEngine signerEngine,
-            DataSource inputApk,
-            DataSink outputApkOut,
-            DataSource outputApkIn)
-                    throws IOException, ZipFormatException, NoSuchAlgorithmException,
-                            InvalidKeyException, SignatureException {
-        // Step 1. Find input APK's main ZIP sections
-        ApkUtils.ZipSections inputZipSections = ApkUtils.findZipSections(inputApk);
-        long apkSigningBlockOffset = -1;
-        try {
-            Pair<DataSource, Long> apkSigningBlockAndOffset =
-                    V2SchemeVerifier.findApkSigningBlock(inputApk, inputZipSections);
-            signerEngine.inputApkSigningBlock(apkSigningBlockAndOffset.getFirst());
-            apkSigningBlockOffset = apkSigningBlockAndOffset.getSecond();
-        } catch (V2SchemeVerifier.SignatureNotFoundException e) {
-            // Input APK does not contain an APK Signing Block. That's OK. APKs are not required to
-            // contain this block. It's only needed if the APK is signed using APK Signature Scheme
-            // v2.
-        }
-
-        // Step 2. Parse the input APK's ZIP Central Directory
-        ByteBuffer inputCd = getZipCentralDirectory(inputApk, inputZipSections);
-        List<CentralDirectoryRecord> inputCdRecords =
-                parseZipCentralDirectory(inputCd, inputZipSections);
-
-        // Step 3. Iterate over input APK's entries and output the Local File Header + data of those
-        // entries which need to be output. Entries are iterated in the order in which their Local
-        // File Header records are stored in the file. This is to achieve better data locality in
-        // case Central Directory entries are in the wrong order.
-        List<CentralDirectoryRecord> inputCdRecordsSortedByLfhOffset =
-                new ArrayList<>(inputCdRecords);
-        Collections.sort(
-                inputCdRecordsSortedByLfhOffset,
-                CentralDirectoryRecord.BY_LOCAL_FILE_HEADER_OFFSET_COMPARATOR);
-        DataSource inputApkLfhSection =
-                inputApk.slice(
-                        0,
-                        (apkSigningBlockOffset != -1)
-                                ? apkSigningBlockOffset
-                                : inputZipSections.getZipCentralDirectoryOffset());
-        int lastModifiedDateForNewEntries = -1;
-        int lastModifiedTimeForNewEntries = -1;
-        long inputOffset = 0;
-        long outputOffset = 0;
-        Map<String, CentralDirectoryRecord> outputCdRecordsByName =
-                new HashMap<>(inputCdRecords.size());
-        for (final CentralDirectoryRecord inputCdRecord : inputCdRecordsSortedByLfhOffset) {
-            String entryName = inputCdRecord.getName();
-            ApkSignerEngine.InputJarEntryInstructions entryInstructions =
-                    signerEngine.inputJarEntry(entryName);
-            boolean shouldOutput;
-            switch (entryInstructions.getOutputPolicy()) {
-                case OUTPUT:
-                    shouldOutput = true;
-                    break;
-                case OUTPUT_BY_ENGINE:
-                case SKIP:
-                    shouldOutput = false;
-                    break;
-                default:
-                    throw new RuntimeException(
-                            "Unknown output policy: " + entryInstructions.getOutputPolicy());
-            }
-
-            long inputLocalFileHeaderStartOffset = inputCdRecord.getLocalFileHeaderOffset();
-            if (inputLocalFileHeaderStartOffset > inputOffset) {
-                // Unprocessed data in input starting at inputOffset and ending and the start of
-                // this record's LFH. We output this data verbatim because this signer is supposed
-                // to preserve as much of input as possible.
-                long chunkSize = inputLocalFileHeaderStartOffset - inputOffset;
-                inputApkLfhSection.feed(inputOffset, chunkSize, outputApkOut);
-                outputOffset += chunkSize;
-                inputOffset = inputLocalFileHeaderStartOffset;
-            }
-            LocalFileRecord inputLocalFileRecord =
-                    LocalFileRecord.getRecord(
-                            inputApkLfhSection, inputCdRecord, inputApkLfhSection.size());
-            inputOffset += inputLocalFileRecord.getSize();
-
-            ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest =
-                    entryInstructions.getInspectJarEntryRequest();
-            if (inspectEntryRequest != null) {
-                fulfillInspectInputJarEntryRequest(
-                        inputApkLfhSection, inputLocalFileRecord, inspectEntryRequest);
-            }
-
-            if (shouldOutput) {
-                // Find the max value of last modified, to be used for new entries added by the
-                // signer.
-                int lastModifiedDate = inputCdRecord.getLastModificationDate();
-                int lastModifiedTime = inputCdRecord.getLastModificationTime();
-                if ((lastModifiedDateForNewEntries == -1)
-                        || (lastModifiedDate > lastModifiedDateForNewEntries)
-                        || ((lastModifiedDate == lastModifiedDateForNewEntries)
-                                && (lastModifiedTime > lastModifiedTimeForNewEntries))) {
-                    lastModifiedDateForNewEntries = lastModifiedDate;
-                    lastModifiedTimeForNewEntries = lastModifiedTime;
-                }
-
-                inspectEntryRequest = signerEngine.outputJarEntry(entryName);
-                if (inspectEntryRequest != null) {
-                    fulfillInspectInputJarEntryRequest(
-                            inputApkLfhSection, inputLocalFileRecord, inspectEntryRequest);
-                }
-
-                // Output entry's Local File Header + data
-                long outputLocalFileHeaderOffset = outputOffset;
-                long outputLocalFileRecordSize =
-                        outputInputJarEntryLfhRecordPreservingDataAlignment(
-                                inputApkLfhSection,
-                                inputLocalFileRecord,
-                                outputApkOut,
-                                outputLocalFileHeaderOffset);
-                outputOffset += outputLocalFileRecordSize;
-
-                // Enqueue entry's Central Directory record for output
-                CentralDirectoryRecord outputCdRecord;
-                if (outputLocalFileHeaderOffset == inputLocalFileRecord.getStartOffsetInArchive()) {
-                    outputCdRecord = inputCdRecord;
-                } else {
-                    outputCdRecord =
-                            inputCdRecord.createWithModifiedLocalFileHeaderOffset(
-                                    outputLocalFileHeaderOffset);
-                }
-                outputCdRecordsByName.put(entryName, outputCdRecord);
-            }
-        }
-        long inputLfhSectionSize = inputApkLfhSection.size();
-        if (inputOffset < inputLfhSectionSize) {
-            // Unprocessed data in input starting at inputOffset and ending and the end of the input
-            // APK's LFH section. We output this data verbatim because this signer is supposed
-            // to preserve as much of input as possible.
-            long chunkSize = inputLfhSectionSize - inputOffset;
-            inputApkLfhSection.feed(inputOffset, chunkSize, outputApkOut);
-            outputOffset += chunkSize;
-            inputOffset = inputLfhSectionSize;
-        }
-
-        // Step 4. Sort output APK's Central Directory records in the order in which they should
-        // appear in the output
-        List<CentralDirectoryRecord> outputCdRecords = new ArrayList<>(inputCdRecords.size() + 10);
-        for (CentralDirectoryRecord inputCdRecord : inputCdRecords) {
-            String entryName = inputCdRecord.getName();
-            CentralDirectoryRecord outputCdRecord = outputCdRecordsByName.get(entryName);
-            if (outputCdRecord != null) {
-                outputCdRecords.add(outputCdRecord);
-            }
-        }
-
-        // Step 5. Generate and output JAR signatures, if necessary. This may output more Local File
-        // Header + data entries and add to the list of output Central Directory records.
-        ApkSignerEngine.OutputJarSignatureRequest outputJarSignatureRequest =
-                signerEngine.outputJarEntries();
-        if (outputJarSignatureRequest != null) {
-            if (lastModifiedDateForNewEntries == -1) {
-                lastModifiedDateForNewEntries = 0x3a21; // Jan 1 2009 (DOS)
-                lastModifiedTimeForNewEntries = 0;
-            }
-            for (ApkSignerEngine.OutputJarSignatureRequest.JarEntry entry :
-                    outputJarSignatureRequest.getAdditionalJarEntries()) {
-                String entryName = entry.getName();
-                byte[] uncompressedData = entry.getData();
-                ZipUtils.DeflateResult deflateResult =
-                        ZipUtils.deflate(ByteBuffer.wrap(uncompressedData));
-                byte[] compressedData = deflateResult.output;
-                long uncompressedDataCrc32 = deflateResult.inputCrc32;
-
-                ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest =
-                        signerEngine.outputJarEntry(entryName);
-                if (inspectEntryRequest != null) {
-                    inspectEntryRequest.getDataSink().consume(
-                            uncompressedData, 0, uncompressedData.length);
-                    inspectEntryRequest.done();
-                }
-
-                long localFileHeaderOffset = outputOffset;
-                outputOffset +=
-                        LocalFileRecord.outputRecordWithDeflateCompressedData(
-                                entryName,
-                                lastModifiedTimeForNewEntries,
-                                lastModifiedDateForNewEntries,
-                                compressedData,
-                                uncompressedDataCrc32,
-                                uncompressedData.length,
-                                outputApkOut);
-
-
-                outputCdRecords.add(
-                        CentralDirectoryRecord.createWithDeflateCompressedData(
-                                entryName,
-                                lastModifiedTimeForNewEntries,
-                                lastModifiedDateForNewEntries,
-                                uncompressedDataCrc32,
-                                compressedData.length,
-                                uncompressedData.length,
-                                localFileHeaderOffset));
-            }
-            outputJarSignatureRequest.done();
-        }
-
-        // Step 6. Construct output ZIP Central Directory in an in-memory buffer
-        long outputCentralDirSizeBytes = 0;
-        for (CentralDirectoryRecord record : outputCdRecords) {
-            outputCentralDirSizeBytes += record.getSize();
-        }
-        if (outputCentralDirSizeBytes > Integer.MAX_VALUE) {
-            throw new IOException(
-                    "Output ZIP Central Directory too large: " + outputCentralDirSizeBytes
-                            + " bytes");
-        }
-        ByteBuffer outputCentralDir = ByteBuffer.allocate((int) outputCentralDirSizeBytes);
-        for (CentralDirectoryRecord record : outputCdRecords) {
-            record.copyTo(outputCentralDir);
-        }
-        outputCentralDir.flip();
-        DataSource outputCentralDirDataSource = new ByteBufferDataSource(outputCentralDir);
-        long outputCentralDirStartOffset = outputOffset;
-        int outputCentralDirRecordCount = outputCdRecords.size();
-
-        // Step 7. Construct output ZIP End of Central Directory record in an in-memory buffer
-        ByteBuffer outputEocd =
-                EocdRecord.createWithModifiedCentralDirectoryInfo(
-                        inputZipSections.getZipEndOfCentralDirectory(),
-                        outputCentralDirRecordCount,
-                        outputCentralDirDataSource.size(),
-                        outputCentralDirStartOffset);
-
-        // Step 8. Generate and output APK Signature Scheme v2 signatures, if necessary. This may
-        // insert an APK Signing Block just before the output's ZIP Central Directory
-        ApkSignerEngine.OutputApkSigningBlockRequest outputApkSigingBlockRequest =
-                signerEngine.outputZipSections(
-                        outputApkIn,
-                        outputCentralDirDataSource,
-                        DataSources.asDataSource(outputEocd));
-        if (outputApkSigingBlockRequest != null) {
-            byte[] outputApkSigningBlock = outputApkSigingBlockRequest.getApkSigningBlock();
-            outputApkOut.consume(outputApkSigningBlock, 0, outputApkSigningBlock.length);
-            ZipUtils.setZipEocdCentralDirectoryOffset(
-                    outputEocd, outputCentralDirStartOffset + outputApkSigningBlock.length);
-            outputApkSigingBlockRequest.done();
-        }
-
-        // Step 9. Output ZIP Central Directory and ZIP End of Central Directory
-        outputCentralDirDataSource.feed(0, outputCentralDirDataSource.size(), outputApkOut);
-        outputApkOut.consume(outputEocd);
-        signerEngine.outputDone();
-    }
-
-    private static void fulfillInspectInputJarEntryRequest(
-            DataSource lfhSection,
-            LocalFileRecord localFileRecord,
-            ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest)
-                    throws IOException, ZipFormatException {
-        localFileRecord.outputUncompressedData(lfhSection, inspectEntryRequest.getDataSink());
-        inspectEntryRequest.done();
-    }
-
-    private static long outputInputJarEntryLfhRecordPreservingDataAlignment(
-            DataSource inputLfhSection,
-            LocalFileRecord inputRecord,
-            DataSink outputLfhSection,
-            long outputOffset) throws IOException {
-        long inputOffset = inputRecord.getStartOffsetInArchive();
-        if (inputOffset == outputOffset) {
-            // This record's data will be aligned same as in the input APK.
-            return inputRecord.outputRecord(inputLfhSection, outputLfhSection);
-        }
-        int dataAlignmentMultiple = getInputJarEntryDataAlignmentMultiple(inputRecord);
-        if ((dataAlignmentMultiple <= 1)
-                || ((inputOffset % dataAlignmentMultiple)
-                        == (outputOffset % dataAlignmentMultiple))) {
-            // This record's data will be aligned same as in the input APK.
-            return inputRecord.outputRecord(inputLfhSection, outputLfhSection);
-        }
-
-        long inputDataStartOffset = inputOffset + inputRecord.getDataStartOffsetInRecord();
-        if ((inputDataStartOffset % dataAlignmentMultiple) != 0) {
-            // This record's data is not aligned in the input APK. No need to align it in the
-            // output.
-            return inputRecord.outputRecord(inputLfhSection, outputLfhSection);
-        }
-
-        // This record's data needs to be re-aligned in the output. This is achieved using the
-        // record's extra field.
-        ByteBuffer aligningExtra =
-                createExtraFieldToAlignData(
-                        inputRecord.getExtra(),
-                        outputOffset + inputRecord.getExtraFieldStartOffsetInsideRecord(),
-                        dataAlignmentMultiple);
-        return inputRecord.outputRecordWithModifiedExtra(
-                inputLfhSection, aligningExtra, outputLfhSection);
-    }
-
-    private static int getInputJarEntryDataAlignmentMultiple(LocalFileRecord entry) {
-        if (entry.isDataCompressed()) {
-            // Compressed entries don't need to be aligned
-            return 1;
-        }
-
-        // Attempt to obtain the alignment multiple from the entry's extra field.
-        ByteBuffer extra = entry.getExtra();
-        if (extra.hasRemaining()) {
-            extra.order(ByteOrder.LITTLE_ENDIAN);
-            // FORMAT: sequence of fields. Each field consists of:
-            //   * uint16 ID
-            //   * uint16 size
-            //   * 'size' bytes: payload
-            while (extra.remaining() >= 4) {
-                short headerId  = extra.getShort();
-                int dataSize = ZipUtils.getUnsignedInt16(extra);
-                if (dataSize > extra.remaining()) {
-                    // Malformed field -- insufficient input remaining
-                    break;
-                }
-                if (headerId != ALIGNMENT_ZIP_EXTRA_DATA_FIELD_HEADER_ID) {
-                    // Skip this field
-                    extra.position(extra.position() + dataSize);
-                    continue;
-                }
-                // This is APK alignment field.
-                // FORMAT:
-                //  * uint16 alignment multiple (in bytes)
-                //  * remaining bytes -- padding to achieve alignment of data which starts after
-                //    the extra field
-                if (dataSize < 2) {
-                    // Malformed
-                    break;
-                }
-                return ZipUtils.getUnsignedInt16(extra);
-            }
-        }
-
-        // Fall back to filename-based defaults
-        return (entry.getName().endsWith(".so")) ? 4096 : 4;
-    }
-
-    private static ByteBuffer createExtraFieldToAlignData(
-            ByteBuffer original,
-            long extraStartOffset,
-            int dataAlignmentMultiple) {
-        if (dataAlignmentMultiple <= 1) {
-            return original;
-        }
-
-        // In the worst case scenario, we'll increase the output size by 6 + dataAlignment - 1.
-        ByteBuffer result = ByteBuffer.allocate(original.remaining() + 5 + dataAlignmentMultiple);
-        result.order(ByteOrder.LITTLE_ENDIAN);
-
-        // Step 1. Output all extra fields other than the one which is to do with alignment
-        // FORMAT: sequence of fields. Each field consists of:
-        //   * uint16 ID
-        //   * uint16 size
-        //   * 'size' bytes: payload
-        while (original.remaining() >= 4) {
-            short headerId  = original.getShort();
-            int dataSize = ZipUtils.getUnsignedInt16(original);
-            if (dataSize > original.remaining()) {
-                // Malformed field -- insufficient input remaining
-                break;
-            }
-            if (((headerId == 0) && (dataSize == 0))
-                    || (headerId == ALIGNMENT_ZIP_EXTRA_DATA_FIELD_HEADER_ID)) {
-                // Ignore the field if it has to do with the old APK data alignment method (filling
-                // the extra field with 0x00 bytes) or the new APK data alignment method.
-                original.position(original.position() + dataSize);
-                continue;
-            }
-            // Copy this field (including header) to the output
-            original.position(original.position() - 4);
-            int originalLimit = original.limit();
-            original.limit(original.position() + 4 + dataSize);
-            result.put(original);
-            original.limit(originalLimit);
-        }
-
-        // Step 2. Add alignment field
-        // FORMAT:
-        //  * uint16 extra header ID
-        //  * uint16 extra data size
-        //        Payload ('data size' bytes)
-        //      * uint16 alignment multiple (in bytes)
-        //      * remaining bytes -- padding to achieve alignment of data which starts after the
-        //        extra field
-        long dataMinStartOffset =
-                extraStartOffset + result.position()
-                        + ALIGNMENT_ZIP_EXTRA_DATA_FIELD_MIN_SIZE_BYTES;
-        int paddingSizeBytes =
-                (dataAlignmentMultiple - ((int) (dataMinStartOffset % dataAlignmentMultiple)))
-                        % dataAlignmentMultiple;
-        result.putShort(ALIGNMENT_ZIP_EXTRA_DATA_FIELD_HEADER_ID);
-        ZipUtils.putUnsignedInt16(result, 2 + paddingSizeBytes);
-        ZipUtils.putUnsignedInt16(result, dataAlignmentMultiple);
-        result.position(result.position() + paddingSizeBytes);
-        result.flip();
-
-        return result;
-    }
-
-    private static ByteBuffer getZipCentralDirectory(
-            DataSource apk,
-            ApkUtils.ZipSections apkSections) throws IOException, ZipFormatException {
-        long cdSizeBytes = apkSections.getZipCentralDirectorySizeBytes();
-        if (cdSizeBytes > Integer.MAX_VALUE) {
-            throw new ZipFormatException("ZIP Central Directory too large: " + cdSizeBytes);
-        }
-        long cdOffset = apkSections.getZipCentralDirectoryOffset();
-        ByteBuffer cd = apk.getByteBuffer(cdOffset, (int) cdSizeBytes);
-        cd.order(ByteOrder.LITTLE_ENDIAN);
-        return cd;
-    }
-
-    private static List<CentralDirectoryRecord> parseZipCentralDirectory(
-            ByteBuffer cd,
-            ApkUtils.ZipSections apkSections) throws ZipFormatException {
-        long cdOffset = apkSections.getZipCentralDirectoryOffset();
-        int expectedCdRecordCount = apkSections.getZipCentralDirectoryRecordCount();
-        List<CentralDirectoryRecord> cdRecords = new ArrayList<>(expectedCdRecordCount);
-        Set<String> entryNames = new HashSet<>(expectedCdRecordCount);
-        for (int i = 0; i < expectedCdRecordCount; i++) {
-            CentralDirectoryRecord cdRecord;
-            int offsetInsideCd = cd.position();
-            try {
-                cdRecord = CentralDirectoryRecord.getRecord(cd);
-            } catch (ZipFormatException e) {
-                throw new ZipFormatException(
-                        "Failed to parse ZIP Central Directory record #" + (i + 1)
-                                + " at file offset " + (cdOffset + offsetInsideCd),
-                        e);
-            }
-            String entryName = cdRecord.getName();
-            if (!entryNames.add(entryName)) {
-                throw new ZipFormatException(
-                        "Malformed APK: multiple JAR entries with the same name: " + entryName);
-            }
-            cdRecords.add(cdRecord);
-        }
-        if (cd.hasRemaining()) {
-            throw new ZipFormatException(
-                    "Unused space at the end of ZIP Central Directory: " + cd.remaining()
-                        + " bytes starting at file offset " + (cdOffset + cd.position()));
-        }
-
-        return cdRecords;
-    }
-
-    /**
-     * Builder of {@link ApkSigner} instances.
-     *
-     * <p>The following information is required to construct a working {@code ApkSigner}:
-     * <ul>
-     * <li>{@link ApkSignerEngine} -- provided in the constructor,</li>
-     * <li>APK to be signed -- see {@link #setInputApk(File) setInputApk} variants,</li>
-     * <li>where to store the signed APK -- see {@link #setOutputApk(File) setOutputApk} variants.
-     * </li>
-     * </ul>
-     */
-    public static class Builder {
-        private final ApkSignerEngine mSignerEngine;
-
-        private File mInputApkFile;
-        private DataSource mInputApkDataSource;
-
-        private File mOutputApkFile;
-        private DataSink mOutputApkDataSink;
-        private DataSource mOutputApkDataSource;
-
-        /**
-         * Constructs a new {@code Builder} which will make {@code ApkSigner} use the provided
-         * signing engine.
-         */
-        public Builder(ApkSignerEngine signerEngine) {
-            mSignerEngine = signerEngine;
-        }
-
-        /**
-         * Sets the APK to be signed.
-         *
-         * @see #setInputApk(DataSource)
-         */
-        public Builder setInputApk(File inputApk) {
-            if (inputApk == null) {
-                throw new NullPointerException("inputApk == null");
-            }
-            mInputApkFile = inputApk;
-            mInputApkDataSource = null;
-            return this;
-        }
-
-        /**
-         * Sets the APK to be signed.
-         *
-         * @see #setInputApk(File)
-         */
-        public Builder setInputApk(DataSource inputApk) {
-            if (inputApk == null) {
-                throw new NullPointerException("inputApk == null");
-            }
-            mInputApkDataSource = inputApk;
-            mInputApkFile = null;
-            return this;
-        }
-
-        /**
-         * Sets the location of the output (signed) APK. {@code ApkSigner} will create this file if
-         * it doesn't exist.
-         *
-         * @see #setOutputApk(DataSink, DataSource)
-         */
-        public Builder setOutputApk(File outputApk) {
-            if (outputApk == null) {
-                throw new NullPointerException("outputApk == null");
-            }
-            mOutputApkFile = outputApk;
-            mOutputApkDataSink = null;
-            mOutputApkDataSource = null;
-            return this;
-        }
-
-        /**
-         * Sets the sink which will receive the output (signed) APK. Data received by the
-         * {@code outputApkOut} sink must be visible through the {@code outputApkIn} data source.
-         *
-         * @see #setOutputApk(File)
-         */
-        public Builder setOutputApk(DataSink outputApkOut, DataSource outputApkIn) {
-            if (outputApkOut == null) {
-                throw new NullPointerException("outputApkOut == null");
-            }
-            if (outputApkIn == null) {
-                throw new NullPointerException("outputApkIn == null");
-            }
-            mOutputApkFile = null;
-            mOutputApkDataSink = outputApkOut;
-            mOutputApkDataSource = outputApkIn;
-            return this;
-        }
-
-        /**
-         * Returns a new {@code ApkSigner} instance initialized according to the configuration of
-         * this builder.
-         */
-        public ApkSigner build() {
-            return new ApkSigner(
-                    mSignerEngine,
-                    mInputApkFile,
-                    mInputApkDataSource,
-                    mOutputApkFile,
-                    mOutputApkDataSink,
-                    mOutputApkDataSource);
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/ApkSignerEngine.java b/tools/apksigner/core/src/com/android/apksigner/core/ApkSignerEngine.java
deleted file mode 100644
index 21c2706..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/ApkSignerEngine.java
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SignatureException;
-import java.util.List;
-
-import com.android.apksigner.core.util.DataSink;
-import com.android.apksigner.core.util.DataSource;
-
-/**
- * APK signing logic which is independent of how input and output APKs are stored, parsed, and
- * generated.
- *
- * <p><h3>Operating Model</h3>
- *
- * The abstract operating model is that there is an input APK which is being signed, thus producing
- * an output APK. In reality, there may be just an output APK being built from scratch, or the input
- * APK and the output APK may be the same file. Because this engine does not deal with reading and
- * writing files, it can handle all of these scenarios.
- *
- * <p>The engine is stateful and thus cannot be used for signing multiple APKs. However, once
- * the engine signed an APK, the engine can be used to re-sign the APK after it has been modified.
- * This may be more efficient than signing the APK using a new instance of the engine. See
- * <a href="#incremental">Incremental Operation</a>.
- *
- * <p>In the engine's operating model, a signed APK is produced as follows.
- * <ol>
- * <li>JAR entries to be signed are output,</li>
- * <li>JAR archive is signed using JAR signing, thus adding the so-called v1 signature to the
- *     output,</li>
- * <li>JAR archive is signed using APK Signature Scheme v2, thus adding the so-called v2 signature
- *     to the output.</li>
- * </ol>
- *
- * <p>The input APK may contain JAR entries which, depending on the engine's configuration, may or
- * may not be output (e.g., existing signatures may need to be preserved or stripped) or which the
- * engine will overwrite as part of signing. The engine thus offers {@link #inputJarEntry(String)}
- * which tells the client whether the input JAR entry needs to be output. This avoids the need for
- * the client to hard-code the aspects of APK signing which determine which parts of input must be
- * ignored. Similarly, the engine offers {@link #inputApkSigningBlock(DataSource)} to help the
- * client avoid dealing with preserving or stripping APK Signature Scheme v2 signature of the input
- * APK.
- *
- * <p>To use the engine to sign an input APK (or a collection of JAR entries), follow these
- * steps:
- * <ol>
- * <li>Obtain a new instance of the engine -- engine instances are stateful and thus cannot be used
- *     for signing multiple APKs.</li>
- * <li>Locate the input APK's APK Signing Block and provide it to
- *     {@link #inputApkSigningBlock(DataSource)}.</li>
- * <li>For each JAR entry in the input APK, invoke {@link #inputJarEntry(String)} to determine
- *     whether this entry should be output. The engine may request to inspect the entry.</li>
- * <li>For each output JAR entry, invoke {@link #outputJarEntry(String)} which may request to
- *     inspect the entry.</li>
- * <li>Once all JAR entries have been output, invoke {@link #outputJarEntries()} which may request
- *     that additional JAR entries are output. These entries comprise the output APK's JAR
- *     signature.</li>
- * <li>Locate the ZIP Central Directory and ZIP End of Central Directory sections in the output and
- *     invoke {@link #outputZipSections(DataSource, DataSource, DataSource)} which may request that
- *     an APK Signature Block is inserted before the ZIP Central Directory. The block contains the
- *     output APK's APK Signature Scheme v2 signature.</li>
- * <li>Invoke {@link #outputDone()} to signal that the APK was output in full. The engine will
- *     confirm that the output APK is signed.</li>
- * <li>Invoke {@link #close()} to signal that the engine will no longer be used. This lets the
- *     engine free any resources it no longer needs.
- * </ol>
- *
- * <p>Some invocations of the engine may provide the client with a task to perform. The client is
- * expected to perform all requested tasks before proceeding to the next stage of signing. See
- * documentation of each method about the deadlines for performing the tasks requested by the
- * method.
- *
- * <p><h3 id="incremental">Incremental Operation</h3></a>
- *
- * The engine supports incremental operation where a signed APK is produced, then modified and
- * re-signed. This may be useful for IDEs, where an app is frequently re-signed after small changes
- * by the developer. Re-signing may be more efficient than signing from scratch.
- *
- * <p>To use the engine in incremental mode, keep notifying the engine of changes to the APK through
- * {@link #inputApkSigningBlock(DataSource)}, {@link #inputJarEntry(String)},
- * {@link #inputJarEntryRemoved(String)}, {@link #outputJarEntry(String)},
- * and {@link #outputJarEntryRemoved(String)}, perform the tasks requested by the engine through
- * these methods, and, when a new signed APK is desired, run through steps 5 onwards to re-sign the
- * APK.
- *
- * <p><h3>Output-only Operation</h3>
- *
- * The engine's abstract operating model consists of an input APK and an output APK. However, it is
- * possible to use the engine in output-only mode where the engine's {@code input...} methods are
- * not invoked. In this mode, the engine has less control over output because it cannot request that
- * some JAR entries are not output. Nevertheless, the engine will attempt to make the output APK
- * signed and will report an error if cannot do so.
- */
-public interface ApkSignerEngine extends Closeable {
-
-    /**
-     * Indicates to this engine that the input APK contains the provided APK Signing Block. The
-     * block may contain signatures of the input APK, such as APK Signature Scheme v2 signatures.
-     *
-     * @param apkSigningBlock APK signing block of the input APK. The provided data source is
-     *        guaranteed to not be used by the engine after this method terminates.
-     *
-     * @throws IOException if an I/O error occurs while reading the APK Signing Block
-     * @throws IllegalStateException if this engine is closed
-     */
-    void inputApkSigningBlock(DataSource apkSigningBlock) throws IOException, IllegalStateException;
-
-    /**
-     * Indicates to this engine that the specified JAR entry was encountered in the input APK.
-     *
-     * <p>When an input entry is updated/changed, it's OK to not invoke
-     * {@link #inputJarEntryRemoved(String)} before invoking this method.
-     *
-     * @return instructions about how to proceed with this entry
-     *
-     * @throws IllegalStateException if this engine is closed
-     */
-    InputJarEntryInstructions inputJarEntry(String entryName) throws IllegalStateException;
-
-    /**
-     * Indicates to this engine that the specified JAR entry was output.
-     *
-     * <p>It is unnecessary to invoke this method for entries added to output by this engine (e.g.,
-     * requested by {@link #outputJarEntries()}) provided the entries were output with exactly the
-     * data requested by the engine.
-     *
-     * <p>When an already output entry is updated/changed, it's OK to not invoke
-     * {@link #outputJarEntryRemoved(String)} before invoking this method.
-     *
-     * @return request to inspect the entry or {@code null} if the engine does not need to inspect
-     *         the entry. The request must be fulfilled before {@link #outputJarEntries()} is
-     *         invoked.
-     *
-     * @throws IllegalStateException if this engine is closed
-     */
-    InspectJarEntryRequest outputJarEntry(String entryName) throws IllegalStateException;
-
-    /**
-     * Indicates to this engine that the specified JAR entry was removed from the input. It's safe
-     * to invoke this for entries for which {@link #inputJarEntry(String)} hasn't been invoked.
-     *
-     * @return output policy of this JAR entry. The policy indicates how this input entry affects
-     *         the output APK. The client of this engine should use this information to determine
-     *         how the removal of this input APK's JAR entry affects the output APK.
-     *
-     * @throws IllegalStateException if this engine is closed
-     */
-    InputJarEntryInstructions.OutputPolicy inputJarEntryRemoved(String entryName)
-            throws IllegalStateException;
-
-    /**
-     * Indicates to this engine that the specified JAR entry was removed from the output. It's safe
-     * to invoke this for entries for which {@link #outputJarEntry(String)} hasn't been invoked.
-     *
-     * @throws IllegalStateException if this engine is closed
-     */
-    void outputJarEntryRemoved(String entryName) throws IllegalStateException;
-
-    /**
-     * Indicates to this engine that all JAR entries have been output.
-     *
-     *
-     * @return request to add JAR signature to the output or {@code null} if there is no need to add
-     *         a JAR signature. The request will contain additional JAR entries to be output. The
-     *         request must be fulfilled before
-     *         {@link #outputZipSections(DataSource, DataSource, DataSource)} is invoked.
-     *
-     * @throws NoSuchAlgorithmException if a signature could not be generated because a required
-     *         cryptographic algorithm implementation is missing
-     * @throws InvalidKeyException if a signature could not be generated because a signing key is
-     *         not suitable for generating the signature
-     * @throws SignatureException if an error occurred while generating a signature
-     * @throws IllegalStateException if there are unfulfilled requests, such as to inspect some JAR
-     *         entries, or if the engine is closed
-     */
-    OutputJarSignatureRequest outputJarEntries()
-            throws NoSuchAlgorithmException, InvalidKeyException, SignatureException,
-                    IllegalStateException;
-
-    /**
-     * Indicates to this engine that the ZIP sections comprising the output APK have been output.
-     *
-     * <p>The provided data sources are guaranteed to not be used by the engine after this method
-     * terminates.
-     *
-     * @param 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 zipCentralDirectory ZIP Central Directory section
-     * @param zipEocd ZIP End of Central Directory (EoCD) record
-     *
-     * @return 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
-     *         {@link #outputDone()} is invoked.
-     *
-     * @throws IOException if an I/O error occurs while reading the provided ZIP sections
-     * @throws NoSuchAlgorithmException if a signature could not be generated because a required
-     *         cryptographic algorithm implementation is missing
-     * @throws InvalidKeyException if a signature could not be generated because a signing key is
-     *         not suitable for generating the signature
-     * @throws SignatureException if an error occurred while generating a signature
-     * @throws IllegalStateException if there are unfulfilled requests, such as to inspect some JAR
-     *         entries or to output JAR signature, or if the engine is closed
-     */
-    OutputApkSigningBlockRequest outputZipSections(
-            DataSource zipEntries,
-            DataSource zipCentralDirectory,
-            DataSource zipEocd)
-                    throws IOException, NoSuchAlgorithmException, InvalidKeyException,
-                            SignatureException, IllegalStateException;
-
-    /**
-     * Indicates to this engine that the signed APK was output.
-     *
-     * <p>This does not change the output APK. The method helps the client confirm that the current
-     * output is signed.
-     *
-     * @throws IllegalStateException if there are unfulfilled requests, such as to inspect some JAR
-     *         entries or to output signatures, or if the engine is closed
-     */
-    void outputDone() throws IllegalStateException;
-
-    /**
-     * Indicates to this engine that it will no longer be used. Invoking this on an already closed
-     * engine is OK.
-     *
-     * <p>This does not change the output APK. For example, if the output APK is not yet fully
-     * signed, it will remain so after this method terminates.
-     */
-    @Override
-    void close();
-
-    /**
-     * Instructions about how to handle an input APK's JAR entry.
-     *
-     * <p>The instructions indicate whether to output the entry (see {@link #getOutputPolicy()}) and
-     * may contain a request to inspect the entry (see {@link #getInspectJarEntryRequest()}), in
-     * which case the request must be fulfilled before {@link ApkSignerEngine#outputJarEntries()} is
-     * invoked.
-     */
-    public static class InputJarEntryInstructions {
-        private final OutputPolicy mOutputPolicy;
-        private final InspectJarEntryRequest mInspectJarEntryRequest;
-
-        /**
-         * Constructs a new {@code InputJarEntryInstructions} instance with the provided entry
-         * output policy and without a request to inspect the entry.
-         */
-        public InputJarEntryInstructions(OutputPolicy outputPolicy) {
-            this(outputPolicy, null);
-        }
-
-        /**
-         * Constructs a new {@code InputJarEntryInstructions} instance with the provided entry
-         * output mode and with the provided request to inspect the entry.
-         *
-         * @param inspectJarEntryRequest request to inspect the entry or {@code null} if there's no
-         *        need to inspect the entry.
-         */
-        public InputJarEntryInstructions(
-                OutputPolicy outputPolicy,
-                InspectJarEntryRequest inspectJarEntryRequest) {
-            mOutputPolicy = outputPolicy;
-            mInspectJarEntryRequest = inspectJarEntryRequest;
-        }
-
-        /**
-         * Returns the output policy for this entry.
-         */
-        public OutputPolicy getOutputPolicy() {
-            return mOutputPolicy;
-        }
-
-        /**
-         * Returns the request to inspect the JAR entry or {@code null} if there is no need to
-         * inspect the entry.
-         */
-        public InspectJarEntryRequest getInspectJarEntryRequest() {
-            return mInspectJarEntryRequest;
-        }
-
-        /**
-         * Output policy for an input APK's JAR entry.
-         */
-        public static enum OutputPolicy {
-            /** Entry must not be output. */
-            SKIP,
-
-            /** Entry should be output. */
-            OUTPUT,
-
-            /** Entry will be output by the engine. The client can thus ignore this input entry. */
-            OUTPUT_BY_ENGINE,
-        }
-    }
-
-    /**
-     * Request to inspect the specified JAR entry.
-     *
-     * <p>The entry's uncompressed data must be provided to the data sink returned by
-     * {@link #getDataSink()}. Once the entry's data has been provided to the sink, {@link #done()}
-     * must be invoked.
-     */
-    interface InspectJarEntryRequest {
-
-        /**
-         * Returns the data sink into which the entry's uncompressed data should be sent.
-         */
-        DataSink getDataSink();
-
-        /**
-         * Indicates that entry's data has been provided in full.
-         */
-        void done();
-
-        /**
-         * Returns the name of the JAR entry.
-         */
-        String getEntryName();
-    }
-
-    /**
-     * Request to add JAR signature (aka v1 signature) to the output APK.
-     *
-     * <p>Entries listed in {@link #getAdditionalJarEntries()} must be added to the output APK after
-     * which {@link #done()} must be invoked.
-     */
-    interface OutputJarSignatureRequest {
-
-        /**
-         * Returns JAR entries that must be added to the output APK.
-         */
-        List<JarEntry> getAdditionalJarEntries();
-
-        /**
-         * Indicates that the JAR entries contained in this request were added to the output APK.
-         */
-        void done();
-
-        /**
-         * JAR entry.
-         */
-        public static class JarEntry {
-            private final String mName;
-            private final byte[] mData;
-
-            /**
-             * Constructs a new {@code JarEntry} with the provided name and data.
-             *
-             * @param data uncompressed data of the entry. Changes to this array will not be
-             *        reflected in {@link #getData()}.
-             */
-            public JarEntry(String name, byte[] data) {
-                mName = name;
-                mData = data.clone();
-            }
-
-            /**
-             * Returns the name of this ZIP entry.
-             */
-            public String getName() {
-                return mName;
-            }
-
-            /**
-             * Returns the uncompressed data of this JAR entry.
-             */
-            public byte[] getData() {
-                return mData.clone();
-            }
-        }
-    }
-
-    /**
-     * Request to add the specified APK Signing Block to the output APK. APK Signature Scheme v2
-     * signature(s) of the APK are contained in this block.
-     *
-     * <p>The APK Signing Block returned by {@link #getApkSigningBlock()} must be placed into the
-     * output APK such that the block is immediately before the ZIP Central Directory, the offset of
-     * ZIP Central Directory in the ZIP End of Central Directory record must be adjusted
-     * accordingly, and then {@link #done()} must be invoked.
-     *
-     * <p>If the output contains an APK Signing Block, that block must be replaced by the block
-     * contained in this request.
-     */
-    interface OutputApkSigningBlockRequest {
-
-        /**
-         * Returns the APK Signing Block.
-         */
-        byte[] getApkSigningBlock();
-
-        /**
-         * Indicates that the APK Signing Block was output as requested.
-         */
-        void done();
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/ApkVerifier.java b/tools/apksigner/core/src/com/android/apksigner/core/ApkVerifier.java
deleted file mode 100644
index f12b47f..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/ApkVerifier.java
+++ /dev/null
@@ -1,1233 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core;
-
-import com.android.apksigner.core.apk.ApkUtils;
-import com.android.apksigner.core.internal.apk.v1.V1SchemeVerifier;
-import com.android.apksigner.core.internal.apk.v2.ContentDigestAlgorithm;
-import com.android.apksigner.core.internal.apk.v2.SignatureAlgorithm;
-import com.android.apksigner.core.internal.apk.v2.V2SchemeVerifier;
-import com.android.apksigner.core.internal.util.AndroidSdkVersion;
-import com.android.apksigner.core.util.DataSource;
-import com.android.apksigner.core.util.DataSources;
-import com.android.apksigner.core.zip.ZipFormatException;
-
-import java.io.Closeable;
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * APK signature verifier which mimics the behavior of the Android platform.
- *
- * <p>The verifier is designed to closely mimic the behavior of Android platforms. This is to enable
- * the verifier to be used for checking whether an APK's signatures will verify on Android.
- *
- * <p>Use {@link Builder} to obtain instances of this verifier.
- */
-public class ApkVerifier {
-
-    private static final int APK_SIGNATURE_SCHEME_V2_ID = 2;
-    private static final Map<Integer, String> SUPPORTED_APK_SIG_SCHEME_NAMES =
-            Collections.singletonMap(APK_SIGNATURE_SCHEME_V2_ID, "APK Signature Scheme v2");
-
-    private final File mApkFile;
-    private final DataSource mApkDataSource;
-
-    private final int mMinSdkVersion;
-    private final int mMaxSdkVersion;
-
-    private ApkVerifier(
-            File apkFile,
-            DataSource apkDataSource,
-            int minSdkVersion,
-            int maxSdkVersion) {
-        mApkFile = apkFile;
-        mApkDataSource = apkDataSource;
-        mMinSdkVersion = minSdkVersion;
-        mMaxSdkVersion = maxSdkVersion;
-    }
-
-    /**
-     * Verifies the APK's signatures and returns the result of verification. The APK can be
-     * considered verified iff the result's {@link Result#isVerified()} returns {@code true}.
-     * The verification result also includes errors, warnings, and information about signers.
-     *
-     * @throws IOException if an I/O error is encountered while reading the APK
-     * @throws ZipFormatException if the APK is malformed at ZIP format level
-     * @throws NoSuchAlgorithmException if the APK's signatures cannot be verified because a
-     *         required cryptographic algorithm implementation is missing
-     * @throws IllegalStateException if this verifier's configuration is missing required
-     *         information.
-     */
-    public Result verify() throws IOException, ZipFormatException, NoSuchAlgorithmException,
-            IllegalStateException {
-        Closeable in = null;
-        try {
-            DataSource apk;
-            if (mApkDataSource != null) {
-                apk = mApkDataSource;
-            } else if (mApkFile != null) {
-                RandomAccessFile f = new RandomAccessFile(mApkFile, "r");
-                in = f;
-                apk = DataSources.asDataSource(f, 0, f.length());
-            } else {
-                throw new IllegalStateException("APK not provided");
-            }
-            return verify(apk, mMinSdkVersion, mMaxSdkVersion);
-        } finally {
-            if (in != null) {
-                in.close();
-            }
-        }
-    }
-
-    /**
-     * Verifies the APK's signatures and returns the result of verification. The APK can be
-     * considered verified iff the result's {@link Result#isVerified()} returns {@code true}.
-     * The verification result also includes errors, warnings, and information about signers.
-     *
-     * @param apk APK file contents
-     * @param minSdkVersion API Level of the oldest Android platform on which the APK's signatures
-     *        may need to be verified
-     * @param maxSdkVersion API Level of the newest Android platform on which the APK's signatures
-     *        may need to be verified
-     *
-     * @throws IOException if an I/O error is encountered while reading the APK
-     * @throws ZipFormatException if the APK is malformed at ZIP format level
-     * @throws NoSuchAlgorithmException if the APK's signatures cannot be verified because a
-     *         required cryptographic algorithm implementation is missing
-     */
-    private static Result verify(DataSource apk, int minSdkVersion, int maxSdkVersion)
-            throws IOException, ZipFormatException, NoSuchAlgorithmException {
-        if (minSdkVersion < 0) {
-            throw new IllegalArgumentException(
-                    "minSdkVersion must not be negative: " + minSdkVersion);
-        }
-        if (minSdkVersion > maxSdkVersion) {
-            throw new IllegalArgumentException(
-                    "minSdkVersion (" + minSdkVersion + ") > maxSdkVersion (" + maxSdkVersion
-                            + ")");
-        }
-        ApkUtils.ZipSections zipSections = ApkUtils.findZipSections(apk);
-
-        Result result = new Result();
-
-        // Android N and newer attempts to verify APK Signature Scheme v2 signature of the APK.
-        // If the signature is not found, it falls back to JAR signature verification. If the
-        // signature is found but does not verify, the APK is rejected.
-        Set<Integer> foundApkSigSchemeIds;
-        if (maxSdkVersion >= AndroidSdkVersion.N) {
-            foundApkSigSchemeIds = new HashSet<>(1);
-            try {
-                V2SchemeVerifier.Result v2Result = V2SchemeVerifier.verify(apk, zipSections);
-                foundApkSigSchemeIds.add(APK_SIGNATURE_SCHEME_V2_ID);
-                result.mergeFrom(v2Result);
-            } catch (V2SchemeVerifier.SignatureNotFoundException ignored) {}
-            if (result.containsErrors()) {
-                return result;
-            }
-        } else {
-            foundApkSigSchemeIds = Collections.emptySet();
-        }
-
-        // Attempt to verify the APK using JAR signing if necessary. Platforms prior to Android N
-        // ignore APK Signature Scheme v2 signatures and always attempt to verify JAR signatures.
-        // Android N onwards verifies JAR signatures only if no APK Signature Scheme v2 (or newer
-        // scheme) signatures were found.
-        if ((minSdkVersion < AndroidSdkVersion.N) || (foundApkSigSchemeIds.isEmpty())) {
-            V1SchemeVerifier.Result v1Result =
-                    V1SchemeVerifier.verify(
-                            apk,
-                            zipSections,
-                            SUPPORTED_APK_SIG_SCHEME_NAMES,
-                            foundApkSigSchemeIds,
-                            minSdkVersion,
-                            maxSdkVersion);
-            result.mergeFrom(v1Result);
-        }
-        if (result.containsErrors()) {
-            return result;
-        }
-
-        // Check whether v1 and v2 scheme signer identifies match, provided both v1 and v2
-        // signatures verified.
-        if ((result.isVerifiedUsingV1Scheme()) && (result.isVerifiedUsingV2Scheme())) {
-            ArrayList<Result.V1SchemeSignerInfo> v1Signers =
-                    new ArrayList<>(result.getV1SchemeSigners());
-            ArrayList<Result.V2SchemeSignerInfo> v2Signers =
-                    new ArrayList<>(result.getV2SchemeSigners());
-            ArrayList<ByteArray> v1SignerCerts = new ArrayList<>();
-            ArrayList<ByteArray> v2SignerCerts = new ArrayList<>();
-            for (Result.V1SchemeSignerInfo signer : v1Signers) {
-                try {
-                    v1SignerCerts.add(new ByteArray(signer.getCertificate().getEncoded()));
-                } catch (CertificateEncodingException e) {
-                    throw new RuntimeException(
-                            "Failed to encode JAR signer " + signer.getName() + " certs", e);
-                }
-            }
-            for (Result.V2SchemeSignerInfo signer : v2Signers) {
-                try {
-                    v2SignerCerts.add(new ByteArray(signer.getCertificate().getEncoded()));
-                } catch (CertificateEncodingException e) {
-                    throw new RuntimeException(
-                            "Failed to encode APK Signature Scheme v2 signer (index: "
-                                    + signer.getIndex() + ") certs",
-                            e);
-                }
-            }
-
-            for (int i = 0; i < v1SignerCerts.size(); i++) {
-                ByteArray v1Cert = v1SignerCerts.get(i);
-                if (!v2SignerCerts.contains(v1Cert)) {
-                    Result.V1SchemeSignerInfo v1Signer = v1Signers.get(i);
-                    v1Signer.addError(Issue.V2_SIG_MISSING);
-                    break;
-                }
-            }
-            for (int i = 0; i < v2SignerCerts.size(); i++) {
-                ByteArray v2Cert = v2SignerCerts.get(i);
-                if (!v1SignerCerts.contains(v2Cert)) {
-                    Result.V2SchemeSignerInfo v2Signer = v2Signers.get(i);
-                    v2Signer.addError(Issue.JAR_SIG_MISSING);
-                    break;
-                }
-            }
-        }
-        if (result.containsErrors()) {
-            return result;
-        }
-
-        // Verified
-        result.setVerified();
-        if (result.isVerifiedUsingV2Scheme()) {
-            for (Result.V2SchemeSignerInfo signerInfo : result.getV2SchemeSigners()) {
-                result.addSignerCertificate(signerInfo.getCertificate());
-            }
-        } else if (result.isVerifiedUsingV1Scheme()) {
-            for (Result.V1SchemeSignerInfo signerInfo : result.getV1SchemeSigners()) {
-                result.addSignerCertificate(signerInfo.getCertificate());
-            }
-        } else {
-            throw new RuntimeException(
-                    "APK considered verified, but has not verified using either v1 or v2 schemes");
-        }
-
-        return result;
-    }
-
-    /**
-     * Result of verifying an APKs signatures. The APK can be considered verified iff
-     * {@link #isVerified()} returns {@code true}.
-     */
-    public static class Result {
-        private final List<IssueWithParams> mErrors = new ArrayList<>();
-        private final List<IssueWithParams> mWarnings = new ArrayList<>();
-        private final List<X509Certificate> mSignerCerts = new ArrayList<>();
-        private final List<V1SchemeSignerInfo> mV1SchemeSigners = new ArrayList<>();
-        private final List<V1SchemeSignerInfo> mV1SchemeIgnoredSigners = new ArrayList<>();
-        private final List<V2SchemeSignerInfo> mV2SchemeSigners = new ArrayList<>();
-
-        private boolean mVerified;
-        private boolean mVerifiedUsingV1Scheme;
-        private boolean mVerifiedUsingV2Scheme;
-
-        /**
-         * Returns {@code true} if the APK's signatures verified.
-         */
-        public boolean isVerified() {
-            return mVerified;
-        }
-
-        private void setVerified() {
-            mVerified = true;
-        }
-
-        /**
-         * Returns {@code true} if the APK's JAR signatures verified.
-         */
-        public boolean isVerifiedUsingV1Scheme() {
-            return mVerifiedUsingV1Scheme;
-        }
-
-        /**
-         * Returns {@code true} if the APK's APK Signature Scheme v2 signatures verified.
-         */
-        public boolean isVerifiedUsingV2Scheme() {
-            return mVerifiedUsingV2Scheme;
-        }
-
-        /**
-         * Returns the verified signers' certificates, one per signer.
-         */
-        public List<X509Certificate> getSignerCertificates() {
-            return mSignerCerts;
-        }
-
-        private void addSignerCertificate(X509Certificate cert) {
-            mSignerCerts.add(cert);
-        }
-
-        /**
-         * Returns information about JAR signers associated with the APK's signature. These are the
-         * signers used by Android.
-         *
-         * @see #getV1SchemeIgnoredSigners()
-         */
-        public List<V1SchemeSignerInfo> getV1SchemeSigners() {
-            return mV1SchemeSigners;
-        }
-
-        /**
-         * Returns information about JAR signers ignored by the APK's signature verification
-         * process. These signers are ignored by Android. However, each signer's errors or warnings
-         * will contain information about why they are ignored.
-         *
-         * @see #getV1SchemeSigners()
-         */
-        public List<V1SchemeSignerInfo> getV1SchemeIgnoredSigners() {
-            return mV1SchemeIgnoredSigners;
-        }
-
-        /**
-         * Returns information about APK Signature Scheme v2 signers associated with the APK's
-         * signature.
-         */
-        public List<V2SchemeSignerInfo> getV2SchemeSigners() {
-            return mV2SchemeSigners;
-        }
-
-        /**
-         * Returns errors encountered while verifying the APK's signatures.
-         */
-        public List<IssueWithParams> getErrors() {
-            return mErrors;
-        }
-
-        /**
-         * Returns warnings encountered while verifying the APK's signatures.
-         */
-        public List<IssueWithParams> getWarnings() {
-            return mWarnings;
-        }
-
-        private void mergeFrom(V1SchemeVerifier.Result source) {
-            mVerifiedUsingV1Scheme = source.verified;
-            mErrors.addAll(source.getErrors());
-            mWarnings.addAll(source.getWarnings());
-            for (V1SchemeVerifier.Result.SignerInfo signer : source.signers) {
-                mV1SchemeSigners.add(new V1SchemeSignerInfo(signer));
-            }
-            for (V1SchemeVerifier.Result.SignerInfo signer : source.ignoredSigners) {
-                mV1SchemeIgnoredSigners.add(new V1SchemeSignerInfo(signer));
-            }
-        }
-
-        private void mergeFrom(V2SchemeVerifier.Result source) {
-            mVerifiedUsingV2Scheme = source.verified;
-            mErrors.addAll(source.getErrors());
-            mWarnings.addAll(source.getWarnings());
-            for (V2SchemeVerifier.Result.SignerInfo signer : source.signers) {
-                mV2SchemeSigners.add(new V2SchemeSignerInfo(signer));
-            }
-        }
-
-        /**
-         * Returns {@code true} if an error was encountered while verifying the APK. Any error
-         * prevents the APK from being considered verified.
-         */
-        public boolean containsErrors() {
-            if (!mErrors.isEmpty()) {
-                return true;
-            }
-            if (!mV1SchemeSigners.isEmpty()) {
-                for (V1SchemeSignerInfo signer : mV1SchemeSigners) {
-                    if (signer.containsErrors()) {
-                        return true;
-                    }
-                }
-            }
-            if (!mV2SchemeSigners.isEmpty()) {
-                for (V2SchemeSignerInfo signer : mV2SchemeSigners) {
-                    if (signer.containsErrors()) {
-                        return true;
-                    }
-                }
-            }
-
-            return false;
-        }
-
-        /**
-         * Information about a JAR signer associated with the APK's signature.
-         */
-        public static class V1SchemeSignerInfo {
-            private final String mName;
-            private final List<X509Certificate> mCertChain;
-            private final String mSignatureBlockFileName;
-            private final String mSignatureFileName;
-
-            private final List<IssueWithParams> mErrors;
-            private final List<IssueWithParams> mWarnings;
-
-            private V1SchemeSignerInfo(V1SchemeVerifier.Result.SignerInfo result) {
-                mName = result.name;
-                mCertChain = result.certChain;
-                mSignatureBlockFileName = result.signatureBlockFileName;
-                mSignatureFileName = result.signatureFileName;
-                mErrors = result.getErrors();
-                mWarnings = result.getWarnings();
-            }
-
-            /**
-             * Returns a user-friendly name of the signer.
-             */
-            public String getName() {
-                return mName;
-            }
-
-            /**
-             * Returns the name of the JAR entry containing this signer's JAR signature block file.
-             */
-            public String getSignatureBlockFileName() {
-                return mSignatureBlockFileName;
-            }
-
-            /**
-             * Returns the name of the JAR entry containing this signer's JAR signature file.
-             */
-            public String getSignatureFileName() {
-                return mSignatureFileName;
-            }
-
-            /**
-             * Returns this signer's signing certificate or {@code null} if not available. The
-             * certificate is guaranteed to be available if no errors were encountered during
-             * verification (see {@link #containsErrors()}.
-             *
-             * <p>This certificate contains the signer's public key.
-             */
-            public X509Certificate getCertificate() {
-                return mCertChain.isEmpty() ? null : mCertChain.get(0);
-            }
-
-            /**
-             * Returns the certificate chain for the signer's public key. The certificate containing
-             * the public key is first, followed by the certificate (if any) which issued the
-             * signing certificate, and so forth. An empty list may be returned if an error was
-             * encountered during verification (see {@link #containsErrors()}).
-             */
-            public List<X509Certificate> getCertificateChain() {
-                return mCertChain;
-            }
-
-            /**
-             * Returns {@code true} if an error was encountered while verifying this signer's JAR
-             * signature. Any error prevents the signer's signature from being considered verified.
-             */
-            public boolean containsErrors() {
-                return !mErrors.isEmpty();
-            }
-
-            /**
-             * Returns errors encountered while verifying this signer's JAR signature. Any error
-             * prevents the signer's signature from being considered verified.
-             */
-            public List<IssueWithParams> getErrors() {
-                return mErrors;
-            }
-
-            /**
-             * Returns warnings encountered while verifying this signer's JAR signature. Warnings
-             * do not prevent the signer's signature from being considered verified.
-             */
-            public List<IssueWithParams> getWarnings() {
-                return mWarnings;
-            }
-
-            private void addError(Issue msg, Object... parameters) {
-                mErrors.add(new IssueWithParams(msg, parameters));
-            }
-        }
-
-        /**
-         * Information about an APK Signature Scheme v2 signer associated with the APK's signature.
-         */
-        public static class V2SchemeSignerInfo {
-            private final int mIndex;
-            private final List<X509Certificate> mCerts;
-
-            private final List<IssueWithParams> mErrors;
-            private final List<IssueWithParams> mWarnings;
-
-            private V2SchemeSignerInfo(V2SchemeVerifier.Result.SignerInfo result) {
-                mIndex = result.index;
-                mCerts = result.certs;
-                mErrors = result.getErrors();
-                mWarnings = result.getWarnings();
-            }
-
-            /**
-             * Returns this signer's {@code 0}-based index in the list of signers contained in the
-             * APK's APK Signature Scheme v2 signature.
-             */
-            public int getIndex() {
-                return mIndex;
-            }
-
-            /**
-             * Returns this signer's signing certificate or {@code null} if not available. The
-             * certificate is guaranteed to be available if no errors were encountered during
-             * verification (see {@link #containsErrors()}.
-             *
-             * <p>This certificate contains the signer's public key.
-             */
-            public X509Certificate getCertificate() {
-                return mCerts.isEmpty() ? null : mCerts.get(0);
-            }
-
-            /**
-             * Returns this signer's certificates. The first certificate is for the signer's public
-             * key. An empty list may be returned if an error was encountered during verification
-             * (see {@link #containsErrors()}).
-             */
-            public List<X509Certificate> getCertificates() {
-                return mCerts;
-            }
-
-            private void addError(Issue msg, Object... parameters) {
-                mErrors.add(new IssueWithParams(msg, parameters));
-            }
-
-            public boolean containsErrors() {
-                return !mErrors.isEmpty();
-            }
-
-            public List<IssueWithParams> getErrors() {
-                return mErrors;
-            }
-
-            public List<IssueWithParams> getWarnings() {
-                return mWarnings;
-            }
-        }
-    }
-
-    /**
-     * Error or warning encountered while verifying an APK's signatures.
-     */
-    public static enum Issue {
-
-        /**
-         * APK is not JAR-signed.
-         */
-        JAR_SIG_NO_SIGNATURES("No JAR signatures"),
-
-        /**
-         * APK does not contain any entries covered by JAR signatures.
-         */
-        JAR_SIG_NO_SIGNED_ZIP_ENTRIES("No JAR entries covered by JAR signatures"),
-
-        /**
-         * APK contains multiple entries with the same name.
-         *
-         * <ul>
-         * <li>Parameter 1: name ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_DUPLICATE_ZIP_ENTRY("Duplicate entry: %1$s"),
-
-        /**
-         * JAR manifest contains a section with a duplicate name.
-         *
-         * <ul>
-         * <li>Parameter 1: section name ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_DUPLICATE_MANIFEST_SECTION("Duplicate section in META-INF/MANIFEST.MF: %1$s"),
-
-        /**
-         * JAR manifest contains a section without a name.
-         *
-         * <ul>
-         * <li>Parameter 1: section index (1-based) ({@code Integer})</li>
-         * </ul>
-         */
-        JAR_SIG_UNNNAMED_MANIFEST_SECTION(
-                "Malformed META-INF/MANIFEST.MF: invidual section #%1$d does not have a name"),
-
-        /**
-         * JAR signature file contains a section without a name.
-         *
-         * <ul>
-         * <li>Parameter 1: signature file name ({@code String})</li>
-         * <li>Parameter 2: section index (1-based) ({@code Integer})</li>
-         * </ul>
-         */
-        JAR_SIG_UNNNAMED_SIG_FILE_SECTION(
-                "Malformed %1$s: invidual section #%2$d does not have a name"),
-
-        /** APK is missing the JAR manifest entry (META-INF/MANIFEST.MF). */
-        JAR_SIG_NO_MANIFEST("Missing META-INF/MANIFEST.MF"),
-
-        /**
-         * JAR manifest references an entry which is not there in the APK.
-         *
-         * <ul>
-         * <li>Parameter 1: entry name ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_MISSING_ZIP_ENTRY_REFERENCED_IN_MANIFEST(
-                "%1$s entry referenced by META-INF/MANIFEST.MF not found in the APK"),
-
-        /**
-         * JAR manifest does not list a digest for the specified entry.
-         *
-         * <ul>
-         * <li>Parameter 1: entry name ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_NO_ZIP_ENTRY_DIGEST_IN_MANIFEST("No digest for %1$s in META-INF/MANIFEST.MF"),
-
-        /**
-         * JAR signature does not list a digest for the specified entry.
-         *
-         * <ul>
-         * <li>Parameter 1: entry name ({@code String})</li>
-         * <li>Parameter 2: signature file name ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_NO_ZIP_ENTRY_DIGEST_IN_SIG_FILE("No digest for %1$s in %2$s"),
-
-        /**
-         * The specified JAR entry is not covered by JAR signature.
-         *
-         * <ul>
-         * <li>Parameter 1: entry name ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_ZIP_ENTRY_NOT_SIGNED("%1$s entry not signed"),
-
-        /**
-         * JAR signature uses different set of signers to protect the two specified ZIP entries.
-         *
-         * <ul>
-         * <li>Parameter 1: first entry name ({@code String})</li>
-         * <li>Parameter 2: first entry signer names ({@code List<String>})</li>
-         * <li>Parameter 3: second entry name ({@code String})</li>
-         * <li>Parameter 4: second entry signer names ({@code List<String>})</li>
-         * </ul>
-         */
-        JAR_SIG_ZIP_ENTRY_SIGNERS_MISMATCH(
-                "Entries %1$s and %3$s are signed with different sets of signers"
-                        + " : <%2$s> vs <%4$s>"),
-
-        /**
-         * Digest of the specified ZIP entry's data does not match the digest expected by the JAR
-         * signature.
-         *
-         * <ul>
-         * <li>Parameter 1: entry name ({@code String})</li>
-         * <li>Parameter 2: digest algorithm (e.g., SHA-256) ({@code String})</li>
-         * <li>Parameter 3: name of the entry in which the expected digest is specified
-         *     ({@code String})</li>
-         * <li>Parameter 4: base64-encoded actual digest ({@code String})</li>
-         * <li>Parameter 5: base64-encoded expected digest ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_ZIP_ENTRY_DIGEST_DID_NOT_VERIFY(
-                "%2$s digest of %1$s does not match the digest specified in %3$s"
-                        + ". Expected: <%5$s>, actual: <%4$s>"),
-
-        /**
-         * Digest of the JAR manifest main section did not verify.
-         *
-         * <ul>
-         * <li>Parameter 1: digest algorithm (e.g., SHA-256) ({@code String})</li>
-         * <li>Parameter 2: name of the entry in which the expected digest is specified
-         *     ({@code String})</li>
-         * <li>Parameter 3: base64-encoded actual digest ({@code String})</li>
-         * <li>Parameter 4: base64-encoded expected digest ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_MANIFEST_MAIN_SECTION_DIGEST_DID_NOT_VERIFY(
-                "%1$s digest of META-INF/MANIFEST.MF main section does not match the digest"
-                        + " specified in %2$s. Expected: <%4$s>, actual: <%3$s>"),
-
-        /**
-         * Digest of the specified JAR manifest section does not match the digest expected by the
-         * JAR signature.
-         *
-         * <ul>
-         * <li>Parameter 1: section name ({@code String})</li>
-         * <li>Parameter 2: digest algorithm (e.g., SHA-256) ({@code String})</li>
-         * <li>Parameter 3: name of the signature file in which the expected digest is specified
-         *     ({@code String})</li>
-         * <li>Parameter 4: base64-encoded actual digest ({@code String})</li>
-         * <li>Parameter 5: base64-encoded expected digest ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_MANIFEST_SECTION_DIGEST_DID_NOT_VERIFY(
-                "%2$s digest of META-INF/MANIFEST.MF section for %1$s does not match the digest"
-                        + " specified in %3$s. Expected: <%5$s>, actual: <%4$s>"),
-
-        /**
-         * JAR signature file does not contain the whole-file digest of the JAR manifest file. The
-         * digest speeds up verification of JAR signature.
-         *
-         * <ul>
-         * <li>Parameter 1: name of the signature file ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_NO_MANIFEST_DIGEST_IN_SIG_FILE(
-                "%1$s does not specify digest of META-INF/MANIFEST.MF"
-                        + ". This slows down verification."),
-
-        /**
-         * APK is signed using APK Signature Scheme v2 or newer, but JAR signature file does not
-         * contain protections against stripping of these newer scheme signatures.
-         *
-         * <ul>
-         * <li>Parameter 1: name of the signature file ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_NO_APK_SIG_STRIP_PROTECTION(
-                "APK is signed using APK Signature Scheme v2 but these signatures may be stripped"
-                        + " without being detected because %1$s does not contain anti-stripping"
-                        + " protections."),
-
-        /**
-         * JAR signature of the signer is missing a file/entry.
-         *
-         * <ul>
-         * <li>Parameter 1: name of the encountered file ({@code String})</li>
-         * <li>Parameter 2: name of the missing file ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_MISSING_FILE("Partial JAR signature. Found: %1$s, missing: %2$s"),
-
-        /**
-         * An exception was encountered while verifying JAR signature contained in a signature block
-         * against the signature file.
-         *
-         * <ul>
-         * <li>Parameter 1: name of the signature block file ({@code String})</li>
-         * <li>Parameter 2: name of the signature file ({@code String})</li>
-         * <li>Parameter 3: exception ({@code Throwable})</li>
-         * </ul>
-         */
-        JAR_SIG_VERIFY_EXCEPTION("Failed to verify JAR signature %1$s against %2$s: %3$s"),
-
-        /**
-         * JAR signature contains unsupported digest algorithm.
-         *
-         * <ul>
-         * <li>Parameter 1: name of the signature block file ({@code String})</li>
-         * <li>Parameter 2: digest algorithm OID ({@code String})</li>
-         * <li>Parameter 2: signature algorithm OID ({@code String})</li>
-         * <li>Parameter 3: API Levels on which this combination of algorithms is not supported
-         *     ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_UNSUPPORTED_SIG_ALG(
-                "JAR signature %1$s uses digest algorithm %2$s and signature algorithm %3$s which"
-                        + " is not supported on API Levels %4$s"),
-
-        /**
-         * An exception was encountered while parsing JAR signature contained in a signature block.
-         *
-         * <ul>
-         * <li>Parameter 1: name of the signature block file ({@code String})</li>
-         * <li>Parameter 2: exception ({@code Throwable})</li>
-         * </ul>
-         */
-        JAR_SIG_PARSE_EXCEPTION("Failed to parse JAR signature %1$s: %2$s"),
-
-        /**
-         * An exception was encountered while parsing a certificate contained in the JAR signature
-         * block.
-         *
-         * <ul>
-         * <li>Parameter 1: name of the signature block file ({@code String})</li>
-         * <li>Parameter 2: exception ({@code Throwable})</li>
-         * </ul>
-         */
-        JAR_SIG_MALFORMED_CERTIFICATE("Malformed certificate in JAR signature %1$s: %2$s"),
-
-        /**
-         * JAR signature contained in a signature block file did not verify against the signature
-         * file.
-         *
-         * <ul>
-         * <li>Parameter 1: name of the signature block file ({@code String})</li>
-         * <li>Parameter 2: name of the signature file ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_DID_NOT_VERIFY("JAR signature %1$s did not verify against %2$s"),
-
-        /**
-         * JAR signature contains no verified signers.
-         *
-         * <ul>
-         * <li>Parameter 1: name of the signature block file ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_NO_SIGNERS("JAR signature %1$s contains no signers"),
-
-        /**
-         * JAR signature file contains a section with a duplicate name.
-         *
-         * <ul>
-         * <li>Parameter 1: signature file name ({@code String})</li>
-         * <li>Parameter 1: section name ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_DUPLICATE_SIG_FILE_SECTION("Duplicate section in %1$s: %2$s"),
-
-        /**
-         * JAR signature file's main section doesn't contain the mandatory Signature-Version
-         * attribute.
-         *
-         * <ul>
-         * <li>Parameter 1: signature file name ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_MISSING_VERSION_ATTR_IN_SIG_FILE(
-                "Malformed %1$s: missing Signature-Version attribute"),
-
-        /**
-         * JAR signature file references an unknown APK signature scheme ID.
-         *
-         * <ul>
-         * <li>Parameter 1: name of the signature file ({@code String})</li>
-         * <li>Parameter 2: unknown APK signature scheme ID ({@code} Integer)</li>
-         * </ul>
-         */
-        JAR_SIG_UNKNOWN_APK_SIG_SCHEME_ID(
-                "JAR signature %1$s references unknown APK signature scheme ID: %2$d"),
-
-        /**
-         * JAR signature file indicates that the APK is supposed to be signed with a supported APK
-         * signature scheme (in addition to the JAR signature) but no such signature was found in
-         * the APK.
-         *
-         * <ul>
-         * <li>Parameter 1: name of the signature file ({@code String})</li>
-         * <li>Parameter 2: APK signature scheme ID ({@code} Integer)</li>
-         * <li>Parameter 3: APK signature scheme English name ({@code} String)</li>
-         * </ul>
-         */
-        JAR_SIG_MISSING_APK_SIG_REFERENCED(
-                "JAR signature %1$s indicates the APK is signed using %3$s but no such signature"
-                        + " was found. Signature stripped?"),
-
-        /**
-         * JAR entry is not covered by signature and thus unauthorized modifications to its contents
-         * will not be detected.
-         *
-         * <ul>
-         * <li>Parameter 1: entry name ({@code String})</li>
-         * </ul>
-         */
-        JAR_SIG_UNPROTECTED_ZIP_ENTRY(
-                "%1$s not protected by signature. Unauthorized modifications to this JAR entry"
-                        + " will not be detected. Delete or move the entry outside of META-INF/."),
-
-        /**
-         * APK which is both JAR-signed and signed using APK Signature Scheme v2 contains an APK
-         * Signature Scheme v2 signature from this signer, but does not contain a JAR signature
-         * from this signer.
-         */
-        JAR_SIG_MISSING(
-                "No APK Signature Scheme v2 signature from this signer despite APK being v2"
-                        + " signed"),
-
-        /**
-         * APK which is both JAR-signed and signed using APK Signature Scheme v2 contains a JAR
-         * signature from this signer, but does not contain an APK Signature Scheme v2 signature
-         * from this signer.
-         */
-        V2_SIG_MISSING(
-                "No APK Signature Scheme v2 signature from this signer despite APK being v2"
-                        + " signed"),
-
-        /**
-         * Failed to parse the list of signers contained in the APK Signature Scheme v2 signature.
-         */
-        V2_SIG_MALFORMED_SIGNERS("Malformed list of signers"),
-
-        /**
-         * Failed to parse this signer's signer block contained in the APK Signature Scheme v2
-         * signature.
-         */
-        V2_SIG_MALFORMED_SIGNER("Malformed signer block"),
-
-        /**
-         * Public key embedded in the APK Signature Scheme v2 signature of this signer could not be
-         * parsed.
-         *
-         * <ul>
-         * <li>Parameter 1: error details ({@code Throwable})</li>
-         * </ul>
-         */
-        V2_SIG_MALFORMED_PUBLIC_KEY("Malformed public key: %1$s"),
-
-        /**
-         * This APK Signature Scheme v2 signer's certificate could not be parsed.
-         *
-         * <ul>
-         * <li>Parameter 1: index ({@code 0}-based) of the certificate in the signer's list of
-         *     certificates ({@code Integer})</li>
-         * <li>Parameter 2: sequence number ({@code 1}-based) of the certificate in the signer's
-         *     list of certificates ({@code Integer})</li>
-         * <li>Parameter 3: error details ({@code Throwable})</li>
-         * </ul>
-         */
-        V2_SIG_MALFORMED_CERTIFICATE("Malformed certificate #%2$d: %3$s"),
-
-        /**
-         * Failed to parse this signer's signature record contained in the APK Signature Scheme v2
-         * signature.
-         *
-         * <ul>
-         * <li>Parameter 1: record number (first record is {@code 1}) ({@code Integer})</li>
-         * </ul>
-         */
-        V2_SIG_MALFORMED_SIGNATURE("Malformed APK Signature Scheme v2 signature record #%1$d"),
-
-        /**
-         * Failed to parse this signer's digest record contained in the APK Signature Scheme v2
-         * signature.
-         *
-         * <ul>
-         * <li>Parameter 1: record number (first record is {@code 1}) ({@code Integer})</li>
-         * </ul>
-         */
-        V2_SIG_MALFORMED_DIGEST("Malformed APK Signature Scheme v2 digest record #%1$d"),
-
-        /**
-         * This APK Signature Scheme v2 signer contains a malformed additional attribute.
-         *
-         * <ul>
-         * <li>Parameter 1: attribute number (first attribute is {@code 1}) {@code Integer})</li>
-         * </ul>
-         */
-        V2_SIG_MALFORMED_ADDITIONAL_ATTRIBUTE("Malformed additional attribute #%1$d"),
-
-        /**
-         * APK Signature Scheme v2 signature contains no signers.
-         */
-        V2_SIG_NO_SIGNERS("No signers in APK Signature Scheme v2 signature"),
-
-        /**
-         * This APK Signature Scheme v2 signer contains a signature produced using an unknown
-         * algorithm.
-         *
-         * <ul>
-         * <li>Parameter 1: algorithm ID ({@code Integer})</li>
-         * </ul>
-         */
-        V2_SIG_UNKNOWN_SIG_ALGORITHM("Unknown signature algorithm: %1$#x"),
-
-        /**
-         * This APK Signature Scheme v2 signer contains an unknown additional attribute.
-         *
-         * <ul>
-         * <li>Parameter 1: attribute ID ({@code Integer})</li>
-         * </ul>
-         */
-        V2_SIG_UNKNOWN_ADDITIONAL_ATTRIBUTE("Unknown additional attribute: ID %1$#x"),
-
-        /**
-         * An exception was encountered while verifying APK Signature Scheme v2 signature of this
-         * signer.
-         *
-         * <ul>
-         * <li>Parameter 1: signature algorithm ({@link SignatureAlgorithm})</li>
-         * <li>Parameter 2: exception ({@code Throwable})</li>
-         * </ul>
-         */
-        V2_SIG_VERIFY_EXCEPTION("Failed to verify %1$s signature: %2$s"),
-
-        /**
-         * APK Signature Scheme v2 signature over this signer's signed-data block did not verify.
-         *
-         * <ul>
-         * <li>Parameter 1: signature algorithm ({@link SignatureAlgorithm})</li>
-         * </ul>
-         */
-        V2_SIG_DID_NOT_VERIFY("%1$s signature over signed-data did not verify"),
-
-        /**
-         * This APK Signature Scheme v2 signer offers no signatures.
-         */
-        V2_SIG_NO_SIGNATURES("No signatures"),
-
-        /**
-         * This APK Signature Scheme v2 signer offers signatures but none of them are supported.
-         */
-        V2_SIG_NO_SUPPORTED_SIGNATURES("No supported signatures"),
-
-        /**
-         * This APK Signature Scheme v2 signer offers no certificates.
-         */
-        V2_SIG_NO_CERTIFICATES("No certificates"),
-
-        /**
-         * This APK Signature Scheme v2 signer's public key listed in the signer's certificate does
-         * not match the public key listed in the signatures record.
-         *
-         * <ul>
-         * <li>Parameter 1: hex-encoded public key from certificate ({@code String})</li>
-         * <li>Parameter 2: hex-encoded public key from signatures record ({@code String})</li>
-         * </ul>
-         */
-        V2_SIG_PUBLIC_KEY_MISMATCH_BETWEEN_CERTIFICATE_AND_SIGNATURES_RECORD(
-                "Public key mismatch between certificate and signature record: <%1$s> vs <%2$s>"),
-
-        /**
-         * This APK Signature Scheme v2 signer's signature algorithms listed in the signatures
-         * record do not match the signature algorithms listed in the signatures record.
-         *
-         * <ul>
-         * <li>Parameter 1: signature algorithms from signatures record ({@code List<Integer>})</li>
-         * <li>Parameter 2: signature algorithms from digests record ({@code List<Integer>})</li>
-         * </ul>
-         */
-        V2_SIG_SIG_ALG_MISMATCH_BETWEEN_SIGNATURES_AND_DIGESTS_RECORDS(
-                "Signature algorithms mismatch between signatures and digests records"
-                        + ": %1$s vs %2$s"),
-
-        /**
-         * The APK's digest does not match the digest contained in the APK Signature Scheme v2
-         * signature.
-         *
-         * <ul>
-         * <li>Parameter 1: content digest algorithm ({@link ContentDigestAlgorithm})</li>
-         * <li>Parameter 2: hex-encoded expected digest of the APK ({@code String})</li>
-         * <li>Parameter 3: hex-encoded actual digest of the APK ({@code String})</li>
-         * </ul>
-         */
-        V2_SIG_APK_DIGEST_DID_NOT_VERIFY(
-                "APK integrity check failed. %1$s digest mismatch."
-                        + " Expected: <%2$s>, actual: <%3$s>"),
-
-        /**
-         * APK Signing Block contains an unknown entry.
-         *
-         * <ul>
-         * <li>Parameter 1: entry ID ({@code Integer})</li>
-         * </ul>
-         */
-        APK_SIG_BLOCK_UNKNOWN_ENTRY_ID("APK Signing Block contains unknown entry: ID %1$#x");
-
-        private final String mFormat;
-
-        private Issue(String format) {
-            mFormat = format;
-        }
-
-        /**
-         * Returns the format string suitable for combining the parameters of this issue into a
-         * readable string. See {@link java.util.Formatter} for format.
-         */
-        private String getFormat() {
-            return mFormat;
-        }
-    }
-
-    /**
-     * {@link Issue} with associated parameters. {@link #toString()} produces a readable formatted
-     * form.
-     */
-    public static class IssueWithParams {
-        private final Issue mIssue;
-        private final Object[] mParams;
-
-        /**
-         * Constructs a new {@code IssueWithParams} of the specified type and with provided
-         * parameters.
-         */
-        public IssueWithParams(Issue issue, Object[] params) {
-            mIssue = issue;
-            mParams = params;
-        }
-
-        /**
-         * Returns the type of this issue.
-         */
-        public Issue getIssue() {
-            return mIssue;
-        }
-
-        /**
-         * Returns the parameters of this issue.
-         */
-        public Object[] getParams() {
-            return mParams.clone();
-        }
-
-        /**
-         * Returns a readable form of this issue.
-         */
-        @Override
-        public String toString() {
-            return String.format(mIssue.getFormat(), mParams);
-        }
-    }
-
-    /**
-     * Wrapped around {@code byte[]} which ensures that {@code equals} and {@code hashCode} operate
-     * on the contents of the arrays rather than on references.
-     */
-    private static class ByteArray {
-        private final byte[] mArray;
-        private final int mHashCode;
-
-        private ByteArray(byte[] arr) {
-            mArray = arr;
-            mHashCode = Arrays.hashCode(mArray);
-        }
-
-        @Override
-        public int hashCode() {
-            return mHashCode;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj == null) {
-                return false;
-            }
-            if (getClass() != obj.getClass()) {
-                return false;
-            }
-            ByteArray other = (ByteArray) obj;
-            if (hashCode() != other.hashCode()) {
-                return false;
-            }
-            if (!Arrays.equals(mArray, other.mArray)) {
-                return false;
-            }
-            return true;
-        }
-    }
-
-    /**
-     * Builder of {@link ApkVerifier} instances.
-     *
-     * <p>Although not required, it is best to provide the SDK version (API Level) of the oldest
-     * Android platform on which the APK is supposed to be installed -- see
-     * {@link #setMinCheckedPlatformVersion(int)}. Without this information, APKs which use security
-     * features not supported on ancient Android platforms (e.g., SHA-256 digests or ECDSA
-     * signatures) will not verify.
-     */
-    public static class Builder {
-        private final File mApkFile;
-        private final DataSource mApkDataSource;
-
-        private int mMinSdkVersion = 1;
-        private int mMaxSdkVersion = Integer.MAX_VALUE;
-
-        /**
-         * Constructs a new {@code Builder} for verifying the provided APK file.
-         */
-        public Builder(File apk) {
-            if (apk == null) {
-                throw new NullPointerException("apk == null");
-            }
-            mApkFile = apk;
-            mApkDataSource = null;
-        }
-
-        /**
-         * Constructs a new {@code Builder} for verifying the provided APK.
-         */
-        public Builder(DataSource apk) {
-            if (apk == null) {
-                throw new NullPointerException("apk == null");
-            }
-            mApkDataSource = apk;
-            mApkFile = null;
-        }
-
-        /**
-         * Sets the oldest Android platform version for which the APK is verified. APK verification
-         * will confirm that the APK is expected to install successfully on all known Android
-         * platforms starting from the platform version with the provided API Level.
-         *
-         * <p>By default, the APK is checked for all platform versions. Thus, APKs which use
-         * security features not supported on ancient Android platforms (e.g., SHA-256 digests or
-         * ECDSA signatures) will not verify by default.
-         *
-         * @param minSdkVersion API Level of the oldest platform for which to verify the APK
-         *
-         * @see #setCheckedPlatformVersions(int, int)
-         */
-        public Builder setMinCheckedPlatformVersion(int minSdkVersion) {
-            mMinSdkVersion = minSdkVersion;
-            mMaxSdkVersion = Integer.MAX_VALUE;
-            return this;
-        }
-
-        /**
-         * Sets the range of Android platform versions for which the APK is verified. APK
-         * verification will confirm that the APK is expected to install successfully on Android
-         * platforms whose API Levels fall into this inclusive range.
-         *
-         * <p>By default, the APK is checked for all platform versions. Thus, APKs which use
-         * security features not supported on ancient Android platforms (e.g., SHA-256 digests or
-         * ECDSA signatures) will not verify by default.
-         *
-         * @param minSdkVersion API Level of the oldest platform for which to verify the APK
-         * @param maxSdkVersion API Level of the newest platform for which to verify the APK
-         *
-         * @see #setMinCheckedPlatformVersion(int)
-         */
-        public Builder setCheckedPlatformVersions(int minSdkVersion, int maxSdkVersion) {
-            mMinSdkVersion = minSdkVersion;
-            mMaxSdkVersion = maxSdkVersion;
-            return this;
-        }
-
-        /**
-         * Returns an {@link ApkVerifier} initialized according to the configuration of this
-         * builder.
-         */
-        public ApkVerifier build() {
-            return new ApkVerifier(
-                    mApkFile,
-                    mApkDataSource,
-                    mMinSdkVersion,
-                    mMaxSdkVersion);
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java b/tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java
deleted file mode 100644
index 75b0b20..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java
+++ /dev/null
@@ -1,900 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core;
-
-import com.android.apksigner.core.internal.apk.v1.DigestAlgorithm;
-import com.android.apksigner.core.internal.apk.v1.V1SchemeSigner;
-import com.android.apksigner.core.internal.apk.v2.V2SchemeSigner;
-import com.android.apksigner.core.internal.util.MessageDigestSink;
-import com.android.apksigner.core.internal.util.Pair;
-import com.android.apksigner.core.util.DataSink;
-import com.android.apksigner.core.util.DataSinks;
-import com.android.apksigner.core.util.DataSource;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.security.InvalidKeyException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SignatureException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Default implementation of {@link ApkSignerEngine}.
- *
- * <p>Use {@link Builder} to obtain instances of this engine.
- */
-public class DefaultApkSignerEngine implements ApkSignerEngine {
-
-    // IMPLEMENTATION NOTE: This engine generates a signed APK as follows:
-    // 1. The engine asks its client to output input JAR entries which are not part of JAR
-    //    signature.
-    // 2. If JAR signing (v1 signing) is enabled, the engine inspects the output JAR entries to
-    //    compute their digests, to be placed into output META-INF/MANIFEST.MF. It also inspects
-    //    the contents of input and output META-INF/MANIFEST.MF to borrow the main section of the
-    //    file. It does not care about individual (i.e., JAR entry-specific) sections. It then
-    //    emits the v1 signature (a set of JAR entries) and asks the client to output them.
-    // 3. If APK Signature Scheme v2 (v2 signing) is enabled, the engine emits an APK Signing Block
-    //    from outputZipSections() and asks its client to insert this block into the output.
-
-    private final boolean mV1SigningEnabled;
-    private final boolean mV2SigningEnabled;
-    private final boolean mOtherSignersSignaturesPreserved;
-    private final List<V1SchemeSigner.SignerConfig> mV1SignerConfigs;
-    private final DigestAlgorithm mV1ContentDigestAlgorithm;
-    private final List<V2SchemeSigner.SignerConfig> mV2SignerConfigs;
-
-    private boolean mClosed;
-
-    private boolean mV1SignaturePending;
-
-    /**
-     * Names of JAR entries which this engine is expected to output as part of v1 signing.
-     */
-    private final Set<String> mSignatureExpectedOutputJarEntryNames;
-
-    /** Requests for digests of output JAR entries. */
-    private final Map<String, GetJarEntryDataDigestRequest> mOutputJarEntryDigestRequests =
-            new HashMap<>();
-
-    /** Digests of output JAR entries. */
-    private final Map<String, byte[]> mOutputJarEntryDigests = new HashMap<>();
-
-    /** Data of JAR entries emitted by this engine as v1 signature. */
-    private final Map<String, byte[]> mEmittedSignatureJarEntryData = new HashMap<>();
-
-    /** Requests for data of output JAR entries which comprise the v1 signature. */
-    private final Map<String, GetJarEntryDataRequest> mOutputSignatureJarEntryDataRequests =
-            new HashMap<>();
-    /**
-     * Request to obtain the data of MANIFEST.MF or {@code null} if the request hasn't been issued.
-     */
-    private GetJarEntryDataRequest mInputJarManifestEntryDataRequest;
-
-    /**
-     * Request to output the emitted v1 signature or {@code null} if the request hasn't been issued.
-     */
-    private OutputJarSignatureRequestImpl mAddV1SignatureRequest;
-
-    private boolean mV2SignaturePending;
-
-    /**
-     * Request to output the emitted v2 signature or {@code null} if the request hasn't been issued.
-     */
-    private OutputApkSigningBlockRequestImpl mAddV2SignatureRequest;
-
-    private DefaultApkSignerEngine(
-            List<SignerConfig> signerConfigs,
-            int minSdkVersion,
-            boolean v1SigningEnabled,
-            boolean v2SigningEnabled,
-            boolean otherSignersSignaturesPreserved) throws InvalidKeyException {
-        if (signerConfigs.isEmpty()) {
-            throw new IllegalArgumentException("At least one signer config must be provided");
-        }
-        if (otherSignersSignaturesPreserved) {
-            throw new UnsupportedOperationException(
-                    "Preserving other signer's signatures is not yet implemented");
-        }
-
-        mV1SigningEnabled = v1SigningEnabled;
-        mV2SigningEnabled = v2SigningEnabled;
-        mOtherSignersSignaturesPreserved = otherSignersSignaturesPreserved;
-        mV1SignerConfigs =
-                (v1SigningEnabled)
-                        ? new ArrayList<>(signerConfigs.size()) : Collections.emptyList();
-        mV2SignerConfigs =
-                (v2SigningEnabled)
-                        ? new ArrayList<>(signerConfigs.size()) : Collections.emptyList();
-        mV1ContentDigestAlgorithm =
-                (v1SigningEnabled)
-                        ? V1SchemeSigner.getSuggestedContentDigestAlgorithm(minSdkVersion) : null;
-        for (SignerConfig signerConfig : signerConfigs) {
-            List<X509Certificate> certificates = signerConfig.getCertificates();
-            PublicKey publicKey = certificates.get(0).getPublicKey();
-
-            if (v1SigningEnabled) {
-                DigestAlgorithm v1SignatureDigestAlgorithm =
-                        V1SchemeSigner.getSuggestedSignatureDigestAlgorithm(
-                                publicKey, minSdkVersion);
-                V1SchemeSigner.SignerConfig v1SignerConfig = new V1SchemeSigner.SignerConfig();
-                v1SignerConfig.name = signerConfig.getName();
-                v1SignerConfig.privateKey = signerConfig.getPrivateKey();
-                v1SignerConfig.certificates = certificates;
-                v1SignerConfig.contentDigestAlgorithm = mV1ContentDigestAlgorithm;
-                v1SignerConfig.signatureDigestAlgorithm = v1SignatureDigestAlgorithm;
-                mV1SignerConfigs.add(v1SignerConfig);
-            }
-
-            if (v2SigningEnabled) {
-                V2SchemeSigner.SignerConfig v2SignerConfig = new V2SchemeSigner.SignerConfig();
-                v2SignerConfig.privateKey = signerConfig.getPrivateKey();
-                v2SignerConfig.certificates = certificates;
-                v2SignerConfig.signatureAlgorithms =
-                        V2SchemeSigner.getSuggestedSignatureAlgorithms(publicKey, minSdkVersion);
-                mV2SignerConfigs.add(v2SignerConfig);
-            }
-        }
-        mSignatureExpectedOutputJarEntryNames =
-                (v1SigningEnabled)
-                        ? V1SchemeSigner.getOutputEntryNames(mV1SignerConfigs)
-                        : Collections.emptySet();
-    }
-
-    @Override
-    public void inputApkSigningBlock(DataSource apkSigningBlock) {
-        checkNotClosed();
-
-        if ((apkSigningBlock == null) || (apkSigningBlock.size() == 0)) {
-            return;
-        }
-
-        if (mOtherSignersSignaturesPreserved) {
-            // TODO: Preserve blocks other than APK Signature Scheme v2 blocks of signers configured
-            // in this engine.
-            return;
-        }
-        // TODO: Preserve blocks other than APK Signature Scheme v2 blocks.
-    }
-
-    @Override
-    public InputJarEntryInstructions inputJarEntry(String entryName) {
-        checkNotClosed();
-
-        InputJarEntryInstructions.OutputPolicy outputPolicy =
-                getInputJarEntryOutputPolicy(entryName);
-        switch (outputPolicy) {
-            case SKIP:
-                return new InputJarEntryInstructions(InputJarEntryInstructions.OutputPolicy.SKIP);
-            case OUTPUT:
-                return new InputJarEntryInstructions(InputJarEntryInstructions.OutputPolicy.OUTPUT);
-            case OUTPUT_BY_ENGINE:
-                if (V1SchemeSigner.MANIFEST_ENTRY_NAME.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.
-                    mInputJarManifestEntryDataRequest = new GetJarEntryDataRequest(entryName);
-                    return new InputJarEntryInstructions(
-                            InputJarEntryInstructions.OutputPolicy.OUTPUT_BY_ENGINE,
-                            mInputJarManifestEntryDataRequest);
-                }
-                return new InputJarEntryInstructions(
-                        InputJarEntryInstructions.OutputPolicy.OUTPUT_BY_ENGINE);
-            default:
-                throw new RuntimeException("Unsupported output policy: " + outputPolicy);
-        }
-    }
-
-    @Override
-    public InspectJarEntryRequest outputJarEntry(String entryName) {
-        checkNotClosed();
-        invalidateV2Signature();
-        if (!mV1SigningEnabled) {
-            // 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();
-            GetJarEntryDataDigestRequest dataDigestRequest =
-                    new GetJarEntryDataDigestRequest(
-                            entryName,
-                            V1SchemeSigner.getJcaMessageDigestAlgorithm(mV1ContentDigestAlgorithm));
-            mOutputJarEntryDigestRequests.put(entryName, dataDigestRequest);
-            mOutputJarEntryDigests.remove(entryName);
-            return dataDigestRequest;
-        }
-
-        if (mSignatureExpectedOutputJarEntryNames.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.MANIFEST_ENTRY_NAME.equals(entryName)) {
-                dataRequest = new GetJarEntryDataRequest(entryName);
-                mInputJarManifestEntryDataRequest = 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 =
-                        (mEmittedSignatureJarEntryData.containsKey(entryName))
-                                ? new GetJarEntryDataRequest(entryName) : null;
-            }
-
-            if (dataRequest != null) {
-                mOutputSignatureJarEntryDataRequests.put(entryName, dataRequest);
-            }
-            return dataRequest;
-        }
-
-        // This entry is not covered by v1 signature and isn't part of v1 signature.
-        return null;
-    }
-
-    @Override
-    public InputJarEntryInstructions.OutputPolicy inputJarEntryRemoved(String entryName) {
-        checkNotClosed();
-        return getInputJarEntryOutputPolicy(entryName);
-    }
-
-    @Override
-    public void outputJarEntryRemoved(String entryName) {
-        checkNotClosed();
-        invalidateV2Signature();
-        if (!mV1SigningEnabled) {
-            return;
-        }
-
-        if (V1SchemeSigner.isJarEntryDigestNeededInManifest(entryName)) {
-            // This entry is covered by v1 signature.
-            invalidateV1Signature();
-            mOutputJarEntryDigests.remove(entryName);
-            mOutputJarEntryDigestRequests.remove(entryName);
-            mOutputSignatureJarEntryDataRequests.remove(entryName);
-            return;
-        }
-
-        if (mSignatureExpectedOutputJarEntryNames.contains(entryName)) {
-            // This entry is part of the v1 signature generated by this engine.
-            invalidateV1Signature();
-            return;
-        }
-    }
-
-    @Override
-    public OutputJarSignatureRequest outputJarEntries()
-            throws InvalidKeyException, SignatureException, NoSuchAlgorithmException {
-        checkNotClosed();
-
-        if (!mV1SignaturePending) {
-            return null;
-        }
-
-        if ((mInputJarManifestEntryDataRequest != null)
-                && (!mInputJarManifestEntryDataRequest.isDone())) {
-            throw new IllegalStateException(
-                    "Still waiting to inspect input APK's "
-                            + mInputJarManifestEntryDataRequest.getEntryName());
-        }
-
-        for (GetJarEntryDataDigestRequest digestRequest
-                : mOutputJarEntryDigestRequests.values()) {
-            String entryName = digestRequest.getEntryName();
-            if (!digestRequest.isDone()) {
-                throw new IllegalStateException(
-                        "Still waiting to inspect output APK's " + entryName);
-            }
-            mOutputJarEntryDigests.put(entryName, digestRequest.getDigest());
-        }
-        mOutputJarEntryDigestRequests.clear();
-
-        for (GetJarEntryDataRequest dataRequest : mOutputSignatureJarEntryDataRequests.values()) {
-            if (!dataRequest.isDone()) {
-                throw new IllegalStateException(
-                        "Still waiting to inspect output APK's " + dataRequest.getEntryName());
-            }
-        }
-
-        List<Integer> apkSigningSchemeIds =
-                (mV2SigningEnabled) ? Collections.singletonList(2) : Collections.emptyList();
-        byte[] inputJarManifest =
-                (mInputJarManifestEntryDataRequest != null)
-                    ? mInputJarManifestEntryDataRequest.getData() : null;
-
-        // Check whether the most recently used signature (if present) is still fine.
-        List<Pair<String, byte[]>> signatureZipEntries;
-        if ((mAddV1SignatureRequest == null) || (!mAddV1SignatureRequest.isDone())) {
-            try {
-                signatureZipEntries =
-                        V1SchemeSigner.sign(
-                                mV1SignerConfigs,
-                                mV1ContentDigestAlgorithm,
-                                mOutputJarEntryDigests,
-                                apkSigningSchemeIds,
-                                inputJarManifest);
-            } catch (CertificateException e) {
-                throw new SignatureException("Failed to generate v1 signature", e);
-            }
-        } else {
-            V1SchemeSigner.OutputManifestFile newManifest =
-                    V1SchemeSigner.generateManifestFile(
-                            mV1ContentDigestAlgorithm, mOutputJarEntryDigests, inputJarManifest);
-            byte[] emittedSignatureManifest =
-                    mEmittedSignatureJarEntryData.get(V1SchemeSigner.MANIFEST_ENTRY_NAME);
-            if (!Arrays.equals(newManifest.contents, emittedSignatureManifest)) {
-                // Emitted v1 signature is no longer valid.
-                try {
-                    signatureZipEntries =
-                            V1SchemeSigner.signManifest(
-                                    mV1SignerConfigs,
-                                    mV1ContentDigestAlgorithm,
-                                    apkSigningSchemeIds,
-                                    newManifest);
-                } catch (CertificateException e) {
-                    throw new SignatureException("Failed to generate v1 signature", e);
-                }
-            } else {
-                // Emitted v1 signature is still valid. Check whether the signature is there in the
-                // output.
-                signatureZipEntries = new ArrayList<>();
-                for (Map.Entry<String, byte[]> expectedOutputEntry
-                        : mEmittedSignatureJarEntryData.entrySet()) {
-                    String entryName = expectedOutputEntry.getKey();
-                    byte[] expectedData = expectedOutputEntry.getValue();
-                    GetJarEntryDataRequest actualDataRequest =
-                            mOutputSignatureJarEntryDataRequests.get(entryName);
-                    if (actualDataRequest == null) {
-                        // This signature entry hasn't been output.
-                        signatureZipEntries.add(Pair.of(entryName, expectedData));
-                        continue;
-                    }
-                    byte[] actualData = actualDataRequest.getData();
-                    if (!Arrays.equals(expectedData, actualData)) {
-                        signatureZipEntries.add(Pair.of(entryName, expectedData));
-                    }
-                }
-                if (signatureZipEntries.isEmpty()) {
-                    // v1 signature in the output is valid
-                    return null;
-                }
-                // v1 signature in the output is not valid.
-            }
-        }
-
-        if (signatureZipEntries.isEmpty()) {
-            // v1 signature in the output is valid
-            mV1SignaturePending = false;
-            return null;
-        }
-
-        List<OutputJarSignatureRequest.JarEntry> sigEntries =
-                new ArrayList<>(signatureZipEntries.size());
-        for (Pair<String, byte[]> entry : signatureZipEntries) {
-            String entryName = entry.getFirst();
-            byte[] entryData = entry.getSecond();
-            sigEntries.add(new OutputJarSignatureRequest.JarEntry(entryName, entryData));
-            mEmittedSignatureJarEntryData.put(entryName, entryData);
-        }
-        mAddV1SignatureRequest = new OutputJarSignatureRequestImpl(sigEntries);
-        return mAddV1SignatureRequest;
-    }
-
-    @Override
-    public OutputApkSigningBlockRequest outputZipSections(
-            DataSource zipEntries,
-            DataSource zipCentralDirectory,
-            DataSource zipEocd)
-                    throws IOException, InvalidKeyException, SignatureException,
-                            NoSuchAlgorithmException {
-        checkNotClosed();
-        checkV1SigningDoneIfEnabled();
-        if (!mV2SigningEnabled) {
-            return null;
-        }
-        invalidateV2Signature();
-
-        byte[] apkSigningBlock =
-                V2SchemeSigner.generateApkSigningBlock(
-                        zipEntries, zipCentralDirectory, zipEocd, mV2SignerConfigs);
-
-        mAddV2SignatureRequest = new OutputApkSigningBlockRequestImpl(apkSigningBlock);
-        return mAddV2SignatureRequest;
-    }
-
-    @Override
-    public void outputDone() {
-        checkNotClosed();
-        checkV1SigningDoneIfEnabled();
-        checkV2SigningDoneIfEnabled();
-    }
-
-    @Override
-    public void close() {
-        mClosed = true;
-
-        mAddV1SignatureRequest = null;
-        mInputJarManifestEntryDataRequest = null;
-        mOutputJarEntryDigestRequests.clear();
-        mOutputJarEntryDigests.clear();
-        mEmittedSignatureJarEntryData.clear();
-        mOutputSignatureJarEntryDataRequests.clear();
-
-        mAddV2SignatureRequest = null;
-    }
-
-    private void invalidateV1Signature() {
-        if (mV1SigningEnabled) {
-            mV1SignaturePending = true;
-        }
-        invalidateV2Signature();
-    }
-
-    private void invalidateV2Signature() {
-        if (mV2SigningEnabled) {
-            mV2SignaturePending = true;
-            mAddV2SignatureRequest = null;
-        }
-    }
-
-    private void checkNotClosed() {
-        if (mClosed) {
-            throw new IllegalStateException("Engine closed");
-        }
-    }
-
-    private void checkV1SigningDoneIfEnabled() {
-        if (!mV1SignaturePending) {
-            return;
-        }
-
-        if (mAddV1SignatureRequest == null) {
-            throw new IllegalStateException(
-                    "v1 signature (JAR signature) not yet generated. Skipped outputJarEntries()?");
-        }
-        if (!mAddV1SignatureRequest.isDone()) {
-            throw new IllegalStateException(
-                    "v1 signature (JAR signature) addition requested by outputJarEntries() hasn't"
-                            + " been fulfilled");
-        }
-        for (Map.Entry<String, byte[]> expectedOutputEntry
-                : mEmittedSignatureJarEntryData.entrySet()) {
-            String entryName = expectedOutputEntry.getKey();
-            byte[] expectedData = expectedOutputEntry.getValue();
-            GetJarEntryDataRequest actualDataRequest =
-                    mOutputSignatureJarEntryDataRequests.get(entryName);
-            if (actualDataRequest == null) {
-                throw new IllegalStateException(
-                        "APK entry " + entryName + " not yet output despite this having been"
-                                + " requested");
-            } else if (!actualDataRequest.isDone()) {
-                throw new IllegalStateException(
-                        "Still waiting to inspect output APK's " + entryName);
-            }
-            byte[] actualData = actualDataRequest.getData();
-            if (!Arrays.equals(expectedData, actualData)) {
-                throw new IllegalStateException(
-                        "Output APK entry " + entryName + " data differs from what was requested");
-            }
-        }
-        mV1SignaturePending = false;
-    }
-
-    private void checkV2SigningDoneIfEnabled() {
-        if (!mV2SignaturePending) {
-            return;
-        }
-        if (mAddV2SignatureRequest == null) {
-            throw new IllegalStateException(
-                    "v2 signature (APK Signature Scheme v2 signature) not yet generated."
-                            + " Skipped outputZipSections()?");
-        }
-        if (!mAddV2SignatureRequest.isDone()) {
-            throw new IllegalStateException(
-                    "v2 signature (APK Signature Scheme v2 signature) addition requested by"
-                            + " outputZipSections() hasn't been fulfilled yet");
-        }
-        mAddV2SignatureRequest = null;
-        mV2SignaturePending = false;
-    }
-
-    /**
-     * Returns the output policy for the provided input JAR entry.
-     */
-    private InputJarEntryInstructions.OutputPolicy getInputJarEntryOutputPolicy(String entryName) {
-        if (mSignatureExpectedOutputJarEntryNames.contains(entryName)) {
-            return InputJarEntryInstructions.OutputPolicy.OUTPUT_BY_ENGINE;
-        }
-        if ((mOtherSignersSignaturesPreserved)
-                || (V1SchemeSigner.isJarEntryDigestNeededInManifest(entryName))) {
-            return InputJarEntryInstructions.OutputPolicy.OUTPUT;
-        }
-        return InputJarEntryInstructions.OutputPolicy.SKIP;
-    }
-
-    private static class OutputJarSignatureRequestImpl implements OutputJarSignatureRequest {
-        private final List<JarEntry> mAdditionalJarEntries;
-        private volatile boolean mDone;
-
-        private OutputJarSignatureRequestImpl(List<JarEntry> additionalZipEntries) {
-            mAdditionalJarEntries =
-                    Collections.unmodifiableList(new ArrayList<>(additionalZipEntries));
-        }
-
-        @Override
-        public List<JarEntry> getAdditionalJarEntries() {
-            return mAdditionalJarEntries;
-        }
-
-        @Override
-        public void done() {
-            mDone = true;
-        }
-
-        private boolean isDone() {
-            return mDone;
-        }
-    }
-
-    private static class OutputApkSigningBlockRequestImpl implements OutputApkSigningBlockRequest {
-        private final byte[] mApkSigningBlock;
-        private volatile boolean mDone;
-
-        private OutputApkSigningBlockRequestImpl(byte[] apkSigingBlock) {
-            mApkSigningBlock = apkSigingBlock.clone();
-        }
-
-        @Override
-        public byte[] getApkSigningBlock() {
-            return mApkSigningBlock.clone();
-        }
-
-        @Override
-        public void done() {
-            mDone = true;
-        }
-
-        private boolean isDone() {
-            return mDone;
-        }
-    }
-
-    /**
-     * JAR entry inspection request which obtain the entry's uncompressed data.
-     */
-    private static class GetJarEntryDataRequest implements InspectJarEntryRequest {
-        private final String mEntryName;
-        private final Object mLock = new Object();
-
-        private boolean mDone;
-        private DataSink mDataSink;
-        private ByteArrayOutputStream mDataSinkBuf;
-
-        private GetJarEntryDataRequest(String entryName) {
-            mEntryName = entryName;
-        }
-
-        @Override
-        public String getEntryName() {
-            return mEntryName;
-        }
-
-        @Override
-        public DataSink getDataSink() {
-            synchronized (mLock) {
-                checkNotDone();
-                if (mDataSinkBuf == null) {
-                    mDataSinkBuf = new ByteArrayOutputStream();
-                }
-                if (mDataSink == null) {
-                    mDataSink = DataSinks.asDataSink(mDataSinkBuf);
-                }
-                return mDataSink;
-            }
-        }
-
-        @Override
-        public void done() {
-            synchronized (mLock) {
-                if (mDone) {
-                    return;
-                }
-                mDone = true;
-            }
-        }
-
-        private boolean isDone() {
-            synchronized (mLock) {
-                return mDone;
-            }
-        }
-
-        private void checkNotDone() throws IllegalStateException {
-            synchronized (mLock) {
-                if (mDone) {
-                    throw new IllegalStateException("Already done");
-                }
-            }
-        }
-
-        private byte[] getData() {
-            synchronized (mLock) {
-                if (!mDone) {
-                    throw new IllegalStateException("Not yet done");
-                }
-                return (mDataSinkBuf != null) ? mDataSinkBuf.toByteArray() : new byte[0];
-            }
-        }
-    }
-
-    /**
-     * JAR entry inspection request which obtains the digest of the entry's uncompressed data.
-     */
-    private static class GetJarEntryDataDigestRequest implements InspectJarEntryRequest {
-        private final String mEntryName;
-        private final String mJcaDigestAlgorithm;
-        private final Object mLock = new Object();
-
-        private boolean mDone;
-        private DataSink mDataSink;
-        private MessageDigest mMessageDigest;
-        private byte[] mDigest;
-
-        private GetJarEntryDataDigestRequest(String entryName, String jcaDigestAlgorithm) {
-            mEntryName = entryName;
-            mJcaDigestAlgorithm = jcaDigestAlgorithm;
-        }
-
-        @Override
-        public String getEntryName() {
-            return mEntryName;
-        }
-
-        @Override
-        public DataSink getDataSink() {
-            synchronized (mLock) {
-                checkNotDone();
-                if (mDataSink == null) {
-                    mDataSink = new MessageDigestSink(new MessageDigest[] {getMessageDigest()});
-                }
-                return mDataSink;
-            }
-        }
-
-        private MessageDigest getMessageDigest() {
-            synchronized (mLock) {
-                if (mMessageDigest == null) {
-                    try {
-                        mMessageDigest = MessageDigest.getInstance(mJcaDigestAlgorithm);
-                    } catch (NoSuchAlgorithmException e) {
-                        throw new RuntimeException(
-                                mJcaDigestAlgorithm + " MessageDigest not available", e);
-                    }
-                }
-                return mMessageDigest;
-            }
-        }
-
-        @Override
-        public void done() {
-            synchronized (mLock) {
-                if (mDone) {
-                    return;
-                }
-                mDone = true;
-                mDigest = getMessageDigest().digest();
-                mMessageDigest = null;
-                mDataSink = null;
-            }
-        }
-
-        private boolean isDone() {
-            synchronized (mLock) {
-                return mDone;
-            }
-        }
-
-        private void checkNotDone() throws IllegalStateException {
-            synchronized (mLock) {
-                if (mDone) {
-                    throw new IllegalStateException("Already done");
-                }
-            }
-        }
-
-        private byte[] getDigest() {
-            synchronized (mLock) {
-                if (!mDone) {
-                    throw new IllegalStateException("Not yet done");
-                }
-                return mDigest.clone();
-            }
-        }
-    }
-
-    /**
-     * Configuration of a signer.
-     *
-     * <p>Use {@link Builder} to obtain configuration instances.
-     */
-    public static class SignerConfig {
-        private final String mName;
-        private final PrivateKey mPrivateKey;
-        private final List<X509Certificate> mCertificates;
-
-        private SignerConfig(
-                String name,
-                PrivateKey privateKey,
-                List<X509Certificate> certificates) {
-            mName = name;
-            mPrivateKey = privateKey;
-            mCertificates = Collections.unmodifiableList(new ArrayList<>(certificates));
-        }
-
-        /**
-         * Returns the name of this signer.
-         */
-        public String getName() {
-            return mName;
-        }
-
-        /**
-         * Returns the signing key of this signer.
-         */
-        public PrivateKey getPrivateKey() {
-            return mPrivateKey;
-        }
-
-        /**
-         * Returns the certificate(s) of this signer. The first certificate's public key corresponds
-         * to this signer's private key.
-         */
-        public List<X509Certificate> getCertificates() {
-            return mCertificates;
-        }
-
-        /**
-         * Builder of {@link SignerConfig} instances.
-         */
-        public static class Builder {
-            private final String mName;
-            private final PrivateKey mPrivateKey;
-            private final List<X509Certificate> mCertificates;
-
-            /**
-             * Constructs a new {@code Builder}.
-             *
-             * @param name signer's name. The name is reflected in the name of files comprising the
-             *        JAR signature of the APK.
-             * @param privateKey signing key
-             * @param certificates list of one or more X.509 certificates. The subject public key of
-             *        the first certificate must correspond to the {@code privateKey}.
-             */
-            public Builder(
-                    String name,
-                    PrivateKey privateKey,
-                    List<X509Certificate> certificates) {
-                mName = name;
-                mPrivateKey = privateKey;
-                mCertificates = new ArrayList<>(certificates);
-            }
-
-            /**
-             * Returns a new {@code SignerConfig} instance configured based on the configuration of
-             * this builder.
-             */
-            public SignerConfig build() {
-                return new SignerConfig(
-                        mName,
-                        mPrivateKey,
-                        mCertificates);
-            }
-        }
-    }
-
-    /**
-     * Builder of {@link DefaultApkSignerEngine} instances.
-     */
-    public static class Builder {
-        private final List<SignerConfig> mSignerConfigs;
-        private final int mMinSdkVersion;
-
-        private boolean mV1SigningEnabled = true;
-        private boolean mV2SigningEnabled = true;
-        private boolean mOtherSignersSignaturesPreserved;
-
-        /**
-         * Constructs a new {@code Builder}.
-         *
-         * @param signerConfigs information about signers with which the APK will be signed. At
-         *        least one signer configuration must be provided.
-         * @param minSdkVersion API Level of the oldest Android platform on which the APK is
-         *        supposed to be installed. See {@code minSdkVersion} attribute in the APK's
-         *        {@code AndroidManifest.xml}. The higher the version, the stronger signing features
-         *        will be enabled.
-         */
-        public Builder(
-                List<SignerConfig> signerConfigs,
-                int minSdkVersion) {
-            if (signerConfigs.isEmpty()) {
-                throw new IllegalArgumentException("At least one signer config must be provided");
-            }
-            mSignerConfigs = new ArrayList<>(signerConfigs);
-            mMinSdkVersion = minSdkVersion;
-        }
-
-        /**
-         * Returns a new {@code DefaultApkSignerEngine} instance configured based on the
-         * configuration of this builder.
-         */
-        public DefaultApkSignerEngine build() throws InvalidKeyException {
-            return new DefaultApkSignerEngine(
-                    mSignerConfigs,
-                    mMinSdkVersion,
-                    mV1SigningEnabled,
-                    mV2SigningEnabled,
-                    mOtherSignersSignaturesPreserved);
-        }
-
-        /**
-         * Sets whether the APK should be signed using JAR signing (aka v1 signature scheme).
-         *
-         * <p>By default, the APK will be signed using this scheme.
-         */
-        public Builder setV1SigningEnabled(boolean enabled) {
-            mV1SigningEnabled = enabled;
-            return this;
-        }
-
-        /**
-         * Sets whether the APK should be signed using APK Signature Scheme v2 (aka v2 signature
-         * scheme).
-         *
-         * <p>By default, the APK will be signed using this scheme.
-         */
-        public Builder setV2SigningEnabled(boolean enabled) {
-            mV2SigningEnabled = enabled;
-            return this;
-        }
-
-        /**
-         * Sets whether signatures produced by signers other than the ones configured in this engine
-         * should be copied from the input APK to the output APK.
-         *
-         * <p>By default, signatures of other signers are omitted from the output APK.
-         */
-        public Builder setOtherSignersSignaturesPreserved(boolean preserved) {
-            mOtherSignersSignaturesPreserved = preserved;
-            return this;
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/apk/ApkUtils.java b/tools/apksigner/core/src/com/android/apksigner/core/apk/ApkUtils.java
deleted file mode 100644
index 8cc8c90..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/apk/ApkUtils.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.apk;
-
-import com.android.apksigner.core.internal.util.Pair;
-import com.android.apksigner.core.internal.zip.ZipUtils;
-import com.android.apksigner.core.util.DataSource;
-import com.android.apksigner.core.zip.ZipFormatException;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * APK utilities.
- */
-public class ApkUtils {
-
-    private ApkUtils() {}
-
-    /**
-     * Finds the main ZIP sections of the provided APK.
-     *
-     * @throws IOException if an I/O error occurred while reading the APK
-     * @throws ZipFormatException if the APK is malformed
-     */
-    public static ZipSections findZipSections(DataSource apk)
-            throws IOException, ZipFormatException {
-        Pair<ByteBuffer, Long> eocdAndOffsetInFile =
-                ZipUtils.findZipEndOfCentralDirectoryRecord(apk);
-        if (eocdAndOffsetInFile == null) {
-            throw new ZipFormatException("ZIP End of Central Directory record not found");
-        }
-
-        ByteBuffer eocdBuf = eocdAndOffsetInFile.getFirst();
-        long eocdOffset = eocdAndOffsetInFile.getSecond();
-        if (ZipUtils.isZip64EndOfCentralDirectoryLocatorPresent(apk, eocdOffset)) {
-            throw new ZipFormatException("ZIP64 APK not supported");
-        }
-        eocdBuf.order(ByteOrder.LITTLE_ENDIAN);
-        long cdStartOffset = ZipUtils.getZipEocdCentralDirectoryOffset(eocdBuf);
-        if (cdStartOffset >= eocdOffset) {
-            throw new ZipFormatException(
-                    "ZIP Central Directory start offset out of range: " + cdStartOffset
-                        + ". ZIP End of Central Directory offset: " + eocdOffset);
-        }
-
-        long cdSizeBytes = ZipUtils.getZipEocdCentralDirectorySizeBytes(eocdBuf);
-        long cdEndOffset = cdStartOffset + cdSizeBytes;
-        if (cdEndOffset > eocdOffset) {
-            throw new ZipFormatException(
-                    "ZIP Central Directory overlaps with End of Central Directory"
-                            + ". CD end: " + cdEndOffset
-                            + ", EoCD start: " + eocdOffset);
-        }
-
-        int cdRecordCount = ZipUtils.getZipEocdCentralDirectoryTotalRecordCount(eocdBuf);
-
-        return new ZipSections(
-                cdStartOffset,
-                cdSizeBytes,
-                cdRecordCount,
-                eocdOffset,
-                eocdBuf);
-    }
-
-    /**
-     * Information about the ZIP sections of an APK.
-     */
-    public static class ZipSections {
-        private final long mCentralDirectoryOffset;
-        private final long mCentralDirectorySizeBytes;
-        private final int mCentralDirectoryRecordCount;
-        private final long mEocdOffset;
-        private final ByteBuffer mEocd;
-
-        public ZipSections(
-                long centralDirectoryOffset,
-                long centralDirectorySizeBytes,
-                int centralDirectoryRecordCount,
-                long eocdOffset,
-                ByteBuffer eocd) {
-            mCentralDirectoryOffset = centralDirectoryOffset;
-            mCentralDirectorySizeBytes = centralDirectorySizeBytes;
-            mCentralDirectoryRecordCount = centralDirectoryRecordCount;
-            mEocdOffset = eocdOffset;
-            mEocd = eocd;
-        }
-
-        /**
-         * Returns the start offset of the ZIP Central Directory. This value is taken from the
-         * ZIP End of Central Directory record.
-         */
-        public long getZipCentralDirectoryOffset() {
-            return mCentralDirectoryOffset;
-        }
-
-        /**
-         * Returns the size (in bytes) of the ZIP Central Directory. This value is taken from the
-         * ZIP End of Central Directory record.
-         */
-        public long getZipCentralDirectorySizeBytes() {
-            return mCentralDirectorySizeBytes;
-        }
-
-        /**
-         * Returns the number of records in the ZIP Central Directory. This value is taken from the
-         * ZIP End of Central Directory record.
-         */
-        public int getZipCentralDirectoryRecordCount() {
-            return mCentralDirectoryRecordCount;
-        }
-
-        /**
-         * Returns the start offset of the ZIP End of Central Directory record. The record extends
-         * until the very end of the APK.
-         */
-        public long getZipEndOfCentralDirectoryOffset() {
-            return mEocdOffset;
-        }
-
-        /**
-         * Returns the contents of the ZIP End of Central Directory.
-         */
-        public ByteBuffer getZipEndOfCentralDirectory() {
-            return mEocd;
-        }
-    }
-
-    /**
-     * Sets the offset of the start of the ZIP Central Directory in the APK's ZIP End of Central
-     * Directory record.
-     *
-     * @param zipEndOfCentralDirectory APK's ZIP End of Central Directory record
-     * @param offset offset of the ZIP Central Directory relative to the start of the archive. Must
-     *        be between {@code 0} and {@code 2^32 - 1} inclusive.
-     */
-    public static void setZipEocdCentralDirectoryOffset(
-            ByteBuffer zipEndOfCentralDirectory, long offset) {
-        ByteBuffer eocd = zipEndOfCentralDirectory.slice();
-        eocd.order(ByteOrder.LITTLE_ENDIAN);
-        ZipUtils.setZipEocdCentralDirectoryOffset(eocd, offset);
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/DigestAlgorithm.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/DigestAlgorithm.java
deleted file mode 100644
index 71e698b..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/DigestAlgorithm.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.apk.v1;
-
-/**
- * Digest algorithm used with JAR signing (aka v1 signing scheme).
- */
-public enum DigestAlgorithm {
-    /** SHA-1 */
-    SHA1("SHA-1"),
-
-    /** SHA2-256 */
-    SHA256("SHA-256");
-
-    private final String mJcaMessageDigestAlgorithm;
-
-    private DigestAlgorithm(String jcaMessageDigestAlgoritm) {
-        mJcaMessageDigestAlgorithm = jcaMessageDigestAlgoritm;
-    }
-
-    /**
-     * Returns the {@link java.security.MessageDigest} algorithm represented by this digest
-     * algorithm.
-     */
-    String getJcaMessageDigestAlgorithm() {
-        return mJcaMessageDigestAlgorithm;
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/V1SchemeSigner.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/V1SchemeSigner.java
deleted file mode 100644
index f124d16..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/V1SchemeSigner.java
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.apk.v1;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.security.InvalidKeyException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.jar.Attributes;
-import java.util.jar.Manifest;
-
-import sun.security.pkcs.ContentInfo;
-import sun.security.pkcs.PKCS7;
-import sun.security.pkcs.SignerInfo;
-import sun.security.x509.AlgorithmId;
-import sun.security.x509.X500Name;
-
-import com.android.apksigner.core.internal.jar.ManifestWriter;
-import com.android.apksigner.core.internal.jar.SignatureFileWriter;
-import com.android.apksigner.core.internal.util.Pair;
-
-/**
- * APK signer which uses JAR signing (aka v1 signing scheme).
- *
- * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File">Signed JAR File</a>
- */
-public abstract class V1SchemeSigner {
-
-    public static final String MANIFEST_ENTRY_NAME = "META-INF/MANIFEST.MF";
-
-    private static final Attributes.Name ATTRIBUTE_NAME_CREATED_BY =
-            new Attributes.Name("Created-By");
-    private static final String ATTRIBUTE_DEFALT_VALUE_CREATED_BY = "1.0 (Android apksigner)";
-    private static final String ATTRIBUTE_VALUE_MANIFEST_VERSION = "1.0";
-    private static final String ATTRIBUTE_VALUE_SIGNATURE_VERSION = "1.0";
-
-    static final String SF_ATTRIBUTE_NAME_ANDROID_APK_SIGNED_NAME_STR = "X-Android-APK-Signed";
-    private static final Attributes.Name SF_ATTRIBUTE_NAME_ANDROID_APK_SIGNED_NAME =
-            new Attributes.Name(SF_ATTRIBUTE_NAME_ANDROID_APK_SIGNED_NAME_STR);
-
-    /**
-     * Signer configuration.
-     */
-    public static class SignerConfig {
-        /** Name. */
-        public String name;
-
-        /** Private key. */
-        public PrivateKey privateKey;
-
-        /**
-         * Certificates, with the first certificate containing the public key corresponding to
-         * {@link #privateKey}.
-         */
-        public List<X509Certificate> certificates;
-
-        /**
-         * Digest algorithm used for the signature.
-         */
-        public DigestAlgorithm signatureDigestAlgorithm;
-
-        /**
-         * Digest algorithm used for digests of JAR entries and MANIFEST.MF.
-         */
-        public DigestAlgorithm contentDigestAlgorithm;
-    }
-
-    /** Hidden constructor to prevent instantiation. */
-    private V1SchemeSigner() {}
-
-    /**
-     * Gets the JAR signing digest algorithm to be used for signing an APK using the provided key.
-     *
-     * @param minSdkVersion minimum API Level of the platform on which the APK may be installed (see
-     *        AndroidManifest.xml minSdkVersion attribute)
-     *
-     * @throws InvalidKeyException if the provided key is not suitable for signing APKs using
-     *         JAR signing (aka v1 signature scheme)
-     */
-    public static DigestAlgorithm getSuggestedSignatureDigestAlgorithm(
-            PublicKey signingKey, int minSdkVersion) throws InvalidKeyException {
-        String keyAlgorithm = signingKey.getAlgorithm();
-        if ("RSA".equalsIgnoreCase(keyAlgorithm)) {
-            // Prior to API Level 18, only SHA-1 can be used with RSA.
-            if (minSdkVersion < 18) {
-                return DigestAlgorithm.SHA1;
-            }
-            return DigestAlgorithm.SHA256;
-        } else if ("DSA".equalsIgnoreCase(keyAlgorithm)) {
-            // Prior to API Level 21, only SHA-1 can be used with DSA
-            if (minSdkVersion < 21) {
-                return DigestAlgorithm.SHA1;
-            } else {
-                return DigestAlgorithm.SHA256;
-            }
-        } else if ("EC".equalsIgnoreCase(keyAlgorithm)) {
-            if (minSdkVersion < 18) {
-                throw new InvalidKeyException(
-                        "ECDSA signatures only supported for minSdkVersion 18 and higher");
-            }
-            // Prior to API Level 21, only SHA-1 can be used with ECDSA
-            if (minSdkVersion < 21) {
-                return DigestAlgorithm.SHA1;
-            } else {
-                return DigestAlgorithm.SHA256;
-            }
-        } else {
-            throw new InvalidKeyException("Unsupported key algorithm: " + keyAlgorithm);
-        }
-    }
-
-    /**
-     * Returns the JAR signing digest algorithm to be used for JAR entry digests.
-     *
-     * @param minSdkVersion minimum API Level of the platform on which the APK may be installed (see
-     *        AndroidManifest.xml minSdkVersion attribute)
-     */
-    public static DigestAlgorithm getSuggestedContentDigestAlgorithm(int minSdkVersion) {
-        return (minSdkVersion >= 18) ? DigestAlgorithm.SHA256 : DigestAlgorithm.SHA1;
-    }
-
-    /**
-     * Returns a new {@link MessageDigest} instance corresponding to the provided digest algorithm.
-     */
-    private static MessageDigest getMessageDigestInstance(DigestAlgorithm digestAlgorithm)
-            throws NoSuchAlgorithmException {
-        String jcaAlgorithm = digestAlgorithm.getJcaMessageDigestAlgorithm();
-        return MessageDigest.getInstance(jcaAlgorithm);
-    }
-
-    /**
-     * Returns the JCA {@link MessageDigest} algorithm corresponding to the provided digest
-     * algorithm.
-     */
-    public static String getJcaMessageDigestAlgorithm(DigestAlgorithm digestAlgorithm) {
-        return digestAlgorithm.getJcaMessageDigestAlgorithm();
-    }
-
-    /**
-     * Returns {@code true} if the provided JAR entry must be mentioned in signed JAR archive's
-     * manifest.
-     */
-    public static boolean isJarEntryDigestNeededInManifest(String entryName) {
-        // See https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File
-
-        // Entries outside of META-INF must be listed in the manifest.
-        if (!entryName.startsWith("META-INF/")) {
-            return true;
-        }
-        // Entries in subdirectories of META-INF must be listed in the manifest.
-        if (entryName.indexOf('/', "META-INF/".length()) != -1) {
-            return true;
-        }
-
-        // Ignored file names (case-insensitive) in META-INF directory:
-        //   MANIFEST.MF
-        //   *.SF
-        //   *.RSA
-        //   *.DSA
-        //   *.EC
-        //   SIG-*
-        String fileNameLowerCase =
-                entryName.substring("META-INF/".length()).toLowerCase(Locale.US);
-        if (("manifest.mf".equals(fileNameLowerCase))
-                || (fileNameLowerCase.endsWith(".sf"))
-                || (fileNameLowerCase.endsWith(".rsa"))
-                || (fileNameLowerCase.endsWith(".dsa"))
-                || (fileNameLowerCase.endsWith(".ec"))
-                || (fileNameLowerCase.startsWith("sig-"))) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Signs the provided APK using JAR signing (aka v1 signature scheme) and returns the list of
-     * JAR entries which need to be added to the APK as part of the signature.
-     *
-     * @param signerConfigs signer configurations, one for each signer. At least one signer config
-     *        must be provided.
-     *
-     * @throws NoSuchAlgorithmException if a required cryptographic algorithm implementation is
-     *         missing
-     * @throws InvalidKeyException if a signing key is not suitable for this signature scheme or
-     *         cannot be used in general
-     * @throws SignatureException if an error occurs when computing digests of generating
-     *         signatures
-     */
-    public static List<Pair<String, byte[]>> sign(
-            List<SignerConfig> signerConfigs,
-            DigestAlgorithm jarEntryDigestAlgorithm,
-            Map<String, byte[]> jarEntryDigests,
-            List<Integer> apkSigningSchemeIds,
-            byte[] sourceManifestBytes)
-                    throws NoSuchAlgorithmException, InvalidKeyException, CertificateException,
-                            SignatureException {
-        if (signerConfigs.isEmpty()) {
-            throw new IllegalArgumentException("At least one signer config must be provided");
-        }
-        OutputManifestFile manifest =
-                generateManifestFile(jarEntryDigestAlgorithm, jarEntryDigests, sourceManifestBytes);
-
-        return signManifest(signerConfigs, jarEntryDigestAlgorithm, apkSigningSchemeIds, manifest);
-    }
-
-    /**
-     * Signs the provided APK using JAR signing (aka v1 signature scheme) and returns the list of
-     * JAR entries which need to be added to the APK as part of the signature.
-     *
-     * @param signerConfigs signer configurations, one for each signer. At least one signer config
-     *        must be provided.
-     *
-     * @throws InvalidKeyException if a signing key is not suitable for this signature scheme or
-     *         cannot be used in general
-     * @throws SignatureException if an error occurs when computing digests of generating
-     *         signatures
-     */
-    public static List<Pair<String, byte[]>> signManifest(
-            List<SignerConfig> signerConfigs,
-            DigestAlgorithm digestAlgorithm,
-            List<Integer> apkSigningSchemeIds,
-            OutputManifestFile manifest)
-                    throws NoSuchAlgorithmException, InvalidKeyException, CertificateException,
-                            SignatureException {
-        if (signerConfigs.isEmpty()) {
-            throw new IllegalArgumentException("At least one signer config must be provided");
-        }
-
-        // For each signer output .SF and .(RSA|DSA|EC) file, then output MANIFEST.MF.
-        List<Pair<String, byte[]>> signatureJarEntries =
-                new ArrayList<>(2 * signerConfigs.size() + 1);
-        byte[] sfBytes =
-                generateSignatureFile(apkSigningSchemeIds, digestAlgorithm, manifest);
-        for (SignerConfig signerConfig : signerConfigs) {
-            String signerName = signerConfig.name;
-            byte[] signatureBlock;
-            try {
-                signatureBlock = generateSignatureBlock(signerConfig, sfBytes);
-            } catch (InvalidKeyException e) {
-                throw new InvalidKeyException(
-                        "Failed to sign using signer \"" + signerName + "\"", e);
-            } catch (CertificateException e) {
-                throw new CertificateException(
-                        "Failed to sign using signer \"" + signerName + "\"", e);
-            } catch (SignatureException e) {
-                throw new SignatureException(
-                        "Failed to sign using signer \"" + signerName + "\"", e);
-            }
-            signatureJarEntries.add(Pair.of("META-INF/" + signerName + ".SF", sfBytes));
-            PublicKey publicKey = signerConfig.certificates.get(0).getPublicKey();
-            String signatureBlockFileName =
-                    "META-INF/" + signerName + "."
-                            + publicKey.getAlgorithm().toUpperCase(Locale.US);
-            signatureJarEntries.add(
-                    Pair.of(signatureBlockFileName, signatureBlock));
-        }
-        signatureJarEntries.add(Pair.of(MANIFEST_ENTRY_NAME, manifest.contents));
-        return signatureJarEntries;
-    }
-
-    /**
-     * Returns the names of JAR entries which this signer will produce as part of v1 signature.
-     */
-    public static Set<String> getOutputEntryNames(List<SignerConfig> signerConfigs) {
-        Set<String> result = new HashSet<>(2 * signerConfigs.size() + 1);
-        for (SignerConfig signerConfig : signerConfigs) {
-            String signerName = signerConfig.name;
-            result.add("META-INF/" + signerName + ".SF");
-            PublicKey publicKey = signerConfig.certificates.get(0).getPublicKey();
-            String signatureBlockFileName =
-                    "META-INF/" + signerName + "."
-                            + publicKey.getAlgorithm().toUpperCase(Locale.US);
-            result.add(signatureBlockFileName);
-        }
-        result.add(MANIFEST_ENTRY_NAME);
-        return result;
-    }
-
-    /**
-     * Generated and returns the {@code META-INF/MANIFEST.MF} file based on the provided (optional)
-     * input {@code MANIFEST.MF} and digests of JAR entries covered by the manifest.
-     */
-    public static OutputManifestFile generateManifestFile(
-            DigestAlgorithm jarEntryDigestAlgorithm,
-            Map<String, byte[]> jarEntryDigests,
-            byte[] sourceManifestBytes) {
-        Manifest sourceManifest = null;
-        if (sourceManifestBytes != null) {
-            try {
-                sourceManifest = new Manifest(new ByteArrayInputStream(sourceManifestBytes));
-            } catch (IOException e) {
-                throw new IllegalArgumentException("Failed to parse source MANIFEST.MF", e);
-            }
-        }
-        ByteArrayOutputStream manifestOut = new ByteArrayOutputStream();
-        Attributes mainAttrs = new Attributes();
-        // Copy the main section from the source manifest (if provided). Otherwise use defaults.
-        if (sourceManifest != null) {
-            mainAttrs.putAll(sourceManifest.getMainAttributes());
-        } else {
-            mainAttrs.put(Attributes.Name.MANIFEST_VERSION, ATTRIBUTE_VALUE_MANIFEST_VERSION);
-            mainAttrs.put(ATTRIBUTE_NAME_CREATED_BY, ATTRIBUTE_DEFALT_VALUE_CREATED_BY);
-        }
-
-        try {
-            ManifestWriter.writeMainSection(manifestOut, mainAttrs);
-        } catch (IOException e) {
-            throw new RuntimeException("Failed to write in-memory MANIFEST.MF", e);
-        }
-
-        List<String> sortedEntryNames = new ArrayList<>(jarEntryDigests.keySet());
-        Collections.sort(sortedEntryNames);
-        SortedMap<String, byte[]> invidualSectionsContents = new TreeMap<>();
-        String entryDigestAttributeName = getEntryDigestAttributeName(jarEntryDigestAlgorithm);
-        for (String entryName : sortedEntryNames) {
-            byte[] entryDigest = jarEntryDigests.get(entryName);
-            Attributes entryAttrs = new Attributes();
-            entryAttrs.putValue(
-                    entryDigestAttributeName,
-                    Base64.getEncoder().encodeToString(entryDigest));
-            ByteArrayOutputStream sectionOut = new ByteArrayOutputStream();
-            byte[] sectionBytes;
-            try {
-                ManifestWriter.writeIndividualSection(sectionOut, entryName, entryAttrs);
-                sectionBytes = sectionOut.toByteArray();
-                manifestOut.write(sectionBytes);
-            } catch (IOException e) {
-                throw new RuntimeException("Failed to write in-memory MANIFEST.MF", e);
-            }
-            invidualSectionsContents.put(entryName, sectionBytes);
-        }
-
-        OutputManifestFile result = new OutputManifestFile();
-        result.contents = manifestOut.toByteArray();
-        result.mainSectionAttributes = mainAttrs;
-        result.individualSectionsContents = invidualSectionsContents;
-        return result;
-    }
-
-    public static class OutputManifestFile {
-        public byte[] contents;
-        public SortedMap<String, byte[]> individualSectionsContents;
-        public Attributes mainSectionAttributes;
-    }
-
-    private static byte[] generateSignatureFile(
-            List<Integer> apkSignatureSchemeIds,
-            DigestAlgorithm manifestDigestAlgorithm,
-            OutputManifestFile manifest) throws NoSuchAlgorithmException {
-        Manifest sf = new Manifest();
-        Attributes mainAttrs = sf.getMainAttributes();
-        mainAttrs.put(Attributes.Name.SIGNATURE_VERSION, ATTRIBUTE_VALUE_SIGNATURE_VERSION);
-        mainAttrs.put(ATTRIBUTE_NAME_CREATED_BY, ATTRIBUTE_DEFALT_VALUE_CREATED_BY);
-        if (!apkSignatureSchemeIds.isEmpty()) {
-            // Add APK Signature Scheme v2 (and newer) signature stripping protection.
-            // This attribute indicates that this APK is supposed to have been signed using one or
-            // more APK-specific signature schemes in addition to the standard JAR signature scheme
-            // used by this code. APK signature verifier should reject the APK if it does not
-            // contain a signature for the signature scheme the verifier prefers out of this set.
-            StringBuilder attrValue = new StringBuilder();
-            for (int id : apkSignatureSchemeIds) {
-                if (attrValue.length() > 0) {
-                    attrValue.append(", ");
-                }
-                attrValue.append(String.valueOf(id));
-            }
-            mainAttrs.put(
-                    SF_ATTRIBUTE_NAME_ANDROID_APK_SIGNED_NAME,
-                    attrValue.toString());
-        }
-
-        // Add main attribute containing the digest of MANIFEST.MF.
-        MessageDigest md = getMessageDigestInstance(manifestDigestAlgorithm);
-        mainAttrs.putValue(
-                getManifestDigestAttributeName(manifestDigestAlgorithm),
-                Base64.getEncoder().encodeToString(md.digest(manifest.contents)));
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        try {
-            SignatureFileWriter.writeMainSection(out, mainAttrs);
-        } catch (IOException e) {
-            throw new RuntimeException("Failed to write in-memory .SF file", e);
-        }
-        String entryDigestAttributeName = getEntryDigestAttributeName(manifestDigestAlgorithm);
-        for (Map.Entry<String, byte[]> manifestSection
-                : manifest.individualSectionsContents.entrySet()) {
-            String sectionName = manifestSection.getKey();
-            byte[] sectionContents = manifestSection.getValue();
-            byte[] sectionDigest = md.digest(sectionContents);
-            Attributes attrs = new Attributes();
-            attrs.putValue(
-                    entryDigestAttributeName,
-                    Base64.getEncoder().encodeToString(sectionDigest));
-
-            try {
-                SignatureFileWriter.writeIndividualSection(out, sectionName, attrs);
-            } catch (IOException e) {
-                throw new RuntimeException("Failed to write in-memory .SF file", e);
-            }
-        }
-
-        // A bug in the java.util.jar implementation of Android platforms up to version 1.6 will
-        // cause a spurious IOException to be thrown if the length of the signature file is a
-        // multiple of 1024 bytes. As a workaround, add an extra CRLF in this case.
-        if ((out.size() > 0) && ((out.size() % 1024) == 0)) {
-            try {
-                SignatureFileWriter.writeSectionDelimiter(out);
-            } catch (IOException e) {
-                throw new RuntimeException("Failed to write to ByteArrayOutputStream", e);
-            }
-        }
-
-        return out.toByteArray();
-    }
-
-    @SuppressWarnings("restriction")
-    private static byte[] generateSignatureBlock(
-            SignerConfig signerConfig, byte[] signatureFileBytes)
-                    throws NoSuchAlgorithmException, InvalidKeyException, CertificateException,
-                            SignatureException {
-        List<X509Certificate> signerCerts = signerConfig.certificates;
-        X509Certificate signerCert = signerCerts.get(0);
-        PublicKey signerPublicKey = signerCert.getPublicKey();
-        DigestAlgorithm digestAlgorithm = signerConfig.signatureDigestAlgorithm;
-        Pair<String, AlgorithmId> signatureAlgs =
-                getSignerInfoSignatureAlgorithm(signerPublicKey, digestAlgorithm);
-        String jcaSignatureAlgorithm = signatureAlgs.getFirst();
-        Signature signature = Signature.getInstance(jcaSignatureAlgorithm);
-        signature.initSign(signerConfig.privateKey);
-        signature.update(signatureFileBytes);
-        byte[] signatureBytes = signature.sign();
-
-        X500Name issuerName;
-        try {
-            issuerName = new X500Name(signerCert.getIssuerX500Principal().getName());
-        } catch (IOException e) {
-            throw new CertificateParsingException(
-                    "Failed to parse signer certificate issuer name", e);
-        }
-
-        AlgorithmId digestAlgorithmId = getSignerInfoDigestAlgorithm(digestAlgorithm);
-        SignerInfo signerInfo =
-                new SignerInfo(
-                        issuerName,
-                        signerCert.getSerialNumber(),
-                        digestAlgorithmId,
-                        signatureAlgs.getSecond(),
-                        signatureBytes);
-        PKCS7 pkcs7 =
-                new PKCS7(
-                        new AlgorithmId[] {digestAlgorithmId},
-                        new ContentInfo(ContentInfo.DATA_OID, null),
-                        signerCerts.toArray(new X509Certificate[signerCerts.size()]),
-                        new SignerInfo[] {signerInfo});
-
-        ByteArrayOutputStream result = new ByteArrayOutputStream();
-        try {
-            pkcs7.encodeSignedData(result);
-        } catch (IOException e) {
-            throw new SignatureException("Failed to encode PKCS#7 signed data", e);
-        }
-        return result.toByteArray();
-    }
-
-    @SuppressWarnings("restriction")
-    private static final AlgorithmId OID_DIGEST_SHA1 = getSupportedAlgorithmId("1.3.14.3.2.26");
-    @SuppressWarnings("restriction")
-    private static final AlgorithmId OID_DIGEST_SHA256 =
-            getSupportedAlgorithmId("2.16.840.1.101.3.4.2.1");
-
-    /**
-     * Returns the {@code SignerInfo} {@code DigestAlgorithm} to use for {@code SignerInfo} signing
-     * using the specified digest algorithm.
-     */
-    @SuppressWarnings("restriction")
-    private static AlgorithmId getSignerInfoDigestAlgorithm(DigestAlgorithm digestAlgorithm) {
-        switch (digestAlgorithm) {
-            case SHA1:
-                return OID_DIGEST_SHA1;
-            case SHA256:
-                return OID_DIGEST_SHA256;
-            default:
-                throw new RuntimeException("Unsupported digest algorithm: " + digestAlgorithm);
-        }
-    }
-
-    /**
-     * Returns the JCA {@link Signature} algorithm and {@code SignerInfo} {@code SignatureAlgorithm}
-     * to use for {@code SignerInfo} which signs with the specified key and digest algorithms.
-     */
-    @SuppressWarnings("restriction")
-    private static Pair<String, AlgorithmId> getSignerInfoSignatureAlgorithm(
-            PublicKey publicKey, DigestAlgorithm digestAlgorithm) throws InvalidKeyException {
-        // NOTE: This method on purpose uses hard-coded OIDs instead of
-        // Algorithm.getId(JCA Signature Algorithm). This is to ensure that the generated SignedData
-        // is compatible with all targeted Android platforms and is not dependent on changes in the
-        // JCA Signature Algorithm -> OID mappings maintained by AlgorithmId.get(String).
-
-        String keyAlgorithm = publicKey.getAlgorithm();
-        String digestPrefixForSigAlg;
-        switch (digestAlgorithm) {
-            case SHA1:
-                digestPrefixForSigAlg = "SHA1";
-                break;
-            case SHA256:
-                digestPrefixForSigAlg = "SHA256";
-                break;
-            default:
-                throw new IllegalArgumentException(
-                        "Unexpected digest algorithm: " + digestAlgorithm);
-        }
-        if ("RSA".equalsIgnoreCase(keyAlgorithm)) {
-            return Pair.of(
-                    digestPrefixForSigAlg + "withRSA",
-                    getSupportedAlgorithmId("1.2.840.113549.1.1.1") // RSA encryption
-                    );
-        } else if ("DSA".equalsIgnoreCase(keyAlgorithm)) {
-            AlgorithmId sigAlgId;
-            switch (digestAlgorithm) {
-                case SHA1:
-                    sigAlgId = getSupportedAlgorithmId("1.2.840.10040.4.1"); // DSA
-                    break;
-                case SHA256:
-                    // DSA signatures with SHA-256 in SignedData are accepted by Android API Level
-                    // 21 and higher. However, there are two ways to specify their SignedData
-                    // SignatureAlgorithm: dsaWithSha256 (2.16.840.1.101.3.4.3.2) and
-                    // dsa (1.2.840.10040.4.1). The latter works only on API Level 22+. Thus, we use
-                    // the former.
-                    sigAlgId =
-                            getSupportedAlgorithmId("2.16.840.1.101.3.4.3.2"); // DSA with SHA-256
-                    break;
-                default:
-                    throw new IllegalArgumentException(
-                            "Unexpected digest algorithm: " + digestAlgorithm);
-            }
-            return Pair.of(digestPrefixForSigAlg + "withDSA", sigAlgId);
-        } else if ("EC".equalsIgnoreCase(keyAlgorithm)) {
-            AlgorithmId sigAlgId;
-            switch (digestAlgorithm) {
-                case SHA1:
-                    sigAlgId = getSupportedAlgorithmId("1.2.840.10045.4.1"); // ECDSA with SHA-1
-                    break;
-                case SHA256:
-                    sigAlgId = getSupportedAlgorithmId("1.2.840.10045.4.3.2"); // ECDSA with SHA-256
-                    break;
-                default:
-                    throw new IllegalArgumentException(
-                            "Unexpected digest algorithm: " + digestAlgorithm);
-            }
-            return Pair.of(digestPrefixForSigAlg + "withECDSA", sigAlgId);
-        } else {
-            throw new InvalidKeyException("Unsupported key algorithm: " + keyAlgorithm);
-        }
-    }
-
-    @SuppressWarnings("restriction")
-    private static AlgorithmId getSupportedAlgorithmId(String oid) {
-        try {
-            return AlgorithmId.get(oid);
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException("Unsupported OID: " + oid, e);
-        }
-    }
-
-    private static String getEntryDigestAttributeName(DigestAlgorithm digestAlgorithm) {
-        switch (digestAlgorithm) {
-            case SHA1:
-                return "SHA1-Digest";
-            case SHA256:
-                return "SHA-256-Digest";
-            default:
-                throw new IllegalArgumentException(
-                        "Unexpected content digest algorithm: " + digestAlgorithm);
-        }
-    }
-
-    private static String getManifestDigestAttributeName(DigestAlgorithm digestAlgorithm) {
-        switch (digestAlgorithm) {
-            case SHA1:
-                return "SHA1-Digest-Manifest";
-            case SHA256:
-                return "SHA-256-Digest-Manifest";
-            default:
-                throw new IllegalArgumentException(
-                        "Unexpected content digest algorithm: " + digestAlgorithm);
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/V1SchemeVerifier.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/V1SchemeVerifier.java
deleted file mode 100644
index 752ba7e..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v1/V1SchemeVerifier.java
+++ /dev/null
@@ -1,1559 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.apk.v1;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SignatureException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Base64;
-import java.util.Base64.Decoder;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.jar.Attributes;
-
-import com.android.apksigner.core.ApkVerifier.Issue;
-import com.android.apksigner.core.ApkVerifier.IssueWithParams;
-import com.android.apksigner.core.apk.ApkUtils;
-import com.android.apksigner.core.internal.jar.ManifestParser;
-import com.android.apksigner.core.internal.util.AndroidSdkVersion;
-import com.android.apksigner.core.internal.util.InclusiveIntRange;
-import com.android.apksigner.core.internal.util.MessageDigestSink;
-import com.android.apksigner.core.internal.zip.CentralDirectoryRecord;
-import com.android.apksigner.core.internal.zip.LocalFileRecord;
-import com.android.apksigner.core.util.DataSource;
-import com.android.apksigner.core.zip.ZipFormatException;
-
-import sun.security.pkcs.PKCS7;
-import sun.security.pkcs.SignerInfo;
-
-/**
- * APK verifier which uses JAR signing (aka v1 signing scheme).
- *
- * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File">Signed JAR File</a>
- */
-public abstract class V1SchemeVerifier {
-
-    private static final String MANIFEST_ENTRY_NAME = V1SchemeSigner.MANIFEST_ENTRY_NAME;
-
-    private V1SchemeVerifier() {}
-
-    /**
-     * Verifies the provided APK's JAR signatures and returns the result of verification. APK is
-     * considered verified only if {@link Result#verified} is {@code true}. If verification fails,
-     * the result will contain errors -- see {@link Result#getErrors()}.
-     *
-     * @throws ZipFormatException if the APK is malformed
-     * @throws IOException if an I/O error occurs when reading the APK
-     * @throws NoSuchAlgorithmException if the APK's JAR signatures cannot be verified because a
-     *         required cryptographic algorithm implementation is missing
-     */
-    public static Result verify(
-            DataSource apk,
-            ApkUtils.ZipSections apkSections,
-            Map<Integer, String> supportedApkSigSchemeNames,
-            Set<Integer> foundApkSigSchemeIds,
-            int minSdkVersion,
-            int maxSdkVersion) throws IOException, ZipFormatException, NoSuchAlgorithmException {
-        if (minSdkVersion > maxSdkVersion) {
-            throw new IllegalArgumentException(
-                    "minSdkVersion (" + minSdkVersion + ") > maxSdkVersion (" + maxSdkVersion
-                            + ")");
-        }
-
-        Result result = new Result();
-
-        // Parse the ZIP Central Directory and check that there are no entries with duplicate names.
-        List<CentralDirectoryRecord> cdRecords = parseZipCentralDirectory(apk, apkSections);
-        Set<String> cdEntryNames = checkForDuplicateEntries(cdRecords, result);
-        if (result.containsErrors()) {
-            return result;
-        }
-
-        // Verify JAR signature(s).
-        Signers.verify(
-                apk,
-                apkSections.getZipCentralDirectoryOffset(),
-                cdRecords,
-                cdEntryNames,
-                supportedApkSigSchemeNames,
-                foundApkSigSchemeIds,
-                minSdkVersion,
-                maxSdkVersion,
-                result);
-
-        return result;
-    }
-
-    /**
-     * Returns the set of entry names and reports any duplicate entry names in the {@code result}
-     * as errors.
-     */
-    private static Set<String> checkForDuplicateEntries(
-            List<CentralDirectoryRecord> cdRecords, Result result) {
-        Set<String> cdEntryNames = new HashSet<>(cdRecords.size());
-        Set<String> duplicateCdEntryNames = null;
-        for (CentralDirectoryRecord cdRecord : cdRecords) {
-            String entryName = cdRecord.getName();
-            if (!cdEntryNames.add(entryName)) {
-                // This is an error. Report this once per duplicate name.
-                if (duplicateCdEntryNames == null) {
-                    duplicateCdEntryNames = new HashSet<>();
-                }
-                if (duplicateCdEntryNames.add(entryName)) {
-                    result.addError(Issue.JAR_SIG_DUPLICATE_ZIP_ENTRY, entryName);
-                }
-            }
-        }
-        return cdEntryNames;
-    }
-
-    /**
-     * All JAR signers of an APK.
-     */
-    private static class Signers {
-
-        /**
-         * Verifies JAR signatures of the provided APK and populates the provided result container
-         * with errors, warnings, and information about signers. The APK is considered verified if
-         * the {@link Result#verified} is {@code true}.
-         */
-        private static void verify(
-                DataSource apk,
-                long cdStartOffset,
-                List<CentralDirectoryRecord> cdRecords,
-                Set<String> cdEntryNames,
-                Map<Integer, String> supportedApkSigSchemeNames,
-                Set<Integer> foundApkSigSchemeIds,
-                int minSdkVersion,
-                int maxSdkVersion,
-                Result result) throws ZipFormatException, IOException, NoSuchAlgorithmException {
-
-            // Find JAR manifest and signature block files.
-            CentralDirectoryRecord manifestEntry = null;
-            Map<String, CentralDirectoryRecord> sigFileEntries = new HashMap<>(1);
-            List<CentralDirectoryRecord> sigBlockEntries = new ArrayList<>(1);
-            for (CentralDirectoryRecord cdRecord : cdRecords) {
-                String entryName = cdRecord.getName();
-                if (!entryName.startsWith("META-INF/")) {
-                    continue;
-                }
-                if ((manifestEntry == null) && (MANIFEST_ENTRY_NAME.equals(entryName))) {
-                    manifestEntry = cdRecord;
-                    continue;
-                }
-                if (entryName.endsWith(".SF")) {
-                    sigFileEntries.put(entryName, cdRecord);
-                    continue;
-                }
-                if ((entryName.endsWith(".RSA"))
-                        || (entryName.endsWith(".DSA"))
-                        || (entryName.endsWith(".EC"))) {
-                    sigBlockEntries.add(cdRecord);
-                    continue;
-                }
-            }
-            if (manifestEntry == null) {
-                result.addError(Issue.JAR_SIG_NO_MANIFEST);
-                return;
-            }
-
-            // Parse the JAR manifest and check that all JAR entries it references exist in the APK.
-            byte[] manifestBytes =
-                    LocalFileRecord.getUncompressedData(apk, manifestEntry, cdStartOffset);
-            Map<String, ManifestParser.Section> entryNameToManifestSection = null;
-            ManifestParser manifest = new ManifestParser(manifestBytes);
-            ManifestParser.Section manifestMainSection = manifest.readSection();
-            List<ManifestParser.Section> manifestIndividualSections = manifest.readAllSections();
-            entryNameToManifestSection = new HashMap<>(manifestIndividualSections.size());
-            int manifestSectionNumber = 0;
-            for (ManifestParser.Section manifestSection : manifestIndividualSections) {
-                manifestSectionNumber++;
-                String entryName = manifestSection.getName();
-                if (entryName == null) {
-                    result.addError(Issue.JAR_SIG_UNNNAMED_MANIFEST_SECTION, manifestSectionNumber);
-                    continue;
-                }
-                if (entryNameToManifestSection.put(entryName, manifestSection) != null) {
-                    result.addError(Issue.JAR_SIG_DUPLICATE_MANIFEST_SECTION, entryName);
-                    continue;
-                }
-                if (!cdEntryNames.contains(entryName)) {
-                    result.addError(
-                            Issue.JAR_SIG_MISSING_ZIP_ENTRY_REFERENCED_IN_MANIFEST, entryName);
-                    continue;
-                }
-            }
-            if (result.containsErrors()) {
-                return;
-            }
-            // STATE OF AFFAIRS:
-            // * All JAR entries listed in JAR manifest are present in the APK.
-
-            // Identify signers
-            List<Signer> signers = new ArrayList<>(sigBlockEntries.size());
-            for (CentralDirectoryRecord sigBlockEntry : sigBlockEntries) {
-                String sigBlockEntryName = sigBlockEntry.getName();
-                int extensionDelimiterIndex = sigBlockEntryName.lastIndexOf('.');
-                if (extensionDelimiterIndex == -1) {
-                    throw new RuntimeException(
-                            "Signature block file name does not contain extension: "
-                                    + sigBlockEntryName);
-                }
-                String sigFileEntryName =
-                        sigBlockEntryName.substring(0, extensionDelimiterIndex) + ".SF";
-                CentralDirectoryRecord sigFileEntry = sigFileEntries.get(sigFileEntryName);
-                if (sigFileEntry == null) {
-                    result.addWarning(
-                            Issue.JAR_SIG_MISSING_FILE, sigBlockEntryName, sigFileEntryName);
-                    continue;
-                }
-                String signerName = sigBlockEntryName.substring("META-INF/".length());
-                Result.SignerInfo signerInfo =
-                        new Result.SignerInfo(
-                                signerName, sigBlockEntryName, sigFileEntry.getName());
-                Signer signer = new Signer(signerName, sigBlockEntry, sigFileEntry, signerInfo);
-                signers.add(signer);
-            }
-            if (signers.isEmpty()) {
-                result.addError(Issue.JAR_SIG_NO_SIGNATURES);
-                return;
-            }
-
-            // Verify each signer's signature block file .(RSA|DSA|EC) against the corresponding
-            // signature file .SF. Any error encountered for any signer terminates verification, to
-            // mimic Android's behavior.
-            for (Signer signer : signers) {
-                signer.verifySigBlockAgainstSigFile(
-                        apk, cdStartOffset, minSdkVersion, maxSdkVersion);
-                if (signer.getResult().containsErrors()) {
-                    result.signers.add(signer.getResult());
-                }
-            }
-            if (result.containsErrors()) {
-                return;
-            }
-            // STATE OF AFFAIRS:
-            // * All JAR entries listed in JAR manifest are present in the APK.
-            // * All signature files (.SF) verify against corresponding block files (.RSA|.DSA|.EC).
-
-            // Verify each signer's signature file (.SF) against the JAR manifest.
-            List<Signer> remainingSigners = new ArrayList<>(signers.size());
-            for (Signer signer : signers) {
-                signer.verifySigFileAgainstManifest(
-                        manifestBytes,
-                        manifestMainSection,
-                        entryNameToManifestSection,
-                        supportedApkSigSchemeNames,
-                        foundApkSigSchemeIds,
-                        minSdkVersion,
-                        maxSdkVersion);
-                if (signer.isIgnored()) {
-                    result.ignoredSigners.add(signer.getResult());
-                } else {
-                    if (signer.getResult().containsErrors()) {
-                        result.signers.add(signer.getResult());
-                    } else {
-                        remainingSigners.add(signer);
-                    }
-                }
-            }
-            if (result.containsErrors()) {
-                return;
-            }
-            signers = remainingSigners;
-            if (signers.isEmpty()) {
-                result.addError(Issue.JAR_SIG_NO_SIGNATURES);
-                return;
-            }
-            // STATE OF AFFAIRS:
-            // * All signature files (.SF) verify against corresponding block files (.RSA|.DSA|.EC).
-            // * Contents of all JAR manifest sections listed in .SF files verify against .SF files.
-            // * All JAR entries listed in JAR manifest are present in the APK.
-
-            // Verify data of JAR entries against JAR manifest and .SF files. On Android, an APK's
-            // JAR entry is considered signed by signers associated with an .SF file iff the entry
-            // is mentioned in the .SF file and the entry's digest(s) mentioned in the JAR manifest
-            // match theentry's uncompressed data. Android requires that all such JAR entries are
-            // signed by the same set of signers. This set may be smaller than the set of signers
-            // we've identified so far.
-            Set<Signer> apkSigners =
-                    verifyJarEntriesAgainstManifestAndSigners(
-                            apk,
-                            cdStartOffset,
-                            cdRecords,
-                            entryNameToManifestSection,
-                            signers,
-                            minSdkVersion,
-                            maxSdkVersion,
-                            result);
-            if (result.containsErrors()) {
-                return;
-            }
-            // STATE OF AFFAIRS:
-            // * All signature files (.SF) verify against corresponding block files (.RSA|.DSA|.EC).
-            // * Contents of all JAR manifest sections listed in .SF files verify against .SF files.
-            // * All JAR entries listed in JAR manifest are present in the APK.
-            // * All JAR entries present in the APK and supposed to be covered by JAR signature
-            //   (i.e., reside outside of META-INF/) are covered by signatures from the same set
-            //   of signers.
-
-            // Report any JAR entries which aren't covered by signature.
-            Set<String> signatureEntryNames = new HashSet<>(1 + result.signers.size() * 2);
-            signatureEntryNames.add(manifestEntry.getName());
-            for (Signer signer : apkSigners) {
-                signatureEntryNames.add(signer.getSignatureBlockEntryName());
-                signatureEntryNames.add(signer.getSignatureFileEntryName());
-            }
-            for (CentralDirectoryRecord cdRecord : cdRecords) {
-                String entryName = cdRecord.getName();
-                if ((entryName.startsWith("META-INF/"))
-                        && (!entryName.endsWith("/"))
-                        && (!signatureEntryNames.contains(entryName))) {
-                    result.addWarning(Issue.JAR_SIG_UNPROTECTED_ZIP_ENTRY, entryName);
-                }
-            }
-
-            // Reflect the sets of used signers and ignored signers in the result.
-            for (Signer signer : signers) {
-                if (apkSigners.contains(signer)) {
-                    result.signers.add(signer.getResult());
-                } else {
-                    result.ignoredSigners.add(signer.getResult());
-                }
-            }
-
-            result.verified = true;
-        }
-    }
-
-    private static class Signer {
-        private final String mName;
-        private final Result.SignerInfo mResult;
-        private final CentralDirectoryRecord mSignatureFileEntry;
-        private final CentralDirectoryRecord mSignatureBlockEntry;
-        private boolean mIgnored;
-
-        private byte[] mSigFileBytes;
-        private Set<String> mSigFileEntryNames;
-
-        private Signer(
-                String name,
-                CentralDirectoryRecord sigBlockEntry,
-                CentralDirectoryRecord sigFileEntry,
-                Result.SignerInfo result) {
-            mName = name;
-            mResult = result;
-            mSignatureBlockEntry = sigBlockEntry;
-            mSignatureFileEntry = sigFileEntry;
-        }
-
-        public String getName() {
-            return mName;
-        }
-
-        public String getSignatureFileEntryName() {
-            return mSignatureFileEntry.getName();
-        }
-
-        public String getSignatureBlockEntryName() {
-            return mSignatureBlockEntry.getName();
-        }
-
-        void setIgnored() {
-            mIgnored = true;
-        }
-
-        public boolean isIgnored() {
-            return mIgnored;
-        }
-
-        public Set<String> getSigFileEntryNames() {
-            return mSigFileEntryNames;
-        }
-
-        public Result.SignerInfo getResult() {
-            return mResult;
-        }
-
-        @SuppressWarnings("restriction")
-        public void verifySigBlockAgainstSigFile(
-                DataSource apk, long cdStartOffset, int minSdkVersion, int maxSdkVersion)
-                        throws IOException, ZipFormatException, NoSuchAlgorithmException {
-            byte[] sigBlockBytes =
-                    LocalFileRecord.getUncompressedData(apk, mSignatureBlockEntry, cdStartOffset);
-            mSigFileBytes =
-                    LocalFileRecord.getUncompressedData(apk, mSignatureFileEntry, cdStartOffset);
-            PKCS7 sigBlock;
-            try {
-                sigBlock = new PKCS7(sigBlockBytes);
-            } catch (IOException e) {
-                if (e.getCause() instanceof CertificateException) {
-                    mResult.addError(
-                            Issue.JAR_SIG_MALFORMED_CERTIFICATE, mSignatureBlockEntry.getName(), e);
-                } else {
-                    mResult.addError(
-                            Issue.JAR_SIG_PARSE_EXCEPTION, mSignatureBlockEntry.getName(), e);
-                }
-                return;
-            }
-            SignerInfo[] unverifiedSignerInfos = sigBlock.getSignerInfos();
-            if ((unverifiedSignerInfos == null) || (unverifiedSignerInfos.length == 0)) {
-                mResult.addError(Issue.JAR_SIG_NO_SIGNERS, mSignatureBlockEntry.getName());
-                return;
-            }
-
-            SignerInfo verifiedSignerInfo = null;
-            if ((unverifiedSignerInfos != null) && (unverifiedSignerInfos.length > 0)) {
-                for (int i = 0; i < unverifiedSignerInfos.length; i++) {
-                    SignerInfo unverifiedSignerInfo = unverifiedSignerInfos[i];
-                    String digestAlgorithmOid =
-                            unverifiedSignerInfo.getDigestAlgorithmId().getOID().toString();
-                    String signatureAlgorithmOid =
-                            unverifiedSignerInfo
-                                    .getDigestEncryptionAlgorithmId().getOID().toString();
-                    InclusiveIntRange desiredApiLevels =
-                            InclusiveIntRange.fromTo(minSdkVersion, maxSdkVersion);
-                    List<InclusiveIntRange> apiLevelsWhereDigestAndSigAlgorithmSupported =
-                            getSigAlgSupportedApiLevels(digestAlgorithmOid, signatureAlgorithmOid);
-                    List<InclusiveIntRange> apiLevelsWhereDigestAlgorithmNotSupported =
-                            desiredApiLevels.getValuesNotIn(apiLevelsWhereDigestAndSigAlgorithmSupported);
-                    if (!apiLevelsWhereDigestAlgorithmNotSupported.isEmpty()) {
-                        mResult.addError(
-                                Issue.JAR_SIG_UNSUPPORTED_SIG_ALG,
-                                mSignatureBlockEntry.getName(),
-                                digestAlgorithmOid,
-                                signatureAlgorithmOid,
-                                String.valueOf(apiLevelsWhereDigestAlgorithmNotSupported));
-                        return;
-                    }
-                    try {
-                        verifiedSignerInfo = sigBlock.verify(unverifiedSignerInfo, mSigFileBytes);
-                    } catch (SignatureException e) {
-                        mResult.addError(
-                                Issue.JAR_SIG_VERIFY_EXCEPTION,
-                                mSignatureBlockEntry.getName(),
-                                mSignatureFileEntry.getName(),
-                                e);
-                        return;
-                    }
-                    if (verifiedSignerInfo != null) {
-                        // Verified
-                        break;
-                    }
-
-                    // Did not verify
-                    if (minSdkVersion < AndroidSdkVersion.N) {
-                        // Prior to N, Android attempted to verify only the first SignerInfo.
-                        mResult.addError(
-                                Issue.JAR_SIG_DID_NOT_VERIFY,
-                                mSignatureBlockEntry.getName(),
-                                mSignatureFileEntry.getName());
-                        return;
-                    }
-                }
-            }
-            if (verifiedSignerInfo == null) {
-                mResult.addError(Issue.JAR_SIG_NO_SIGNERS, mSignatureBlockEntry.getName());
-                return;
-            }
-
-            List<X509Certificate> certChain;
-            try {
-                certChain = verifiedSignerInfo.getCertificateChain(sigBlock);
-            } catch (IOException e) {
-                throw new RuntimeException(
-                        "Failed to obtain cert chain from " + mSignatureBlockEntry.getName(), e);
-            }
-            if ((certChain == null) || (certChain.isEmpty())) {
-                throw new RuntimeException("Verified SignerInfo does not have a certificate chain");
-            }
-            mResult.certChain.clear();
-            mResult.certChain.addAll(certChain);
-        }
-
-        private static final String OID_DIGEST_MD5 = "1.2.840.113549.2.5";
-        private static final String OID_DIGEST_SHA1 = "1.3.14.3.2.26";
-        private static final String OID_DIGEST_SHA224 = "2.16.840.1.101.3.4.2.4";
-        private static final String OID_DIGEST_SHA256 = "2.16.840.1.101.3.4.2.1";
-        private static final String OID_DIGEST_SHA384 = "2.16.840.1.101.3.4.2.2";
-        private static final String OID_DIGEST_SHA512 = "2.16.840.1.101.3.4.2.3";
-
-        private static final String OID_SIG_RSA = "1.2.840.113549.1.1.1";
-        private static final String OID_SIG_MD5_WITH_RSA = "1.2.840.113549.1.1.4";
-        private static final String OID_SIG_SHA1_WITH_RSA = "1.2.840.113549.1.1.5";
-        private static final String OID_SIG_SHA224_WITH_RSA = "1.2.840.113549.1.1.14";
-        private static final String OID_SIG_SHA256_WITH_RSA = "1.2.840.113549.1.1.11";
-        private static final String OID_SIG_SHA384_WITH_RSA = "1.2.840.113549.1.1.12";
-        private static final String OID_SIG_SHA512_WITH_RSA = "1.2.840.113549.1.1.13";
-
-        private static final String OID_SIG_DSA = "1.2.840.10040.4.1";
-        private static final String OID_SIG_SHA1_WITH_DSA = "1.2.840.10040.4.3";
-        private static final String OID_SIG_SHA224_WITH_DSA = "2.16.840.1.101.3.4.3.1";
-        private static final String OID_SIG_SHA256_WITH_DSA = "2.16.840.1.101.3.4.3.2";
-
-        private static final String OID_SIG_SHA1_WITH_ECDSA = "1.2.840.10045.4.1";
-        private static final String OID_SIG_SHA224_WITH_ECDSA = "1.2.840.10045.4.3.1";
-        private static final String OID_SIG_SHA256_WITH_ECDSA = "1.2.840.10045.4.3.2";
-        private static final String OID_SIG_SHA384_WITH_ECDSA = "1.2.840.10045.4.3.3";
-        private static final String OID_SIG_SHA512_WITH_ECDSA = "1.2.840.10045.4.3.4";
-
-        private static final Map<String, List<InclusiveIntRange>> SUPPORTED_SIG_ALG_OIDS =
-                new HashMap<>();
-        {
-            addSupportedSigAlg(
-                    OID_DIGEST_MD5, OID_SIG_RSA,
-                    InclusiveIntRange.from(0));
-            addSupportedSigAlg(
-                    OID_DIGEST_MD5, OID_SIG_MD5_WITH_RSA,
-                    InclusiveIntRange.fromTo(0, 8), InclusiveIntRange.from(21));
-            addSupportedSigAlg(
-                    OID_DIGEST_MD5, OID_SIG_SHA1_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_MD5, OID_SIG_SHA224_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_MD5, OID_SIG_SHA256_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_MD5, OID_SIG_SHA384_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_MD5, OID_SIG_SHA512_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_RSA,
-                    InclusiveIntRange.from(0));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_MD5_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_SHA1_WITH_RSA,
-                    InclusiveIntRange.from(0));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_SHA224_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_SHA256_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_SHA384_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_SHA512_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_RSA,
-                    InclusiveIntRange.fromTo(0, 8), InclusiveIntRange.from(21));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_MD5_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_SHA1_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_SHA224_WITH_RSA,
-                    InclusiveIntRange.fromTo(0, 8), InclusiveIntRange.from(21));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_SHA256_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 21));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_SHA384_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_SHA512_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_RSA,
-                    InclusiveIntRange.fromTo(0, 8), InclusiveIntRange.from(18));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_MD5_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_SHA1_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 21));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_SHA224_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_SHA256_WITH_RSA,
-                    InclusiveIntRange.fromTo(0, 8), InclusiveIntRange.from(18));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_SHA384_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_SHA512_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA384, OID_SIG_RSA,
-                    InclusiveIntRange.from(18));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA384, OID_SIG_MD5_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA384, OID_SIG_SHA1_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA384, OID_SIG_SHA224_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA384, OID_SIG_SHA256_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA384, OID_SIG_SHA384_WITH_RSA,
-                    InclusiveIntRange.from(21));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA384, OID_SIG_SHA512_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA512, OID_SIG_RSA,
-                    InclusiveIntRange.from(18));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA512, OID_SIG_MD5_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA512, OID_SIG_SHA1_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA512, OID_SIG_SHA224_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA512, OID_SIG_SHA256_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA512, OID_SIG_SHA384_WITH_RSA,
-                    InclusiveIntRange.fromTo(21, 21));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA512, OID_SIG_SHA512_WITH_RSA,
-                    InclusiveIntRange.from(21));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_MD5, OID_SIG_SHA1_WITH_DSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_MD5, OID_SIG_SHA224_WITH_DSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_MD5, OID_SIG_SHA256_WITH_DSA,
-                    InclusiveIntRange.fromTo(21, 23));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_DSA,
-                    InclusiveIntRange.from(0));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_SHA1_WITH_DSA,
-                    InclusiveIntRange.from(9));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_SHA224_WITH_DSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_SHA256_WITH_DSA,
-                    InclusiveIntRange.fromTo(21, 23));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_DSA,
-                    InclusiveIntRange.from(22));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_SHA1_WITH_DSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_SHA224_WITH_DSA,
-                    InclusiveIntRange.from(21));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_SHA256_WITH_DSA,
-                    InclusiveIntRange.fromTo(21, 23));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_DSA,
-                    InclusiveIntRange.from(22));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_SHA1_WITH_DSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_SHA224_WITH_DSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_SHA256_WITH_DSA,
-                    InclusiveIntRange.from(21));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA384, OID_SIG_SHA1_WITH_DSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA384, OID_SIG_SHA224_WITH_DSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA384, OID_SIG_SHA256_WITH_DSA,
-                    InclusiveIntRange.fromTo(21, 23));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA512, OID_SIG_SHA1_WITH_DSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA512, OID_SIG_SHA224_WITH_DSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA512, OID_SIG_SHA256_WITH_DSA,
-                    InclusiveIntRange.fromTo(21, 23));
-
-
-            addSupportedSigAlg(
-                    OID_DIGEST_MD5, OID_SIG_SHA1_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_MD5, OID_SIG_SHA224_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_MD5, OID_SIG_SHA256_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_MD5, OID_SIG_SHA384_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_MD5, OID_SIG_SHA512_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_SHA1_WITH_ECDSA,
-                    InclusiveIntRange.from(18));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_SHA224_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_SHA256_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_SHA384_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA1, OID_SIG_SHA512_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_SHA1_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_SHA224_WITH_ECDSA,
-                    InclusiveIntRange.from(21));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_SHA256_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_SHA384_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA224, OID_SIG_SHA512_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_SHA1_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_SHA224_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_SHA256_WITH_ECDSA,
-                    InclusiveIntRange.from(21));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_SHA384_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA256, OID_SIG_SHA512_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA384, OID_SIG_SHA1_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA384, OID_SIG_SHA224_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA384, OID_SIG_SHA256_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA384, OID_SIG_SHA384_WITH_ECDSA,
-                    InclusiveIntRange.from(21));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA384, OID_SIG_SHA512_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA512, OID_SIG_SHA1_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA512, OID_SIG_SHA224_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA512, OID_SIG_SHA256_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA512, OID_SIG_SHA384_WITH_ECDSA,
-                    InclusiveIntRange.fromTo(21, 23));
-            addSupportedSigAlg(
-                    OID_DIGEST_SHA512, OID_SIG_SHA512_WITH_ECDSA,
-                    InclusiveIntRange.from(21));
-        }
-
-        private static void addSupportedSigAlg(
-                String digestAlgorithmOid,
-                String signatureAlgorithmOid,
-                InclusiveIntRange... supportedApiLevels) {
-            SUPPORTED_SIG_ALG_OIDS.put(
-                    digestAlgorithmOid + "with" + signatureAlgorithmOid,
-                    Arrays.asList(supportedApiLevels));
-        }
-
-        private List<InclusiveIntRange> getSigAlgSupportedApiLevels(
-                String digestAlgorithmOid,
-                String signatureAlgorithmOid) {
-            List<InclusiveIntRange> result =
-                    SUPPORTED_SIG_ALG_OIDS.get(digestAlgorithmOid + "with" + signatureAlgorithmOid);
-            return (result != null) ? result : Collections.emptyList();
-        }
-
-        public void verifySigFileAgainstManifest(
-                byte[] manifestBytes,
-                ManifestParser.Section manifestMainSection,
-                Map<String, ManifestParser.Section> entryNameToManifestSection,
-                Map<Integer, String> supportedApkSigSchemeNames,
-                Set<Integer> foundApkSigSchemeIds,
-                int minSdkVersion,
-                int maxSdkVersion) throws NoSuchAlgorithmException {
-            // Inspect the main section of the .SF file.
-            ManifestParser sf = new ManifestParser(mSigFileBytes);
-            ManifestParser.Section sfMainSection = sf.readSection();
-            if (sfMainSection.getAttributeValue(Attributes.Name.SIGNATURE_VERSION) == null) {
-                mResult.addError(
-                        Issue.JAR_SIG_MISSING_VERSION_ATTR_IN_SIG_FILE,
-                        mSignatureFileEntry.getName());
-                setIgnored();
-                return;
-            }
-
-            if (maxSdkVersion >= AndroidSdkVersion.N) {
-                // Android N and newer rejects APKs whose .SF file says they were supposed to be
-                // signed with APK Signature Scheme v2 (or newer) and yet no such signature was
-                // found.
-                checkForStrippedApkSignatures(
-                        sfMainSection, supportedApkSigSchemeNames, foundApkSigSchemeIds);
-                if (mResult.containsErrors()) {
-                    return;
-                }
-            }
-
-            boolean createdBySigntool = false;
-            String createdBy = sfMainSection.getAttributeValue("Created-By");
-            if (createdBy != null) {
-                createdBySigntool = createdBy.indexOf("signtool") != -1;
-            }
-            boolean manifestDigestVerified =
-                    verifyManifestDigest(
-                            sfMainSection,
-                            createdBySigntool,
-                            manifestBytes,
-                            minSdkVersion,
-                            maxSdkVersion);
-            if (!createdBySigntool) {
-                verifyManifestMainSectionDigest(
-                        sfMainSection,
-                        manifestMainSection,
-                        manifestBytes,
-                        minSdkVersion,
-                        maxSdkVersion);
-            }
-            if (mResult.containsErrors()) {
-                return;
-            }
-
-            // Inspect per-entry sections of .SF file. Technically, if the digest of JAR manifest
-            // verifies, per-entry sections should be ignored. However, most Android platform
-            // implementations require that such sections exist.
-            List<ManifestParser.Section> sfSections = sf.readAllSections();
-            Set<String> sfEntryNames = new HashSet<>(sfSections.size());
-            int sfSectionNumber = 0;
-            for (ManifestParser.Section sfSection : sfSections) {
-                sfSectionNumber++;
-                String entryName = sfSection.getName();
-                if (entryName == null) {
-                    mResult.addError(
-                            Issue.JAR_SIG_UNNNAMED_SIG_FILE_SECTION,
-                            mSignatureFileEntry.getName(),
-                            sfSectionNumber);
-                    setIgnored();
-                    return;
-                }
-                if (!sfEntryNames.add(entryName)) {
-                    mResult.addError(
-                            Issue.JAR_SIG_DUPLICATE_SIG_FILE_SECTION,
-                            mSignatureFileEntry.getName(),
-                            entryName);
-                    setIgnored();
-                    return;
-                }
-                if (manifestDigestVerified) {
-                    // No need to verify this entry's corresponding JAR manifest entry because the
-                    // JAR manifest verifies in full.
-                    continue;
-                }
-                // Whole-file digest of JAR manifest hasn't been verified. Thus, we need to verify
-                // the digest of the JAR manifest section corresponding to this .SF section.
-                ManifestParser.Section manifestSection = entryNameToManifestSection.get(entryName);
-                if (manifestSection == null) {
-                    mResult.addError(
-                            Issue.JAR_SIG_NO_ZIP_ENTRY_DIGEST_IN_SIG_FILE,
-                            entryName,
-                            mSignatureFileEntry.getName());
-                    setIgnored();
-                    continue;
-                }
-                verifyManifestIndividualSectionDigest(
-                        sfSection,
-                        createdBySigntool,
-                        manifestSection,
-                        manifestBytes,
-                        minSdkVersion,
-                        maxSdkVersion);
-            }
-            mSigFileEntryNames = sfEntryNames;
-        }
-
-
-        /**
-         * Returns {@code true} if the whole-file digest of the manifest against the main section of
-         * the .SF file.
-         */
-        private boolean verifyManifestDigest(
-                ManifestParser.Section sfMainSection,
-                boolean createdBySigntool,
-                byte[] manifestBytes,
-                int minSdkVersion,
-                int maxSdkVersion) throws NoSuchAlgorithmException {
-            Collection<NamedDigest> expectedDigests =
-                    getDigestsToVerify(
-                            sfMainSection,
-                            ((createdBySigntool) ? "-Digest" : "-Digest-Manifest"),
-                            minSdkVersion,
-                            maxSdkVersion);
-            boolean digestFound = !expectedDigests.isEmpty();
-            if (!digestFound) {
-                mResult.addWarning(
-                        Issue.JAR_SIG_NO_MANIFEST_DIGEST_IN_SIG_FILE,
-                        mSignatureFileEntry.getName());
-                return false;
-            }
-
-            boolean verified = true;
-            for (NamedDigest expectedDigest : expectedDigests) {
-                String jcaDigestAlgorithm = expectedDigest.jcaDigestAlgorithm;
-                byte[] actual = digest(jcaDigestAlgorithm, manifestBytes);
-                byte[] expected = expectedDigest.digest;
-                if (!Arrays.equals(expected, actual)) {
-                    mResult.addWarning(
-                            Issue.JAR_SIG_ZIP_ENTRY_DIGEST_DID_NOT_VERIFY,
-                            V1SchemeSigner.MANIFEST_ENTRY_NAME,
-                            jcaDigestAlgorithm,
-                            mSignatureFileEntry.getName(),
-                            Base64.getEncoder().encodeToString(actual),
-                            Base64.getEncoder().encodeToString(expected));
-                    verified = false;
-                }
-            }
-            return verified;
-        }
-
-        /**
-         * Verifies the digest of the manifest's main section against the main section of the .SF
-         * file.
-         */
-        private void verifyManifestMainSectionDigest(
-                ManifestParser.Section sfMainSection,
-                ManifestParser.Section manifestMainSection,
-                byte[] manifestBytes,
-                int minSdkVersion,
-                int maxSdkVersion) throws NoSuchAlgorithmException {
-            Collection<NamedDigest> expectedDigests =
-                    getDigestsToVerify(
-                            sfMainSection,
-                            "-Digest-Manifest-Main-Attributes",
-                            minSdkVersion,
-                            maxSdkVersion);
-            if (expectedDigests.isEmpty()) {
-                return;
-            }
-
-            for (NamedDigest expectedDigest : expectedDigests) {
-                String jcaDigestAlgorithm = expectedDigest.jcaDigestAlgorithm;
-                byte[] actual =
-                        digest(
-                                jcaDigestAlgorithm,
-                                manifestBytes,
-                                manifestMainSection.getStartOffset(),
-                                manifestMainSection.getSizeBytes());
-                byte[] expected = expectedDigest.digest;
-                if (!Arrays.equals(expected, actual)) {
-                    mResult.addError(
-                            Issue.JAR_SIG_MANIFEST_MAIN_SECTION_DIGEST_DID_NOT_VERIFY,
-                            jcaDigestAlgorithm,
-                            mSignatureFileEntry.getName(),
-                            Base64.getEncoder().encodeToString(actual),
-                            Base64.getEncoder().encodeToString(expected));
-                }
-            }
-        }
-
-        /**
-         * Verifies the digest of the manifest's individual section against the corresponding
-         * individual section of the .SF file.
-         */
-        private void verifyManifestIndividualSectionDigest(
-                ManifestParser.Section sfIndividualSection,
-                boolean createdBySigntool,
-                ManifestParser.Section manifestIndividualSection,
-                byte[] manifestBytes,
-                int minSdkVersion,
-                int maxSdkVersion) throws NoSuchAlgorithmException {
-            String entryName = sfIndividualSection.getName();
-            Collection<NamedDigest> expectedDigests =
-                    getDigestsToVerify(
-                            sfIndividualSection, "-Digest", minSdkVersion, maxSdkVersion);
-            if (expectedDigests.isEmpty()) {
-                mResult.addError(
-                        Issue.JAR_SIG_NO_ZIP_ENTRY_DIGEST_IN_SIG_FILE,
-                        entryName,
-                        mSignatureFileEntry.getName());
-                return;
-            }
-
-            int sectionStartIndex = manifestIndividualSection.getStartOffset();
-            int sectionSizeBytes = manifestIndividualSection.getSizeBytes();
-            if (createdBySigntool) {
-                int sectionEndIndex = sectionStartIndex + sectionSizeBytes;
-                if ((manifestBytes[sectionEndIndex - 1] == '\n')
-                        && (manifestBytes[sectionEndIndex - 2] == '\n')) {
-                    sectionSizeBytes--;
-                }
-            }
-            for (NamedDigest expectedDigest : expectedDigests) {
-                String jcaDigestAlgorithm = expectedDigest.jcaDigestAlgorithm;
-                byte[] actual =
-                        digest(
-                                jcaDigestAlgorithm,
-                                manifestBytes,
-                                sectionStartIndex,
-                                sectionSizeBytes);
-                byte[] expected = expectedDigest.digest;
-                if (!Arrays.equals(expected, actual)) {
-                    mResult.addError(
-                            Issue.JAR_SIG_MANIFEST_SECTION_DIGEST_DID_NOT_VERIFY,
-                            entryName,
-                            jcaDigestAlgorithm,
-                            mSignatureFileEntry.getName(),
-                            Base64.getEncoder().encodeToString(actual),
-                            Base64.getEncoder().encodeToString(expected));
-                }
-            }
-        }
-
-        private void checkForStrippedApkSignatures(
-                ManifestParser.Section sfMainSection,
-                Map<Integer, String> supportedApkSigSchemeNames,
-                Set<Integer> foundApkSigSchemeIds) {
-            String signedWithApkSchemes =
-                    sfMainSection.getAttributeValue(
-                            V1SchemeSigner.SF_ATTRIBUTE_NAME_ANDROID_APK_SIGNED_NAME_STR);
-            // This field contains a comma-separated list of APK signature scheme IDs which were
-            // used to sign this APK. Android rejects APKs where an ID is known to the platform but
-            // the APK didn't verify using that scheme.
-
-            if (signedWithApkSchemes == null) {
-                // APK signature (e.g., v2 scheme) stripping protections not enabled.
-                if (!foundApkSigSchemeIds.isEmpty()) {
-                    // APK is signed with an APK signature scheme such as v2 scheme.
-                    mResult.addWarning(
-                            Issue.JAR_SIG_NO_APK_SIG_STRIP_PROTECTION,
-                            mSignatureFileEntry.getName());
-                }
-                return;
-            }
-
-            if (supportedApkSigSchemeNames.isEmpty()) {
-                return;
-            }
-
-            Set<Integer> supportedApkSigSchemeIds = supportedApkSigSchemeNames.keySet();
-            Set<Integer> supportedExpectedApkSigSchemeIds = new HashSet<>(1);
-            StringTokenizer tokenizer = new StringTokenizer(signedWithApkSchemes, ",");
-            while (tokenizer.hasMoreTokens()) {
-                String idText = tokenizer.nextToken().trim();
-                if (idText.isEmpty()) {
-                    continue;
-                }
-                int id;
-                try {
-                    id = Integer.parseInt(idText);
-                } catch (Exception ignored) {
-                    continue;
-                }
-                // This APK was supposed to be signed with the APK signature scheme having
-                // this ID.
-                if (supportedApkSigSchemeIds.contains(id)) {
-                    supportedExpectedApkSigSchemeIds.add(id);
-                } else {
-                    mResult.addWarning(
-                            Issue.JAR_SIG_UNKNOWN_APK_SIG_SCHEME_ID,
-                            mSignatureFileEntry.getName(),
-                            id);
-                }
-            }
-
-            for (int id : supportedExpectedApkSigSchemeIds) {
-                if (!foundApkSigSchemeIds.contains(id)) {
-                    String apkSigSchemeName = supportedApkSigSchemeNames.get(id);
-                    mResult.addError(
-                            Issue.JAR_SIG_MISSING_APK_SIG_REFERENCED,
-                            mSignatureFileEntry.getName(),
-                            id,
-                            apkSigSchemeName);
-                }
-            }
-        }
-    }
-
-    private static Collection<NamedDigest> getDigestsToVerify(
-            ManifestParser.Section section,
-            String digestAttrSuffix,
-            int minSdkVersion,
-            int maxSdkVersion) {
-        Decoder base64Decoder = Base64.getDecoder();
-        List<NamedDigest> result = new ArrayList<>(1);
-        if (minSdkVersion < AndroidSdkVersion.JELLY_BEAN_MR2) {
-            // Prior to JB MR2, Android platform's logic for picking a digest algorithm to verify is
-            // to rely on the ancient Digest-Algorithms attribute which contains
-            // whitespace-separated list of digest algorithms (defaulting to SHA-1) to try. The
-            // first digest attribute (with supported digest algorithm) found using the list is
-            // used.
-            String algs = section.getAttributeValue("Digest-Algorithms");
-            if (algs == null) {
-                algs = "SHA SHA1";
-            }
-            StringTokenizer tokens = new StringTokenizer(algs);
-            while (tokens.hasMoreTokens()) {
-                String alg = tokens.nextToken();
-                String attrName = alg + digestAttrSuffix;
-                String digestBase64 = section.getAttributeValue(attrName);
-                if (digestBase64 == null) {
-                    // Attribute not found
-                    continue;
-                }
-                alg = getCanonicalJcaMessageDigestAlgorithm(alg);
-                if ((alg == null)
-                        || (getMinSdkVersionFromWhichSupportedInManifestOrSignatureFile(alg)
-                                > minSdkVersion)) {
-                    // Unsupported digest algorithm
-                    continue;
-                }
-                // Supported digest algorithm
-                result.add(new NamedDigest(alg, base64Decoder.decode(digestBase64)));
-                break;
-            }
-            // No supported digests found -- this will fail to verify on pre-JB MR2 Androids.
-            if (result.isEmpty()) {
-                return result;
-            }
-        }
-
-        if (maxSdkVersion >= AndroidSdkVersion.JELLY_BEAN_MR2) {
-            // On JB MR2 and newer, Android platform picks the strongest algorithm out of:
-            // SHA-512, SHA-384, SHA-256, SHA-1.
-            for (String alg : JB_MR2_AND_NEWER_DIGEST_ALGS) {
-                String attrName = getJarDigestAttributeName(alg, digestAttrSuffix);
-                String digestBase64 = section.getAttributeValue(attrName);
-                if (digestBase64 == null) {
-                    // Attribute not found
-                    continue;
-                }
-                byte[] digest = base64Decoder.decode(digestBase64);
-                byte[] digestInResult = getDigest(result, alg);
-                if ((digestInResult == null) || (!Arrays.equals(digestInResult, digest))) {
-                    result.add(new NamedDigest(alg, digest));
-                }
-                break;
-            }
-        }
-
-        return result;
-    }
-
-    private static String[] JB_MR2_AND_NEWER_DIGEST_ALGS = {
-            "SHA-512",
-            "SHA-384",
-            "SHA-256",
-            "SHA-1",
-    };
-
-    private static String getCanonicalJcaMessageDigestAlgorithm(String algorithm) {
-        return UPPER_CASE_JCA_DIGEST_ALG_TO_CANONICAL.get(algorithm.toUpperCase(Locale.US));
-    }
-
-    public static int getMinSdkVersionFromWhichSupportedInManifestOrSignatureFile(
-            String jcaAlgorithmName) {
-        Integer result =
-                MIN_SDK_VESION_FROM_WHICH_DIGEST_SUPPORTED_IN_MANIFEST.get(
-                        jcaAlgorithmName.toUpperCase(Locale.US));
-        return (result != null) ? result : Integer.MAX_VALUE;
-    }
-
-    private static String getJarDigestAttributeName(
-            String jcaDigestAlgorithm, String attrNameSuffix) {
-        if ("SHA-1".equalsIgnoreCase(jcaDigestAlgorithm)) {
-            return "SHA1" + attrNameSuffix;
-        } else {
-            return jcaDigestAlgorithm + attrNameSuffix;
-        }
-    }
-
-    private static Map<String, String> UPPER_CASE_JCA_DIGEST_ALG_TO_CANONICAL;
-    static {
-        UPPER_CASE_JCA_DIGEST_ALG_TO_CANONICAL = new HashMap<>(8);
-        UPPER_CASE_JCA_DIGEST_ALG_TO_CANONICAL.put("MD5", "MD5");
-        UPPER_CASE_JCA_DIGEST_ALG_TO_CANONICAL.put("SHA", "SHA-1");
-        UPPER_CASE_JCA_DIGEST_ALG_TO_CANONICAL.put("SHA1", "SHA-1");
-        UPPER_CASE_JCA_DIGEST_ALG_TO_CANONICAL.put("SHA-1", "SHA-1");
-        UPPER_CASE_JCA_DIGEST_ALG_TO_CANONICAL.put("SHA-256", "SHA-256");
-        UPPER_CASE_JCA_DIGEST_ALG_TO_CANONICAL.put("SHA-384", "SHA-384");
-        UPPER_CASE_JCA_DIGEST_ALG_TO_CANONICAL.put("SHA-512", "SHA-512");
-    }
-
-    private static Map<String, Integer> MIN_SDK_VESION_FROM_WHICH_DIGEST_SUPPORTED_IN_MANIFEST;
-    static {
-        MIN_SDK_VESION_FROM_WHICH_DIGEST_SUPPORTED_IN_MANIFEST = new HashMap<>(5);
-        MIN_SDK_VESION_FROM_WHICH_DIGEST_SUPPORTED_IN_MANIFEST.put("MD5", 0);
-        MIN_SDK_VESION_FROM_WHICH_DIGEST_SUPPORTED_IN_MANIFEST.put("SHA-1", 0);
-        MIN_SDK_VESION_FROM_WHICH_DIGEST_SUPPORTED_IN_MANIFEST.put("SHA-256", 0);
-        MIN_SDK_VESION_FROM_WHICH_DIGEST_SUPPORTED_IN_MANIFEST.put(
-                "SHA-384", AndroidSdkVersion.GINGERBREAD);
-        MIN_SDK_VESION_FROM_WHICH_DIGEST_SUPPORTED_IN_MANIFEST.put(
-                "SHA-512", AndroidSdkVersion.GINGERBREAD);
-    }
-
-    private static byte[] getDigest(Collection<NamedDigest> digests, String jcaDigestAlgorithm) {
-        for (NamedDigest digest : digests) {
-            if (digest.jcaDigestAlgorithm.equalsIgnoreCase(jcaDigestAlgorithm)) {
-                return digest.digest;
-            }
-        }
-        return null;
-    }
-
-    private static List<CentralDirectoryRecord> parseZipCentralDirectory(
-            DataSource apk,
-            ApkUtils.ZipSections apkSections)
-                    throws IOException, ZipFormatException {
-        // Read the ZIP Central Directory
-        long cdSizeBytes = apkSections.getZipCentralDirectorySizeBytes();
-        if (cdSizeBytes > Integer.MAX_VALUE) {
-            throw new ZipFormatException("ZIP Central Directory too large: " + cdSizeBytes);
-        }
-        long cdOffset = apkSections.getZipCentralDirectoryOffset();
-        ByteBuffer cd = apk.getByteBuffer(cdOffset, (int) cdSizeBytes);
-        cd.order(ByteOrder.LITTLE_ENDIAN);
-
-        // Parse the ZIP Central Directory
-        int expectedCdRecordCount = apkSections.getZipCentralDirectoryRecordCount();
-        List<CentralDirectoryRecord> cdRecords = new ArrayList<>(expectedCdRecordCount);
-        for (int i = 0; i < expectedCdRecordCount; i++) {
-            CentralDirectoryRecord cdRecord;
-            int offsetInsideCd = cd.position();
-            try {
-                cdRecord = CentralDirectoryRecord.getRecord(cd);
-            } catch (ZipFormatException e) {
-                throw new ZipFormatException(
-                        "Failed to parse Central Directory record #" + (i + 1)
-                                + " at file offset " + (cdOffset + offsetInsideCd),
-                        e);
-            }
-            String entryName = cdRecord.getName();
-            if (entryName.endsWith("/")) {
-                // Ignore directory entries
-                continue;
-            }
-            cdRecords.add(cdRecord);
-        }
-        // There may be more data in Central Directory, but we don't warn or throw because Android
-        // ignores unused CD data.
-
-        return cdRecords;
-    }
-
-    /**
-     * Returns {@code true} if the provided JAR entry must be mentioned in signed JAR archive's
-     * manifest for the APK to verify on Android.
-     */
-    private static boolean isJarEntryDigestNeededInManifest(String entryName) {
-        // NOTE: This logic is different from what's required by the JAR signing scheme. This is
-        // because Android's APK verification logic differs from that spec. In particular, JAR
-        // signing spec includes into JAR manifest all files in subdirectories of META-INF and
-        // any files inside META-INF not related to signatures.
-        if (entryName.startsWith("META-INF/")) {
-            return false;
-        }
-        return !entryName.endsWith("/");
-    }
-
-    private static Set<Signer> verifyJarEntriesAgainstManifestAndSigners(
-            DataSource apk,
-            long cdOffsetInApk,
-            Collection<CentralDirectoryRecord> cdRecords,
-            Map<String, ManifestParser.Section> entryNameToManifestSection,
-            List<Signer> signers,
-            int minSdkVersion,
-            int maxSdkVersion,
-            Result result) throws ZipFormatException, IOException, NoSuchAlgorithmException {
-        // Iterate over APK contents as sequentially as possible to improve performance.
-        List<CentralDirectoryRecord> cdRecordsSortedByLocalFileHeaderOffset =
-                new ArrayList<>(cdRecords);
-        Collections.sort(
-                cdRecordsSortedByLocalFileHeaderOffset,
-                CentralDirectoryRecord.BY_LOCAL_FILE_HEADER_OFFSET_COMPARATOR);
-        Set<String> manifestEntryNamesMissingFromApk =
-                new HashSet<>(entryNameToManifestSection.keySet());
-        List<Signer> firstSignedEntrySigners = null;
-        String firstSignedEntryName = null;
-        for (CentralDirectoryRecord cdRecord : cdRecordsSortedByLocalFileHeaderOffset) {
-            String entryName = cdRecord.getName();
-            manifestEntryNamesMissingFromApk.remove(entryName);
-            if (!isJarEntryDigestNeededInManifest(entryName)) {
-                continue;
-            }
-
-            ManifestParser.Section manifestSection = entryNameToManifestSection.get(entryName);
-            if (manifestSection == null) {
-                result.addError(Issue.JAR_SIG_NO_ZIP_ENTRY_DIGEST_IN_MANIFEST, entryName);
-                continue;
-            }
-
-            List<Signer> entrySigners = new ArrayList<>(signers.size());
-            for (Signer signer : signers) {
-                if (signer.getSigFileEntryNames().contains(entryName)) {
-                    entrySigners.add(signer);
-                }
-            }
-            if (entrySigners.isEmpty()) {
-                result.addError(Issue.JAR_SIG_ZIP_ENTRY_NOT_SIGNED, entryName);
-                continue;
-            }
-            if (firstSignedEntrySigners == null) {
-                firstSignedEntrySigners = entrySigners;
-                firstSignedEntryName = entryName;
-            } else if (!entrySigners.equals(firstSignedEntrySigners)) {
-                result.addError(
-                        Issue.JAR_SIG_ZIP_ENTRY_SIGNERS_MISMATCH,
-                        firstSignedEntryName,
-                        getSignerNames(firstSignedEntrySigners),
-                        entryName,
-                        getSignerNames(entrySigners));
-                continue;
-            }
-
-            Collection<NamedDigest> expectedDigests =
-                    getDigestsToVerify(manifestSection, "-Digest", minSdkVersion, maxSdkVersion);
-            if (expectedDigests.isEmpty()) {
-                result.addError(Issue.JAR_SIG_NO_ZIP_ENTRY_DIGEST_IN_MANIFEST, entryName);
-                continue;
-            }
-
-            MessageDigest[] mds = new MessageDigest[expectedDigests.size()];
-            int mdIndex = 0;
-            for (NamedDigest expectedDigest : expectedDigests) {
-                mds[mdIndex] = getMessageDigest(expectedDigest.jcaDigestAlgorithm);
-                mdIndex++;
-            }
-
-            try {
-                LocalFileRecord.outputUncompressedData(
-                        apk,
-                        cdRecord,
-                        cdOffsetInApk,
-                        new MessageDigestSink(mds));
-            } catch (ZipFormatException e) {
-                throw new ZipFormatException("Malformed entry: " + entryName, e);
-            } catch (IOException e) {
-                throw new IOException("Failed to read entry: " + entryName, e);
-            }
-
-            mdIndex = 0;
-            for (NamedDigest expectedDigest : expectedDigests) {
-                byte[] actualDigest = mds[mdIndex].digest();
-                if (!Arrays.equals(expectedDigest.digest, actualDigest)) {
-                    result.addError(
-                            Issue.JAR_SIG_ZIP_ENTRY_DIGEST_DID_NOT_VERIFY,
-                            entryName,
-                            expectedDigest.jcaDigestAlgorithm,
-                            V1SchemeSigner.MANIFEST_ENTRY_NAME,
-                            Base64.getEncoder().encodeToString(actualDigest),
-                            Base64.getEncoder().encodeToString(expectedDigest.digest));
-                }
-            }
-        }
-
-        if (firstSignedEntrySigners == null) {
-            result.addError(Issue.JAR_SIG_NO_SIGNED_ZIP_ENTRIES);
-            return Collections.emptySet();
-        } else {
-            return new HashSet<>(firstSignedEntrySigners);
-        }
-    }
-
-    private static List<String> getSignerNames(List<Signer> signers) {
-        if (signers.isEmpty()) {
-            return Collections.emptyList();
-        }
-        List<String> result = new ArrayList<>(signers.size());
-        for (Signer signer : signers) {
-            result.add(signer.getName());
-        }
-        return result;
-    }
-
-    private static MessageDigest getMessageDigest(String algorithm)
-            throws NoSuchAlgorithmException {
-        return MessageDigest.getInstance(algorithm);
-    }
-
-    private static byte[] digest(String algorithm, byte[] data, int offset, int length)
-            throws NoSuchAlgorithmException {
-        MessageDigest md = getMessageDigest(algorithm);
-        md.update(data, offset, length);
-        return md.digest();
-    }
-
-    private static byte[] digest(String algorithm, byte[] data) throws NoSuchAlgorithmException {
-        return getMessageDigest(algorithm).digest(data);
-    }
-
-    private static class NamedDigest {
-        private final String jcaDigestAlgorithm;
-        private final byte[] digest;
-
-        private NamedDigest(String jcaDigestAlgorithm, byte[] digest) {
-            this.jcaDigestAlgorithm = jcaDigestAlgorithm;
-            this.digest = digest;
-        }
-    }
-
-    public static class Result {
-
-        /** Whether the APK's JAR signature verifies. */
-        public boolean verified;
-
-        /** List of APK's signers. These signers are used by Android. */
-        public final List<SignerInfo> signers = new ArrayList<>();
-
-        /**
-         * Signers encountered in the APK but not included in the set of the APK's signers. These
-         * signers are ignored by Android.
-         */
-        public final List<SignerInfo> ignoredSigners = new ArrayList<>();
-
-        private final List<IssueWithParams> mWarnings = new ArrayList<>();
-        private final List<IssueWithParams> mErrors = new ArrayList<>();
-
-        private boolean containsErrors() {
-            if (!mErrors.isEmpty()) {
-                return true;
-            }
-            for (SignerInfo signer : signers) {
-                if (signer.containsErrors()) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        private void addError(Issue msg, Object... parameters) {
-            mErrors.add(new IssueWithParams(msg, parameters));
-        }
-
-        private void addWarning(Issue msg, Object... parameters) {
-            mWarnings.add(new IssueWithParams(msg, parameters));
-        }
-
-        public List<IssueWithParams> getErrors() {
-            return mErrors;
-        }
-
-        public List<IssueWithParams> getWarnings() {
-            return mWarnings;
-        }
-
-        public static class SignerInfo {
-            public final String name;
-            public final String signatureFileName;
-            public final String signatureBlockFileName;
-            public final List<X509Certificate> certChain = new ArrayList<>();
-
-            private final List<IssueWithParams> mWarnings = new ArrayList<>();
-            private final List<IssueWithParams> mErrors = new ArrayList<>();
-
-            private SignerInfo(
-                    String name, String signatureBlockFileName, String signatureFileName) {
-                this.name = name;
-                this.signatureBlockFileName = signatureBlockFileName;
-                this.signatureFileName = signatureFileName;
-            }
-
-            private boolean containsErrors() {
-                return !mErrors.isEmpty();
-            }
-
-            private void addError(Issue msg, Object... parameters) {
-                mErrors.add(new IssueWithParams(msg, parameters));
-            }
-
-            private void addWarning(Issue msg, Object... parameters) {
-                mWarnings.add(new IssueWithParams(msg, parameters));
-            }
-
-            public List<IssueWithParams> getErrors() {
-                return mErrors;
-            }
-
-            public List<IssueWithParams> getWarnings() {
-                return mWarnings;
-            }
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/ContentDigestAlgorithm.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/ContentDigestAlgorithm.java
deleted file mode 100644
index 7c136be..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/ContentDigestAlgorithm.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.apk.v2;
-
-/**
- * APK Signature Scheme v2 content digest algorithm.
- */
-public enum ContentDigestAlgorithm {
-    /** SHA2-256 over 1 MB chunks. */
-    CHUNKED_SHA256("SHA-256", 256 / 8),
-
-    /** SHA2-512 over 1 MB chunks. */
-    CHUNKED_SHA512("SHA-512", 512 / 8);
-
-    private final String mJcaMessageDigestAlgorithm;
-    private final int mChunkDigestOutputSizeBytes;
-
-    private ContentDigestAlgorithm(
-            String jcaMessageDigestAlgorithm, int chunkDigestOutputSizeBytes) {
-        mJcaMessageDigestAlgorithm = jcaMessageDigestAlgorithm;
-        mChunkDigestOutputSizeBytes = chunkDigestOutputSizeBytes;
-    }
-
-    /**
-     * Returns the {@link java.security.MessageDigest} algorithm used for computing digests of
-     * chunks by this content digest algorithm.
-     */
-    String getJcaMessageDigestAlgorithm() {
-        return mJcaMessageDigestAlgorithm;
-    }
-
-    /**
-     * Returns the size (in bytes) of the digest of a chunk of content.
-     */
-    int getChunkDigestOutputSizeBytes() {
-        return mChunkDigestOutputSizeBytes;
-    }
-}
\ No newline at end of file
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/SignatureAlgorithm.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/SignatureAlgorithm.java
deleted file mode 100644
index 20f890d..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/SignatureAlgorithm.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.apk.v2;
-
-import com.android.apksigner.core.internal.util.Pair;
-
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.MGF1ParameterSpec;
-import java.security.spec.PSSParameterSpec;
-
-/**
- * APK Signature Scheme v2 signature algorithm.
- */
-public enum SignatureAlgorithm {
-    /**
-     * RSASSA-PSS with SHA2-256 digest, SHA2-256 MGF1, 32 bytes of salt, trailer: 0xbc, content
-     * digested using SHA2-256 in 1 MB chunks.
-     */
-    RSA_PSS_WITH_SHA256(
-            0x0101,
-            ContentDigestAlgorithm.CHUNKED_SHA256,
-            "RSA",
-            Pair.of("SHA256withRSA/PSS",
-                    new PSSParameterSpec(
-                            "SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 256 / 8, 1))),
-
-    /**
-     * RSASSA-PSS with SHA2-512 digest, SHA2-512 MGF1, 64 bytes of salt, trailer: 0xbc, content
-     * digested using SHA2-512 in 1 MB chunks.
-     */
-    RSA_PSS_WITH_SHA512(
-            0x0102,
-            ContentDigestAlgorithm.CHUNKED_SHA512,
-            "RSA",
-            Pair.of(
-                    "SHA512withRSA/PSS",
-                    new PSSParameterSpec(
-                            "SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 512 / 8, 1))),
-
-    /** RSASSA-PKCS1-v1_5 with SHA2-256 digest, content digested using SHA2-256 in 1 MB chunks. */
-    RSA_PKCS1_V1_5_WITH_SHA256(
-            0x0103,
-            ContentDigestAlgorithm.CHUNKED_SHA256,
-            "RSA",
-            Pair.of("SHA256withRSA", null)),
-
-    /** RSASSA-PKCS1-v1_5 with SHA2-512 digest, content digested using SHA2-512 in 1 MB chunks. */
-    RSA_PKCS1_V1_5_WITH_SHA512(
-            0x0104,
-            ContentDigestAlgorithm.CHUNKED_SHA512,
-            "RSA",
-            Pair.of("SHA512withRSA", null)),
-
-    /** ECDSA with SHA2-256 digest, content digested using SHA2-256 in 1 MB chunks. */
-    ECDSA_WITH_SHA256(
-            0x0201,
-            ContentDigestAlgorithm.CHUNKED_SHA256,
-            "EC",
-            Pair.of("SHA256withECDSA", null)),
-
-    /** ECDSA with SHA2-512 digest, content digested using SHA2-512 in 1 MB chunks. */
-    ECDSA_WITH_SHA512(
-            0x0202,
-            ContentDigestAlgorithm.CHUNKED_SHA512,
-            "EC",
-            Pair.of("SHA512withECDSA", null)),
-
-    /** DSA with SHA2-256 digest, content digested using SHA2-256 in 1 MB chunks. */
-    DSA_WITH_SHA256(
-            0x0301,
-            ContentDigestAlgorithm.CHUNKED_SHA256,
-            "DSA",
-            Pair.of("SHA256withDSA", null));
-
-    private final int mId;
-    private final String mJcaKeyAlgorithm;
-    private final ContentDigestAlgorithm mContentDigestAlgorithm;
-    private final Pair<String, ? extends AlgorithmParameterSpec> mJcaSignatureAlgAndParams;
-
-    private SignatureAlgorithm(int id,
-            ContentDigestAlgorithm contentDigestAlgorithm,
-            String jcaKeyAlgorithm,
-            Pair<String, ? extends AlgorithmParameterSpec> jcaSignatureAlgAndParams) {
-        mId = id;
-        mContentDigestAlgorithm = contentDigestAlgorithm;
-        mJcaKeyAlgorithm = jcaKeyAlgorithm;
-        mJcaSignatureAlgAndParams = jcaSignatureAlgAndParams;
-    }
-
-    /**
-     * Returns the ID of this signature algorithm as used in APK Signature Scheme v2 wire format.
-     */
-    int getId() {
-        return mId;
-    }
-
-    /**
-     * Returns the content digest algorithm associated with this signature algorithm.
-     */
-    ContentDigestAlgorithm getContentDigestAlgorithm() {
-        return mContentDigestAlgorithm;
-    }
-
-    /**
-     * Returns the JCA {@link java.security.Key} algorithm used by this signature scheme.
-     */
-    String getJcaKeyAlgorithm() {
-        return mJcaKeyAlgorithm;
-    }
-
-    /**
-     * Returns the {@link java.security.Signature} algorithm and the {@link AlgorithmParameterSpec}
-     * (or null if not needed) to parameterize the {@code Signature}.
-     */
-    Pair<String, ? extends AlgorithmParameterSpec> getJcaSignatureAlgorithmAndParams() {
-        return mJcaSignatureAlgAndParams;
-    }
-
-    static SignatureAlgorithm findById(int id) {
-        for (SignatureAlgorithm alg : SignatureAlgorithm.values()) {
-            if (alg.getId() == id) {
-                return alg;
-            }
-        }
-
-        return null;
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/V2SchemeSigner.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/V2SchemeSigner.java
deleted file mode 100644
index 06d31dd..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/V2SchemeSigner.java
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.apk.v2;
-
-import com.android.apksigner.core.internal.util.MessageDigestSink;
-import com.android.apksigner.core.internal.util.Pair;
-import com.android.apksigner.core.internal.zip.ZipUtils;
-import com.android.apksigner.core.util.DataSource;
-import com.android.apksigner.core.util.DataSources;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.security.DigestException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.ECKey;
-import java.security.interfaces.RSAKey;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * APK Signature Scheme v2 signer.
- *
- * <p>APK Signature Scheme v2 is a whole-file signature scheme which aims to protect every single
- * bit of the APK, as opposed to the JAR Signature Scheme which protects only the names and
- * uncompressed contents of ZIP entries.
- *
- * <p>TODO: Link to APK Signature Scheme v2 documentation once it's available.
- */
-public abstract class V2SchemeSigner {
-    /*
-     * The two main goals of APK Signature Scheme v2 are:
-     * 1. Detect any unauthorized modifications to the APK. This is achieved by making the signature
-     *    cover every byte of the APK being signed.
-     * 2. Enable much faster signature and integrity verification. This is achieved by requiring
-     *    only a minimal amount of APK parsing before the signature is verified, thus completely
-     *    bypassing ZIP entry decompression and by making integrity verification parallelizable by
-     *    employing a hash tree.
-     *
-     * The generated signature block is wrapped into an APK Signing Block and inserted into the
-     * original APK immediately before the start of ZIP Central Directory. This is to ensure that
-     * JAR and ZIP parsers continue to work on the signed APK. The APK Signing Block is designed for
-     * extensibility. For example, a future signature scheme could insert its signatures there as
-     * well. The contract of the APK Signing Block is that all contents outside of the block must be
-     * protected by signatures inside the block.
-     */
-
-    private static final int CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES = 1024 * 1024;
-
-    private static final byte[] APK_SIGNING_BLOCK_MAGIC =
-          new byte[] {
-              0x41, 0x50, 0x4b, 0x20, 0x53, 0x69, 0x67, 0x20,
-              0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x34, 0x32,
-          };
-    private static final int APK_SIGNATURE_SCHEME_V2_BLOCK_ID = 0x7109871a;
-
-    /**
-     * Signer configuration.
-     */
-    public static class SignerConfig {
-        /** Private key. */
-        public PrivateKey privateKey;
-
-        /**
-         * Certificates, with the first certificate containing the public key corresponding to
-         * {@link #privateKey}.
-         */
-        public List<X509Certificate> certificates;
-
-        /**
-         * List of signature algorithms with which to sign.
-         */
-        public List<SignatureAlgorithm> signatureAlgorithms;
-    }
-
-    /** Hidden constructor to prevent instantiation. */
-    private V2SchemeSigner() {}
-
-    /**
-     * Gets the APK Signature Scheme v2 signature algorithms to be used for signing an APK using the
-     * provided key.
-     *
-     * @param minSdkVersion minimum API Level of the platform on which the APK may be installed (see
-     *        AndroidManifest.xml minSdkVersion attribute).
-     *
-     * @throws InvalidKeyException if the provided key is not suitable for signing APKs using
-     *         APK Signature Scheme v2
-     */
-    public static List<SignatureAlgorithm> getSuggestedSignatureAlgorithms(
-            PublicKey signingKey, int minSdkVersion) throws InvalidKeyException {
-        String keyAlgorithm = signingKey.getAlgorithm();
-        if ("RSA".equalsIgnoreCase(keyAlgorithm)) {
-            // Use RSASSA-PKCS1-v1_5 signature scheme instead of RSASSA-PSS to guarantee
-            // deterministic signatures which make life easier for OTA updates (fewer files
-            // changed when deterministic signature schemes are used).
-
-            // Pick a digest which is no weaker than the key.
-            int modulusLengthBits = ((RSAKey) signingKey).getModulus().bitLength();
-            if (modulusLengthBits <= 3072) {
-                // 3072-bit RSA is roughly 128-bit strong, meaning SHA-256 is a good fit.
-                return Collections.singletonList(SignatureAlgorithm.RSA_PKCS1_V1_5_WITH_SHA256);
-            } else {
-                // Keys longer than 3072 bit need to be paired with a stronger digest to avoid the
-                // digest being the weak link. SHA-512 is the next strongest supported digest.
-                return Collections.singletonList(SignatureAlgorithm.RSA_PKCS1_V1_5_WITH_SHA512);
-            }
-        } else if ("DSA".equalsIgnoreCase(keyAlgorithm)) {
-            // DSA is supported only with SHA-256.
-            return Collections.singletonList(SignatureAlgorithm.DSA_WITH_SHA256);
-        } else if ("EC".equalsIgnoreCase(keyAlgorithm)) {
-            // Pick a digest which is no weaker than the key.
-            int keySizeBits = ((ECKey) signingKey).getParams().getOrder().bitLength();
-            if (keySizeBits <= 256) {
-                // 256-bit Elliptic Curve is roughly 128-bit strong, meaning SHA-256 is a good fit.
-                return Collections.singletonList(SignatureAlgorithm.ECDSA_WITH_SHA256);
-            } else {
-                // Keys longer than 256 bit need to be paired with a stronger digest to avoid the
-                // digest being the weak link. SHA-512 is the next strongest supported digest.
-                return Collections.singletonList(SignatureAlgorithm.ECDSA_WITH_SHA512);
-            }
-        } else {
-            throw new InvalidKeyException("Unsupported key algorithm: " + keyAlgorithm);
-        }
-    }
-
-    /**
-     * Signs the provided APK using APK Signature Scheme v2 and returns the APK Signing Block
-     * containing the signature.
-     *
-     * @param signerConfigs signer configurations, one for each signer At least one signer config
-     *        must be provided.
-     *
-     * @throws IOException if an I/O error occurs
-     * @throws NoSuchAlgorithmException if a required cryptographic algorithm implementation is
-     *         missing
-     * @throws InvalidKeyException if a signing key is not suitable for this signature scheme or
-     *         cannot be used in general
-     * @throws SignatureException if an error occurs when computing digests of generating
-     *         signatures
-     */
-    public static byte[] generateApkSigningBlock(
-            DataSource beforeCentralDir,
-            DataSource centralDir,
-            DataSource eocd,
-            List<SignerConfig> signerConfigs)
-                        throws IOException, NoSuchAlgorithmException, InvalidKeyException,
-                                SignatureException {
-        if (signerConfigs.isEmpty()) {
-            throw new IllegalArgumentException(
-                    "No signer configs provided. At least one is required");
-        }
-
-        // Figure out which digest(s) to use for APK contents.
-        Set<ContentDigestAlgorithm> contentDigestAlgorithms = new HashSet<>(1);
-        for (SignerConfig signerConfig : signerConfigs) {
-            for (SignatureAlgorithm signatureAlgorithm : signerConfig.signatureAlgorithms) {
-                contentDigestAlgorithms.add(signatureAlgorithm.getContentDigestAlgorithm());
-            }
-        }
-
-        // Ensure that, when digesting, ZIP End of Central Directory record's Central Directory
-        // offset field is treated as pointing to the offset at which the APK Signing Block will
-        // start.
-        long centralDirOffsetForDigesting = beforeCentralDir.size();
-        ByteBuffer eocdBuf = ByteBuffer.allocate((int) eocd.size());
-        eocdBuf.order(ByteOrder.LITTLE_ENDIAN);
-        eocd.copyTo(0, (int) eocd.size(), eocdBuf);
-        eocdBuf.flip();
-        ZipUtils.setZipEocdCentralDirectoryOffset(eocdBuf, centralDirOffsetForDigesting);
-
-        // Compute digests of APK contents.
-        Map<ContentDigestAlgorithm, byte[]> contentDigests; // digest algorithm ID -> digest
-        try {
-            contentDigests =
-                    computeContentDigests(
-                            contentDigestAlgorithms,
-                            new DataSource[] {
-                                    beforeCentralDir,
-                                    centralDir,
-                                    DataSources.asDataSource(eocdBuf)});
-        } catch (IOException e) {
-            throw new IOException("Failed to read APK being signed", e);
-        } catch (DigestException e) {
-            throw new SignatureException("Failed to compute digests of APK", e);
-        }
-
-        // Sign the digests and wrap the signatures and signer info into an APK Signing Block.
-        return generateApkSigningBlock(signerConfigs, contentDigests);
-    }
-
-    static Map<ContentDigestAlgorithm, byte[]> computeContentDigests(
-            Set<ContentDigestAlgorithm> digestAlgorithms,
-            DataSource[] contents) throws IOException, NoSuchAlgorithmException, DigestException {
-        // For each digest algorithm the result is computed as follows:
-        // 1. Each segment of contents is split into consecutive chunks of 1 MB in size.
-        //    The final chunk will be shorter iff the length of segment is not a multiple of 1 MB.
-        //    No chunks are produced for empty (zero length) segments.
-        // 2. The digest of each chunk is computed over the concatenation of byte 0xa5, the chunk's
-        //    length in bytes (uint32 little-endian) and the chunk's contents.
-        // 3. The output digest is computed over the concatenation of the byte 0x5a, the number of
-        //    chunks (uint32 little-endian) and the concatenation of digests of chunks of all
-        //    segments in-order.
-
-        long chunkCountLong = 0;
-        for (DataSource input : contents) {
-            chunkCountLong +=
-                    getChunkCount(input.size(), CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES);
-        }
-        if (chunkCountLong > Integer.MAX_VALUE) {
-            throw new DigestException("Input too long: " + chunkCountLong + " chunks");
-        }
-        int chunkCount = (int) chunkCountLong;
-
-        ContentDigestAlgorithm[] digestAlgorithmsArray =
-                digestAlgorithms.toArray(new ContentDigestAlgorithm[digestAlgorithms.size()]);
-        MessageDigest[] mds = new MessageDigest[digestAlgorithmsArray.length];
-        byte[][] digestsOfChunks = new byte[digestAlgorithmsArray.length][];
-        int[] digestOutputSizes = new int[digestAlgorithmsArray.length];
-        for (int i = 0; i < digestAlgorithmsArray.length; i++) {
-            ContentDigestAlgorithm digestAlgorithm = digestAlgorithmsArray[i];
-            int digestOutputSizeBytes = digestAlgorithm.getChunkDigestOutputSizeBytes();
-            digestOutputSizes[i] = digestOutputSizeBytes;
-            byte[] concatenationOfChunkCountAndChunkDigests =
-                    new byte[5 + chunkCount * digestOutputSizeBytes];
-            concatenationOfChunkCountAndChunkDigests[0] = 0x5a;
-            setUnsignedInt32LittleEndian(
-                    chunkCount, concatenationOfChunkCountAndChunkDigests, 1);
-            digestsOfChunks[i] = concatenationOfChunkCountAndChunkDigests;
-            String jcaAlgorithm = digestAlgorithm.getJcaMessageDigestAlgorithm();
-            mds[i] = MessageDigest.getInstance(jcaAlgorithm);
-        }
-
-        MessageDigestSink mdSink = new MessageDigestSink(mds);
-        byte[] chunkContentPrefix = new byte[5];
-        chunkContentPrefix[0] = (byte) 0xa5;
-        int chunkIndex = 0;
-        // Optimization opportunity: digests of chunks can be computed in parallel. However,
-        // determining the number of computations to be performed in parallel is non-trivial. This
-        // depends on a wide range of factors, such as data source type (e.g., in-memory or fetched
-        // from file), CPU/memory/disk cache bandwidth and latency, interconnect architecture of CPU
-        // cores, load on the system from other threads of execution and other processes, size of
-        // input.
-        // For now, we compute these digests sequentially and thus have the luxury of improving
-        // performance by writing the digest of each chunk into a pre-allocated buffer at exactly
-        // the right position. This avoids unnecessary allocations, copying, and enables the final
-        // digest to be more efficient because it's presented with all of its input in one go.
-        for (DataSource input : contents) {
-            long inputOffset = 0;
-            long inputRemaining = input.size();
-            while (inputRemaining > 0) {
-                int chunkSize =
-                        (int) Math.min(inputRemaining, CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES);
-                setUnsignedInt32LittleEndian(chunkSize, chunkContentPrefix, 1);
-                for (int i = 0; i < mds.length; i++) {
-                    mds[i].update(chunkContentPrefix);
-                }
-                try {
-                    input.feed(inputOffset, chunkSize, mdSink);
-                } catch (IOException e) {
-                    throw new IOException("Failed to read chunk #" + chunkIndex, e);
-                }
-                for (int i = 0; i < digestAlgorithmsArray.length; i++) {
-                    MessageDigest md = mds[i];
-                    byte[] concatenationOfChunkCountAndChunkDigests = digestsOfChunks[i];
-                    int expectedDigestSizeBytes = digestOutputSizes[i];
-                    int actualDigestSizeBytes =
-                            md.digest(
-                                    concatenationOfChunkCountAndChunkDigests,
-                                    5 + chunkIndex * expectedDigestSizeBytes,
-                                    expectedDigestSizeBytes);
-                    if (actualDigestSizeBytes != expectedDigestSizeBytes) {
-                        throw new RuntimeException(
-                                "Unexpected output size of " + md.getAlgorithm()
-                                        + " digest: " + actualDigestSizeBytes);
-                    }
-                }
-                inputOffset += chunkSize;
-                inputRemaining -= chunkSize;
-                chunkIndex++;
-            }
-        }
-
-        Map<ContentDigestAlgorithm, byte[]> result = new HashMap<>(digestAlgorithmsArray.length);
-        for (int i = 0; i < digestAlgorithmsArray.length; i++) {
-            ContentDigestAlgorithm digestAlgorithm = digestAlgorithmsArray[i];
-            byte[] concatenationOfChunkCountAndChunkDigests = digestsOfChunks[i];
-            MessageDigest md = mds[i];
-            byte[] digest = md.digest(concatenationOfChunkCountAndChunkDigests);
-            result.put(digestAlgorithm, digest);
-        }
-        return result;
-    }
-
-    private static final long getChunkCount(long inputSize, int chunkSize) {
-        return (inputSize + chunkSize - 1) / chunkSize;
-    }
-
-    private static void setUnsignedInt32LittleEndian(int value, byte[] result, int offset) {
-        result[offset] = (byte) (value & 0xff);
-        result[offset + 1] = (byte) ((value >> 8) & 0xff);
-        result[offset + 2] = (byte) ((value >> 16) & 0xff);
-        result[offset + 3] = (byte) ((value >> 24) & 0xff);
-    }
-
-    private static byte[] generateApkSigningBlock(
-            List<SignerConfig> signerConfigs,
-            Map<ContentDigestAlgorithm, byte[]> contentDigests)
-                    throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
-        byte[] apkSignatureSchemeV2Block =
-                generateApkSignatureSchemeV2Block(signerConfigs, contentDigests);
-        return generateApkSigningBlock(apkSignatureSchemeV2Block);
-    }
-
-    private static byte[] generateApkSigningBlock(byte[] apkSignatureSchemeV2Block) {
-        // FORMAT:
-        // uint64:  size (excluding this field)
-        // repeated ID-value pairs:
-        //     uint64:           size (excluding this field)
-        //     uint32:           ID
-        //     (size - 4) bytes: value
-        // uint64:  size (same as the one above)
-        // uint128: magic
-
-        int resultSize =
-                8 // size
-                + 8 + 4 + apkSignatureSchemeV2Block.length // v2Block as ID-value pair
-                + 8 // size
-                + 16 // magic
-                ;
-        ByteBuffer result = ByteBuffer.allocate(resultSize);
-        result.order(ByteOrder.LITTLE_ENDIAN);
-        long blockSizeFieldValue = resultSize - 8;
-        result.putLong(blockSizeFieldValue);
-
-        long pairSizeFieldValue = 4 + apkSignatureSchemeV2Block.length;
-        result.putLong(pairSizeFieldValue);
-        result.putInt(APK_SIGNATURE_SCHEME_V2_BLOCK_ID);
-        result.put(apkSignatureSchemeV2Block);
-
-        result.putLong(blockSizeFieldValue);
-        result.put(APK_SIGNING_BLOCK_MAGIC);
-
-        return result.array();
-    }
-
-    private static byte[] generateApkSignatureSchemeV2Block(
-            List<SignerConfig> signerConfigs,
-            Map<ContentDigestAlgorithm, byte[]> contentDigests)
-                    throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
-        // FORMAT:
-        // * length-prefixed sequence of length-prefixed signer blocks.
-
-        List<byte[]> signerBlocks = new ArrayList<>(signerConfigs.size());
-        int signerNumber = 0;
-        for (SignerConfig signerConfig : signerConfigs) {
-            signerNumber++;
-            byte[] signerBlock;
-            try {
-                signerBlock = generateSignerBlock(signerConfig, contentDigests);
-            } catch (InvalidKeyException e) {
-                throw new InvalidKeyException("Signer #" + signerNumber + " failed", e);
-            } catch (SignatureException e) {
-                throw new SignatureException("Signer #" + signerNumber + " failed", e);
-            }
-            signerBlocks.add(signerBlock);
-        }
-
-        return encodeAsSequenceOfLengthPrefixedElements(
-                new byte[][] {
-                    encodeAsSequenceOfLengthPrefixedElements(signerBlocks),
-                });
-    }
-
-    private static byte[] generateSignerBlock(
-            SignerConfig signerConfig,
-            Map<ContentDigestAlgorithm, byte[]> contentDigests)
-                    throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
-        if (signerConfig.certificates.isEmpty()) {
-            throw new SignatureException("No certificates configured for signer");
-        }
-        PublicKey publicKey = signerConfig.certificates.get(0).getPublicKey();
-
-        byte[] encodedPublicKey = encodePublicKey(publicKey);
-
-        V2SignatureSchemeBlock.SignedData signedData = new V2SignatureSchemeBlock.SignedData();
-        try {
-            signedData.certificates = encodeCertificates(signerConfig.certificates);
-        } catch (CertificateEncodingException e) {
-            throw new SignatureException("Failed to encode certificates", e);
-        }
-
-        List<Pair<Integer, byte[]>> digests =
-                new ArrayList<>(signerConfig.signatureAlgorithms.size());
-        for (SignatureAlgorithm signatureAlgorithm : signerConfig.signatureAlgorithms) {
-            ContentDigestAlgorithm contentDigestAlgorithm =
-                    signatureAlgorithm.getContentDigestAlgorithm();
-            byte[] contentDigest = contentDigests.get(contentDigestAlgorithm);
-            if (contentDigest == null) {
-                throw new RuntimeException(
-                        contentDigestAlgorithm + " content digest for " + signatureAlgorithm
-                                + " not computed");
-            }
-            digests.add(Pair.of(signatureAlgorithm.getId(), contentDigest));
-        }
-        signedData.digests = digests;
-
-        V2SignatureSchemeBlock.Signer signer = new V2SignatureSchemeBlock.Signer();
-        // FORMAT:
-        // * length-prefixed sequence of length-prefixed digests:
-        //   * uint32: signature algorithm ID
-        //   * length-prefixed bytes: digest of contents
-        // * length-prefixed sequence of certificates:
-        //   * length-prefixed bytes: X.509 certificate (ASN.1 DER encoded).
-        // * length-prefixed sequence of length-prefixed additional attributes:
-        //   * uint32: ID
-        //   * (length - 4) bytes: value
-        signer.signedData = encodeAsSequenceOfLengthPrefixedElements(new byte[][] {
-            encodeAsSequenceOfLengthPrefixedPairsOfIntAndLengthPrefixedBytes(signedData.digests),
-            encodeAsSequenceOfLengthPrefixedElements(signedData.certificates),
-            // additional attributes
-            new byte[0],
-        });
-        signer.publicKey = encodedPublicKey;
-        signer.signatures = new ArrayList<>(signerConfig.signatureAlgorithms.size());
-        for (SignatureAlgorithm signatureAlgorithm : signerConfig.signatureAlgorithms) {
-            Pair<String, ? extends AlgorithmParameterSpec> sigAlgAndParams =
-                    signatureAlgorithm.getJcaSignatureAlgorithmAndParams();
-            String jcaSignatureAlgorithm = sigAlgAndParams.getFirst();
-            AlgorithmParameterSpec jcaSignatureAlgorithmParams = sigAlgAndParams.getSecond();
-            byte[] signatureBytes;
-            try {
-                Signature signature = Signature.getInstance(jcaSignatureAlgorithm);
-                signature.initSign(signerConfig.privateKey);
-                if (jcaSignatureAlgorithmParams != null) {
-                    signature.setParameter(jcaSignatureAlgorithmParams);
-                }
-                signature.update(signer.signedData);
-                signatureBytes = signature.sign();
-            } catch (InvalidKeyException e) {
-                throw new InvalidKeyException("Failed to sign using " + jcaSignatureAlgorithm, e);
-            } catch (InvalidAlgorithmParameterException | SignatureException e) {
-                throw new SignatureException("Failed to sign using " + jcaSignatureAlgorithm, e);
-            }
-
-            try {
-                Signature signature = Signature.getInstance(jcaSignatureAlgorithm);
-                signature.initVerify(publicKey);
-                if (jcaSignatureAlgorithmParams != null) {
-                    signature.setParameter(jcaSignatureAlgorithmParams);
-                }
-                signature.update(signer.signedData);
-                if (!signature.verify(signatureBytes)) {
-                    throw new SignatureException("Signature did not verify");
-                }
-            } catch (InvalidKeyException e) {
-                throw new InvalidKeyException(
-                        "Failed to verify generated " + jcaSignatureAlgorithm + " signature using"
-                                + " public key from certificate", e);
-            } catch (InvalidAlgorithmParameterException | SignatureException e) {
-                throw new SignatureException(
-                        "Failed to verify generated " + jcaSignatureAlgorithm + " signature using"
-                                + " public key from certificate", e);
-            }
-
-            signer.signatures.add(Pair.of(signatureAlgorithm.getId(), signatureBytes));
-        }
-
-        // FORMAT:
-        // * length-prefixed signed data
-        // * length-prefixed sequence of length-prefixed signatures:
-        //   * uint32: signature algorithm ID
-        //   * length-prefixed bytes: signature of signed data
-        // * length-prefixed bytes: public key (X.509 SubjectPublicKeyInfo, ASN.1 DER encoded)
-        return encodeAsSequenceOfLengthPrefixedElements(
-                new byte[][] {
-                    signer.signedData,
-                    encodeAsSequenceOfLengthPrefixedPairsOfIntAndLengthPrefixedBytes(
-                            signer.signatures),
-                    signer.publicKey,
-                });
-    }
-
-    private static final class V2SignatureSchemeBlock {
-        private static final class Signer {
-            public byte[] signedData;
-            public List<Pair<Integer, byte[]>> signatures;
-            public byte[] publicKey;
-        }
-
-        private static final class SignedData {
-            public List<Pair<Integer, byte[]>> digests;
-            public List<byte[]> certificates;
-        }
-    }
-
-    private static byte[] encodePublicKey(PublicKey publicKey)
-            throws InvalidKeyException, NoSuchAlgorithmException {
-        byte[] encodedPublicKey = null;
-        if ("X.509".equals(publicKey.getFormat())) {
-            encodedPublicKey = publicKey.getEncoded();
-        }
-        if (encodedPublicKey == null) {
-            try {
-                encodedPublicKey =
-                        KeyFactory.getInstance(publicKey.getAlgorithm())
-                                .getKeySpec(publicKey, X509EncodedKeySpec.class)
-                                .getEncoded();
-            } catch (InvalidKeySpecException e) {
-                throw new InvalidKeyException(
-                        "Failed to obtain X.509 encoded form of public key " + publicKey
-                                + " of class " + publicKey.getClass().getName(),
-                        e);
-            }
-        }
-        if ((encodedPublicKey == null) || (encodedPublicKey.length == 0)) {
-            throw new InvalidKeyException(
-                    "Failed to obtain X.509 encoded form of public key " + publicKey
-                            + " of class " + publicKey.getClass().getName());
-        }
-        return encodedPublicKey;
-    }
-
-    private static List<byte[]> encodeCertificates(List<X509Certificate> certificates)
-            throws CertificateEncodingException {
-        List<byte[]> result = new ArrayList<>(certificates.size());
-        for (X509Certificate certificate : certificates) {
-            result.add(certificate.getEncoded());
-        }
-        return result;
-    }
-
-    private static byte[] encodeAsSequenceOfLengthPrefixedElements(List<byte[]> sequence) {
-        return encodeAsSequenceOfLengthPrefixedElements(
-                sequence.toArray(new byte[sequence.size()][]));
-    }
-
-    private static byte[] encodeAsSequenceOfLengthPrefixedElements(byte[][] sequence) {
-        int payloadSize = 0;
-        for (byte[] element : sequence) {
-            payloadSize += 4 + element.length;
-        }
-        ByteBuffer result = ByteBuffer.allocate(payloadSize);
-        result.order(ByteOrder.LITTLE_ENDIAN);
-        for (byte[] element : sequence) {
-            result.putInt(element.length);
-            result.put(element);
-        }
-        return result.array();
-      }
-
-    private static byte[] encodeAsSequenceOfLengthPrefixedPairsOfIntAndLengthPrefixedBytes(
-            List<Pair<Integer, byte[]>> sequence) {
-        int resultSize = 0;
-        for (Pair<Integer, byte[]> element : sequence) {
-            resultSize += 12 + element.getSecond().length;
-        }
-        ByteBuffer result = ByteBuffer.allocate(resultSize);
-        result.order(ByteOrder.LITTLE_ENDIAN);
-        for (Pair<Integer, byte[]> element : sequence) {
-            byte[] second = element.getSecond();
-            result.putInt(8 + second.length);
-            result.putInt(element.getFirst());
-            result.putInt(second.length);
-            result.put(second);
-        }
-        return result.array();
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/V2SchemeVerifier.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/V2SchemeVerifier.java
deleted file mode 100644
index 5e1e8fb..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/V2SchemeVerifier.java
+++ /dev/null
@@ -1,955 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.apk.v2;
-
-import com.android.apksigner.core.ApkVerifier.Issue;
-import com.android.apksigner.core.ApkVerifier.IssueWithParams;
-import com.android.apksigner.core.apk.ApkUtils;
-import com.android.apksigner.core.internal.util.ByteBufferDataSource;
-import com.android.apksigner.core.internal.util.DelegatingX509Certificate;
-import com.android.apksigner.core.internal.util.Pair;
-import com.android.apksigner.core.internal.zip.ZipUtils;
-import com.android.apksigner.core.util.DataSource;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.security.DigestException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * APK Signature Scheme v2 verifier.
- *
- * <p>APK Signature Scheme v2 is a whole-file signature scheme which aims to protect every single
- * bit of the APK, as opposed to the JAR Signature Scheme which protects only the names and
- * uncompressed contents of ZIP entries.
- *
- * <p>TODO: Link to APK Signature Scheme v2 documentation once it's available.
- */
-public abstract class V2SchemeVerifier {
-
-    private static final long APK_SIG_BLOCK_MAGIC_HI = 0x3234206b636f6c42L;
-    private static final long APK_SIG_BLOCK_MAGIC_LO = 0x20676953204b5041L;
-    private static final int APK_SIG_BLOCK_MIN_SIZE = 32;
-
-    private static final int APK_SIGNATURE_SCHEME_V2_BLOCK_ID = 0x7109871a;
-
-    /** Hidden constructor to prevent instantiation. */
-    private V2SchemeVerifier() {}
-
-    /**
-     * Verifies the provided APK's APK Signature Scheme v2 signatures and returns the result of
-     * verification. APK is considered verified only if {@link Result#verified} is {@code true}. If
-     * verification fails, the result will contain errors -- see {@link Result#getErrors()}.
-     *
-     * @throws NoSuchAlgorithmException if the APK's signatures cannot be verified because a
-     *         required cryptographic algorithm implementation is missing
-     * @throws SignatureNotFoundException if no APK Signature Scheme v2 signatures are found
-     * @throws IOException if an I/O error occurs when reading the APK
-     */
-    public static Result verify(DataSource apk, ApkUtils.ZipSections zipSections)
-            throws IOException, NoSuchAlgorithmException, SignatureNotFoundException {
-        Result result = new Result();
-        SignatureInfo signatureInfo = findSignature(apk, zipSections, result);
-
-        DataSource beforeApkSigningBlock = apk.slice(0, signatureInfo.apkSigningBlockOffset);
-        DataSource centralDir =
-                apk.slice(
-                        signatureInfo.centralDirOffset,
-                        signatureInfo.eocdOffset - signatureInfo.centralDirOffset);
-        ByteBuffer eocd = signatureInfo.eocd;
-
-        verify(beforeApkSigningBlock,
-                signatureInfo.signatureBlock,
-                centralDir,
-                eocd,
-                result);
-        return result;
-    }
-
-    /**
-     * Verifies the provided APK's v2 signatures and outputs the results into the provided
-     * {@code result}. APK is considered verified only if there are no errors reported in the
-     * {@code result}.
-     */
-    private static void verify(
-            DataSource beforeApkSigningBlock,
-            ByteBuffer apkSignatureSchemeV2Block,
-            DataSource centralDir,
-            ByteBuffer eocd,
-            Result result) throws IOException, NoSuchAlgorithmException {
-        Set<ContentDigestAlgorithm> contentDigestsToVerify = new HashSet<>(1);
-        parseSigners(apkSignatureSchemeV2Block, contentDigestsToVerify, result);
-        if (result.containsErrors()) {
-            return;
-        }
-        verifyIntegrity(
-                beforeApkSigningBlock, centralDir, eocd, contentDigestsToVerify, result);
-        if (!result.containsErrors()) {
-            result.verified = true;
-        }
-    }
-
-    /**
-     * Parses each signer in the provided APK Signature Scheme v2 block and populates
-     * {@code signerInfos} of the provided {@code result}.
-     *
-     * <p>This verifies signatures over {@code signed-data} block contained in each signer block.
-     * However, this does not verify the integrity of the rest of the APK but rather simply reports
-     * the expected digests of the rest of the APK (see {@code contentDigestsToVerify}).
-     */
-    private static void parseSigners(
-            ByteBuffer apkSignatureSchemeV2Block,
-            Set<ContentDigestAlgorithm> contentDigestsToVerify,
-            Result result) throws NoSuchAlgorithmException {
-        ByteBuffer signers;
-        try {
-            signers = getLengthPrefixedSlice(apkSignatureSchemeV2Block);
-        } catch (IOException e) {
-            result.addError(Issue.V2_SIG_MALFORMED_SIGNERS);
-            return;
-        }
-        if (!signers.hasRemaining()) {
-            result.addError(Issue.V2_SIG_NO_SIGNERS);
-            return;
-        }
-
-        CertificateFactory certFactory;
-        try {
-            certFactory = CertificateFactory.getInstance("X.509");
-        } catch (CertificateException e) {
-            throw new RuntimeException("Failed to obtain X.509 CertificateFactory", e);
-        }
-        int signerCount = 0;
-        while (signers.hasRemaining()) {
-            int signerIndex = signerCount;
-            signerCount++;
-            Result.SignerInfo signerInfo = new Result.SignerInfo();
-            signerInfo.index = signerIndex;
-            result.signers.add(signerInfo);
-            try {
-                ByteBuffer signer = getLengthPrefixedSlice(signers);
-                parseSigner(signer, certFactory, signerInfo, contentDigestsToVerify);
-            } catch (IOException | BufferUnderflowException e) {
-                signerInfo.addError(Issue.V2_SIG_MALFORMED_SIGNER);
-                return;
-            }
-        }
-    }
-
-    /**
-     * Parses the provided signer block and populates the {@code result}.
-     *
-     * <p>This verifies signatures over {@code signed-data} contained in this block but does not
-     * verify the integrity of the rest of the APK. Rather, this method adds to the
-     * {@code contentDigestsToVerify}.
-     */
-    private static void parseSigner(
-            ByteBuffer signerBlock,
-            CertificateFactory certFactory,
-            Result.SignerInfo result,
-            Set<ContentDigestAlgorithm> contentDigestsToVerify)
-                    throws IOException, NoSuchAlgorithmException {
-        ByteBuffer signedData = getLengthPrefixedSlice(signerBlock);
-        byte[] signedDataBytes = new byte[signedData.remaining()];
-        signedData.get(signedDataBytes);
-        signedData.flip();
-        result.signedData = signedDataBytes;
-
-        ByteBuffer signatures = getLengthPrefixedSlice(signerBlock);
-        byte[] publicKeyBytes = readLengthPrefixedByteArray(signerBlock);
-
-        // Parse the signatures block and identify supported signatures
-        int signatureCount = 0;
-        List<SupportedSignature> supportedSignatures = new ArrayList<>(1);
-        while (signatures.hasRemaining()) {
-            signatureCount++;
-            try {
-                ByteBuffer signature = getLengthPrefixedSlice(signatures);
-                int sigAlgorithmId = signature.getInt();
-                byte[] sigBytes = readLengthPrefixedByteArray(signature);
-                result.signatures.add(
-                        new Result.SignerInfo.Signature(sigAlgorithmId, sigBytes));
-                SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.findById(sigAlgorithmId);
-                if (signatureAlgorithm == null) {
-                    result.addWarning(Issue.V2_SIG_UNKNOWN_SIG_ALGORITHM, sigAlgorithmId);
-                    continue;
-                }
-                supportedSignatures.add(new SupportedSignature(signatureAlgorithm, sigBytes));
-            } catch (IOException | BufferUnderflowException e) {
-                result.addError(Issue.V2_SIG_MALFORMED_SIGNATURE, signatureCount);
-                return;
-            }
-        }
-        if (result.signatures.isEmpty()) {
-            result.addError(Issue.V2_SIG_NO_SIGNATURES);
-            return;
-        }
-
-        // Verify signatures over signed-data block using the public key
-        List<SupportedSignature> signaturesToVerify = getSignaturesToVerify(supportedSignatures);
-        if (signaturesToVerify.isEmpty()) {
-            result.addError(Issue.V2_SIG_NO_SUPPORTED_SIGNATURES);
-            return;
-        }
-        for (SupportedSignature signature : signaturesToVerify) {
-            SignatureAlgorithm signatureAlgorithm = signature.algorithm;
-            String jcaSignatureAlgorithm =
-                    signatureAlgorithm.getJcaSignatureAlgorithmAndParams().getFirst();
-            AlgorithmParameterSpec jcaSignatureAlgorithmParams =
-                    signatureAlgorithm.getJcaSignatureAlgorithmAndParams().getSecond();
-            String keyAlgorithm = signatureAlgorithm.getJcaKeyAlgorithm();
-            PublicKey publicKey;
-            try {
-                publicKey =
-                        KeyFactory.getInstance(keyAlgorithm).generatePublic(
-                                new X509EncodedKeySpec(publicKeyBytes));
-            } catch (Exception e) {
-                result.addError(Issue.V2_SIG_MALFORMED_PUBLIC_KEY, e);
-                return;
-            }
-            try {
-                Signature sig = Signature.getInstance(jcaSignatureAlgorithm);
-                sig.initVerify(publicKey);
-                if (jcaSignatureAlgorithmParams != null) {
-                    sig.setParameter(jcaSignatureAlgorithmParams);
-                }
-                signedData.position(0);
-                sig.update(signedData);
-                byte[] sigBytes = signature.signature;
-                if (!sig.verify(sigBytes)) {
-                    result.addError(Issue.V2_SIG_DID_NOT_VERIFY, signatureAlgorithm);
-                    return;
-                }
-                result.verifiedSignatures.put(signatureAlgorithm, sigBytes);
-                contentDigestsToVerify.add(signatureAlgorithm.getContentDigestAlgorithm());
-            } catch (InvalidKeyException | InvalidAlgorithmParameterException
-                    | SignatureException e) {
-                result.addError(Issue.V2_SIG_VERIFY_EXCEPTION, signatureAlgorithm, e);
-                return;
-            }
-        }
-
-        // At least one signature over signedData has verified. We can now parse signed-data.
-        signedData.position(0);
-        ByteBuffer digests = getLengthPrefixedSlice(signedData);
-        ByteBuffer certificates = getLengthPrefixedSlice(signedData);
-        ByteBuffer additionalAttributes = getLengthPrefixedSlice(signedData);
-
-        // Parse the certificates block
-        int certificateIndex = -1;
-        while (certificates.hasRemaining()) {
-            certificateIndex++;
-            byte[] encodedCert = readLengthPrefixedByteArray(certificates);
-            X509Certificate certificate;
-            try {
-                certificate =
-                        (X509Certificate)
-                                certFactory.generateCertificate(
-                                        new ByteArrayInputStream(encodedCert));
-            } catch (CertificateException e) {
-                result.addError(
-                        Issue.V2_SIG_MALFORMED_CERTIFICATE,
-                        certificateIndex,
-                        certificateIndex + 1,
-                        e);
-                return;
-            }
-            // Wrap the cert so that the result's getEncoded returns exactly the original encoded
-            // form. Without this, getEncoded may return a different form from what was stored in
-            // the signature. This is becase some X509Certificate(Factory) implementations re-encode
-            // certificates.
-            certificate = new GuaranteedEncodedFormX509Certificate(certificate, encodedCert);
-            result.certs.add(certificate);
-        }
-
-        if (result.certs.isEmpty()) {
-            result.addError(Issue.V2_SIG_NO_CERTIFICATES);
-            return;
-        }
-        X509Certificate mainCertificate = result.certs.get(0);
-        byte[] certificatePublicKeyBytes = mainCertificate.getPublicKey().getEncoded();
-        if (!Arrays.equals(publicKeyBytes, certificatePublicKeyBytes)) {
-            result.addError(
-                    Issue.V2_SIG_PUBLIC_KEY_MISMATCH_BETWEEN_CERTIFICATE_AND_SIGNATURES_RECORD,
-                    toHex(certificatePublicKeyBytes),
-                    toHex(publicKeyBytes));
-            return;
-        }
-
-        // Parse the digests block
-        int digestCount = 0;
-        while (digests.hasRemaining()) {
-            digestCount++;
-            try {
-                ByteBuffer digest = getLengthPrefixedSlice(digests);
-                int sigAlgorithmId = digest.getInt();
-                byte[] digestBytes = readLengthPrefixedByteArray(digest);
-                result.contentDigests.add(
-                        new Result.SignerInfo.ContentDigest(sigAlgorithmId, digestBytes));
-            } catch (IOException | BufferUnderflowException e) {
-                result.addError(Issue.V2_SIG_MALFORMED_DIGEST, digestCount);
-                return;
-            }
-        }
-
-        List<Integer> sigAlgsFromSignaturesRecord = new ArrayList<>(result.signatures.size());
-        for (Result.SignerInfo.Signature signature : result.signatures) {
-            sigAlgsFromSignaturesRecord.add(signature.getAlgorithmId());
-        }
-        List<Integer> sigAlgsFromDigestsRecord = new ArrayList<>(result.contentDigests.size());
-        for (Result.SignerInfo.ContentDigest digest : result.contentDigests) {
-            sigAlgsFromDigestsRecord.add(digest.getSignatureAlgorithmId());
-        }
-
-        if (!sigAlgsFromSignaturesRecord.equals(sigAlgsFromDigestsRecord)) {
-            result.addError(
-                    Issue.V2_SIG_SIG_ALG_MISMATCH_BETWEEN_SIGNATURES_AND_DIGESTS_RECORDS,
-                    sigAlgsFromSignaturesRecord,
-                    sigAlgsFromDigestsRecord);
-            return;
-        }
-
-        // Parse the additional attributes block.
-        int additionalAttributeCount = 0;
-        while (additionalAttributes.hasRemaining()) {
-            additionalAttributeCount++;
-            try {
-                ByteBuffer attribute = getLengthPrefixedSlice(additionalAttributes);
-                int id = attribute.getInt();
-                byte[] value = readLengthPrefixedByteArray(attribute);
-                result.additionalAttributes.add(
-                        new Result.SignerInfo.AdditionalAttribute(id, value));
-                result.addWarning(Issue.V2_SIG_UNKNOWN_ADDITIONAL_ATTRIBUTE, id);
-            } catch (IOException | BufferUnderflowException e) {
-                result.addError(
-                        Issue.V2_SIG_MALFORMED_ADDITIONAL_ATTRIBUTE, additionalAttributeCount);
-                return;
-            }
-        }
-    }
-
-    private static List<SupportedSignature> getSignaturesToVerify(
-            List<SupportedSignature> signatures) {
-        // Pick the signature with the strongest algorithm, to mimic Android's behavior.
-        SignatureAlgorithm bestSigAlgorithm = null;
-        byte[] bestSigAlgorithmSignatureBytes = null;
-        for (SupportedSignature sig : signatures) {
-            SignatureAlgorithm sigAlgorithm = sig.algorithm;
-            if ((bestSigAlgorithm == null)
-                    || (compareSignatureAlgorithm(sigAlgorithm, bestSigAlgorithm) > 0)) {
-                bestSigAlgorithm = sigAlgorithm;
-                bestSigAlgorithmSignatureBytes = sig.signature;
-            }
-        }
-
-        if (bestSigAlgorithm == null) {
-            return Collections.emptyList();
-        } else {
-            return Collections.singletonList(
-                    new SupportedSignature(bestSigAlgorithm, bestSigAlgorithmSignatureBytes));
-        }
-    }
-
-    private static class SupportedSignature {
-        private final SignatureAlgorithm algorithm;
-        private final byte[] signature;
-
-        private SupportedSignature(SignatureAlgorithm algorithm, byte[] signature) {
-            this.algorithm = algorithm;
-            this.signature = signature;
-        }
-    }
-
-    /**
-     * Returns positive number if {@code alg1} is preferred over {@code alg2}, {@code -1} if
-     * {@code alg2} is preferred over {@code alg1}, and {@code 0} if there is no preference.
-     */
-    private static int compareSignatureAlgorithm(SignatureAlgorithm alg1, SignatureAlgorithm alg2) {
-        ContentDigestAlgorithm digestAlg1 = alg1.getContentDigestAlgorithm();
-        ContentDigestAlgorithm digestAlg2 = alg2.getContentDigestAlgorithm();
-        return compareContentDigestAlgorithm(digestAlg1, digestAlg2);
-    }
-
-    /**
-     * Returns positive number if {@code alg1} is preferred over {@code alg2}, {@code -1} if
-     * {@code alg2} is preferred over {@code alg1}, and {@code 0} if there is no preference.
-     */
-    private static int compareContentDigestAlgorithm(
-            ContentDigestAlgorithm alg1,
-            ContentDigestAlgorithm alg2) {
-        switch (alg1) {
-            case CHUNKED_SHA256:
-                switch (alg2) {
-                    case CHUNKED_SHA256:
-                        return 0;
-                    case CHUNKED_SHA512:
-                        return -1;
-                    default:
-                        throw new IllegalArgumentException("Unknown alg2: " + alg2);
-                }
-            case CHUNKED_SHA512:
-                switch (alg2) {
-                    case CHUNKED_SHA256:
-                        return 1;
-                    case CHUNKED_SHA512:
-                        return 0;
-                    default:
-                        throw new IllegalArgumentException("Unknown alg2: " + alg2);
-                }
-            default:
-                throw new IllegalArgumentException("Unknown alg1: " + alg1);
-        }
-    }
-
-    /**
-     * Verifies integrity of the APK outside of the APK Signing Block by computing digests of the
-     * APK and comparing them against the digests listed in APK Signing Block. The expected digests
-     * taken from {@code v2SchemeSignerInfos} of the provided {@code result}.
-     */
-    private static void verifyIntegrity(
-            DataSource beforeApkSigningBlock,
-            DataSource centralDir,
-            ByteBuffer eocd,
-            Set<ContentDigestAlgorithm> contentDigestAlgorithms,
-            Result result) throws IOException, NoSuchAlgorithmException {
-        if (contentDigestAlgorithms.isEmpty()) {
-            // This should never occur because this method is invoked once at least one signature
-            // is verified, meaning at least one content digest is known.
-            throw new RuntimeException("No content digests found");
-        }
-
-        // For the purposes of verifying integrity, ZIP End of Central Directory (EoCD) must be
-        // treated as though its Central Directory offset points to the start of APK Signing Block.
-        // We thus modify the EoCD accordingly.
-        ByteBuffer modifiedEocd = ByteBuffer.allocate(eocd.remaining());
-        modifiedEocd.order(ByteOrder.LITTLE_ENDIAN);
-        modifiedEocd.put(eocd);
-        modifiedEocd.flip();
-        ZipUtils.setZipEocdCentralDirectoryOffset(modifiedEocd, beforeApkSigningBlock.size());
-        Map<ContentDigestAlgorithm, byte[]> actualContentDigests;
-        try {
-            actualContentDigests =
-                    V2SchemeSigner.computeContentDigests(
-                            contentDigestAlgorithms,
-                            new DataSource[] {
-                                    beforeApkSigningBlock,
-                                    centralDir,
-                                    new ByteBufferDataSource(modifiedEocd)
-                            });
-        } catch (DigestException e) {
-            throw new RuntimeException("Failed to compute content digests", e);
-        }
-        if (!contentDigestAlgorithms.equals(actualContentDigests.keySet())) {
-            throw new RuntimeException(
-                    "Mismatch between sets of requested and computed content digests"
-                            + " . Requested: " + contentDigestAlgorithms
-                            + ", computed: " + actualContentDigests.keySet());
-        }
-
-        // Compare digests computed over the rest of APK against the corresponding expected digests
-        // in signer blocks.
-        for (Result.SignerInfo signerInfo : result.signers) {
-            for (Result.SignerInfo.ContentDigest expected : signerInfo.contentDigests) {
-                SignatureAlgorithm signatureAlgorithm =
-                        SignatureAlgorithm.findById(expected.getSignatureAlgorithmId());
-                if (signatureAlgorithm == null) {
-                    continue;
-                }
-                ContentDigestAlgorithm contentDigestAlgorithm =
-                        signatureAlgorithm.getContentDigestAlgorithm();
-                byte[] expectedDigest = expected.getValue();
-                byte[] actualDigest = actualContentDigests.get(contentDigestAlgorithm);
-                if (!Arrays.equals(expectedDigest, actualDigest)) {
-                    signerInfo.addError(
-                            Issue.V2_SIG_APK_DIGEST_DID_NOT_VERIFY,
-                            contentDigestAlgorithm,
-                            toHex(expectedDigest),
-                            toHex(actualDigest));
-                    continue;
-                }
-                signerInfo.verifiedContentDigests.put(contentDigestAlgorithm, actualDigest);
-            }
-        }
-    }
-
-    /**
-     * APK Signature Scheme v2 block and additional information relevant to verifying the signatures
-     * contained in the block against the file.
-     */
-    private static class SignatureInfo {
-        /** Contents of APK Signature Scheme v2 block. */
-        private final ByteBuffer signatureBlock;
-
-        /** Position of the APK Signing Block in the file. */
-        private final long apkSigningBlockOffset;
-
-        /** Position of the ZIP Central Directory in the file. */
-        private final long centralDirOffset;
-
-        /** Position of the ZIP End of Central Directory (EoCD) in the file. */
-        private final long eocdOffset;
-
-        /** Contents of ZIP End of Central Directory (EoCD) of the file. */
-        private final ByteBuffer eocd;
-
-        private SignatureInfo(
-                ByteBuffer signatureBlock,
-                long apkSigningBlockOffset,
-                long centralDirOffset,
-                long eocdOffset,
-                ByteBuffer eocd) {
-            this.signatureBlock = signatureBlock;
-            this.apkSigningBlockOffset = apkSigningBlockOffset;
-            this.centralDirOffset = centralDirOffset;
-            this.eocdOffset = eocdOffset;
-            this.eocd = eocd;
-        }
-    }
-
-    /**
-     * Returns the APK Signature Scheme v2 block contained in the provided APK file and the
-     * additional information relevant for verifying the block against the file.
-     *
-     * @throws SignatureNotFoundException if the APK is not signed using APK Signature Scheme v2
-     * @throws IOException if an I/O error occurs while reading the APK
-     */
-    private static SignatureInfo findSignature(
-            DataSource apk, ApkUtils.ZipSections zipSections, Result result)
-                    throws IOException, SignatureNotFoundException {
-        // Find the APK Signing Block. The block immediately precedes the Central Directory.
-        ByteBuffer eocd = zipSections.getZipEndOfCentralDirectory();
-        Pair<DataSource, Long> apkSigningBlockAndOffset = findApkSigningBlock(apk, zipSections);
-        DataSource apkSigningBlock = apkSigningBlockAndOffset.getFirst();
-        long apkSigningBlockOffset = apkSigningBlockAndOffset.getSecond();
-        ByteBuffer apkSigningBlockBuf =
-                apkSigningBlock.getByteBuffer(0, (int) apkSigningBlock.size());
-        apkSigningBlockBuf.order(ByteOrder.LITTLE_ENDIAN);
-
-        // Find the APK Signature Scheme v2 Block inside the APK Signing Block.
-        ByteBuffer apkSignatureSchemeV2Block =
-                findApkSignatureSchemeV2Block(apkSigningBlockBuf, result);
-
-        return new SignatureInfo(
-                apkSignatureSchemeV2Block,
-                apkSigningBlockOffset,
-                zipSections.getZipCentralDirectoryOffset(),
-                zipSections.getZipEndOfCentralDirectoryOffset(),
-                eocd);
-    }
-
-    /**
-     * Returns the APK Signing Block and its offset in the provided APK.
-     *
-     * @throws SignatureNotFoundException if the APK does not contain an APK Signing Block
-     */
-    public static Pair<DataSource, Long> findApkSigningBlock(
-            DataSource apk, ApkUtils.ZipSections zipSections)
-                    throws IOException, SignatureNotFoundException {
-        // FORMAT:
-        // OFFSET       DATA TYPE  DESCRIPTION
-        // * @+0  bytes uint64:    size in bytes (excluding this field)
-        // * @+8  bytes payload
-        // * @-24 bytes uint64:    size in bytes (same as the one above)
-        // * @-16 bytes uint128:   magic
-
-        long centralDirStartOffset = zipSections.getZipCentralDirectoryOffset();
-        long centralDirEndOffset =
-                centralDirStartOffset + zipSections.getZipCentralDirectorySizeBytes();
-        long eocdStartOffset = zipSections.getZipEndOfCentralDirectoryOffset();
-        if (centralDirEndOffset != eocdStartOffset) {
-            throw new SignatureNotFoundException(
-                    "ZIP Central Directory is not immediately followed by End of Central Directory"
-                            + ". CD end: " + centralDirEndOffset
-                            + ", EoCD start: " + eocdStartOffset);
-        }
-
-        if (centralDirStartOffset < APK_SIG_BLOCK_MIN_SIZE) {
-            throw new SignatureNotFoundException(
-                    "APK too small for APK Signing Block. ZIP Central Directory offset: "
-                            + centralDirStartOffset);
-        }
-        // Read the magic and offset in file from the footer section of the block:
-        // * uint64:   size of block
-        // * 16 bytes: magic
-        ByteBuffer footer = apk.getByteBuffer(centralDirStartOffset - 24, 24);
-        footer.order(ByteOrder.LITTLE_ENDIAN);
-        if ((footer.getLong(8) != APK_SIG_BLOCK_MAGIC_LO)
-                || (footer.getLong(16) != APK_SIG_BLOCK_MAGIC_HI)) {
-            throw new SignatureNotFoundException(
-                    "No APK Signing Block before ZIP Central Directory");
-        }
-        // Read and compare size fields
-        long apkSigBlockSizeInFooter = footer.getLong(0);
-        if ((apkSigBlockSizeInFooter < footer.capacity())
-                || (apkSigBlockSizeInFooter > Integer.MAX_VALUE - 8)) {
-            throw new SignatureNotFoundException(
-                    "APK Signing Block size out of range: " + apkSigBlockSizeInFooter);
-        }
-        int totalSize = (int) (apkSigBlockSizeInFooter + 8);
-        long apkSigBlockOffset = centralDirStartOffset - totalSize;
-        if (apkSigBlockOffset < 0) {
-            throw new SignatureNotFoundException(
-                    "APK Signing Block offset out of range: " + apkSigBlockOffset);
-        }
-        ByteBuffer apkSigBlock = apk.getByteBuffer(apkSigBlockOffset, 8);
-        apkSigBlock.order(ByteOrder.LITTLE_ENDIAN);
-        long apkSigBlockSizeInHeader = apkSigBlock.getLong(0);
-        if (apkSigBlockSizeInHeader != apkSigBlockSizeInFooter) {
-            throw new SignatureNotFoundException(
-                    "APK Signing Block sizes in header and footer do not match: "
-                            + apkSigBlockSizeInHeader + " vs " + apkSigBlockSizeInFooter);
-        }
-        return Pair.of(apk.slice(apkSigBlockOffset, totalSize), apkSigBlockOffset);
-    }
-
-    private static ByteBuffer findApkSignatureSchemeV2Block(
-            ByteBuffer apkSigningBlock,
-            Result result) throws SignatureNotFoundException {
-        checkByteOrderLittleEndian(apkSigningBlock);
-        // FORMAT:
-        // OFFSET       DATA TYPE  DESCRIPTION
-        // * @+0  bytes uint64:    size in bytes (excluding this field)
-        // * @+8  bytes pairs
-        // * @-24 bytes uint64:    size in bytes (same as the one above)
-        // * @-16 bytes uint128:   magic
-        ByteBuffer pairs = sliceFromTo(apkSigningBlock, 8, apkSigningBlock.capacity() - 24);
-
-        int entryCount = 0;
-        while (pairs.hasRemaining()) {
-            entryCount++;
-            if (pairs.remaining() < 8) {
-                throw new SignatureNotFoundException(
-                        "Insufficient data to read size of APK Signing Block entry #" + entryCount);
-            }
-            long lenLong = pairs.getLong();
-            if ((lenLong < 4) || (lenLong > Integer.MAX_VALUE)) {
-                throw new SignatureNotFoundException(
-                        "APK Signing Block entry #" + entryCount
-                                + " size out of range: " + lenLong);
-            }
-            int len = (int) lenLong;
-            int nextEntryPos = pairs.position() + len;
-            if (len > pairs.remaining()) {
-                throw new SignatureNotFoundException(
-                        "APK Signing Block entry #" + entryCount + " size out of range: " + len
-                                + ", available: " + pairs.remaining());
-            }
-            int id = pairs.getInt();
-            if (id == APK_SIGNATURE_SCHEME_V2_BLOCK_ID) {
-                return getByteBuffer(pairs, len - 4);
-            }
-            result.addWarning(Issue.APK_SIG_BLOCK_UNKNOWN_ENTRY_ID, id);
-            pairs.position(nextEntryPos);
-        }
-
-        throw new SignatureNotFoundException(
-                "No APK Signature Scheme v2 block in APK Signing Block");
-    }
-
-    private static void checkByteOrderLittleEndian(ByteBuffer buffer) {
-        if (buffer.order() != ByteOrder.LITTLE_ENDIAN) {
-            throw new IllegalArgumentException("ByteBuffer byte order must be little endian");
-        }
-    }
-
-    public static class SignatureNotFoundException extends Exception {
-        private static final long serialVersionUID = 1L;
-
-        public SignatureNotFoundException(String message) {
-            super(message);
-        }
-
-        public SignatureNotFoundException(String message, Throwable cause) {
-            super(message, cause);
-        }
-    }
-
-    /**
-     * Returns new byte buffer whose content is a shared subsequence of this buffer's content
-     * between the specified start (inclusive) and end (exclusive) positions. As opposed to
-     * {@link ByteBuffer#slice()}, the returned buffer's byte order is the same as the source
-     * buffer's byte order.
-     */
-    private static ByteBuffer sliceFromTo(ByteBuffer source, int start, int end) {
-        if (start < 0) {
-            throw new IllegalArgumentException("start: " + start);
-        }
-        if (end < start) {
-            throw new IllegalArgumentException("end < start: " + end + " < " + start);
-        }
-        int capacity = source.capacity();
-        if (end > source.capacity()) {
-            throw new IllegalArgumentException("end > capacity: " + end + " > " + capacity);
-        }
-        int originalLimit = source.limit();
-        int originalPosition = source.position();
-        try {
-            source.position(0);
-            source.limit(end);
-            source.position(start);
-            ByteBuffer result = source.slice();
-            result.order(source.order());
-            return result;
-        } finally {
-            source.position(0);
-            source.limit(originalLimit);
-            source.position(originalPosition);
-        }
-    }
-
-    /**
-     * Relative <em>get</em> method for reading {@code size} number of bytes from the current
-     * position of this buffer.
-     *
-     * <p>This method reads the next {@code size} bytes at this buffer's current position,
-     * returning them as a {@code ByteBuffer} with start set to 0, limit and capacity set to
-     * {@code size}, byte order set to this buffer's byte order; and then increments the position by
-     * {@code size}.
-     */
-    private static ByteBuffer getByteBuffer(ByteBuffer source, int size)
-            throws BufferUnderflowException {
-        if (size < 0) {
-            throw new IllegalArgumentException("size: " + size);
-        }
-        int originalLimit = source.limit();
-        int position = source.position();
-        int limit = position + size;
-        if ((limit < position) || (limit > originalLimit)) {
-            throw new BufferUnderflowException();
-        }
-        source.limit(limit);
-        try {
-            ByteBuffer result = source.slice();
-            result.order(source.order());
-            source.position(limit);
-            return result;
-        } finally {
-            source.limit(originalLimit);
-        }
-    }
-
-    private static ByteBuffer getLengthPrefixedSlice(ByteBuffer source) throws IOException {
-        if (source.remaining() < 4) {
-            throw new IOException(
-                    "Remaining buffer too short to contain length of length-prefixed field."
-                            + " Remaining: " + source.remaining());
-        }
-        int len = source.getInt();
-        if (len < 0) {
-            throw new IllegalArgumentException("Negative length");
-        } else if (len > source.remaining()) {
-            throw new IOException("Length-prefixed field longer than remaining buffer."
-                    + " Field length: " + len + ", remaining: " + source.remaining());
-        }
-        return getByteBuffer(source, len);
-    }
-
-    private static byte[] readLengthPrefixedByteArray(ByteBuffer buf) throws IOException {
-        int len = buf.getInt();
-        if (len < 0) {
-            throw new IOException("Negative length");
-        } else if (len > buf.remaining()) {
-            throw new IOException("Underflow while reading length-prefixed value. Length: " + len
-                    + ", available: " + buf.remaining());
-        }
-        byte[] result = new byte[len];
-        buf.get(result);
-        return result;
-    }
-
-    /**
-     * {@link X509Certificate} whose {@link #getEncoded()} returns the data provided at construction
-     * time.
-     */
-    private static class GuaranteedEncodedFormX509Certificate extends DelegatingX509Certificate {
-        private byte[] mEncodedForm;
-
-        public GuaranteedEncodedFormX509Certificate(X509Certificate wrapped, byte[] encodedForm) {
-            super(wrapped);
-            this.mEncodedForm = (encodedForm != null) ? encodedForm.clone() : null;
-        }
-
-        @Override
-        public byte[] getEncoded() throws CertificateEncodingException {
-            return (mEncodedForm != null) ? mEncodedForm.clone() : null;
-        }
-    }
-
-    private static final char[] HEX_DIGITS = "01234567890abcdef".toCharArray();
-
-    private static String toHex(byte[] value) {
-        StringBuilder sb = new StringBuilder(value.length * 2);
-        int len = value.length;
-        for (int i = 0; i < len; i++) {
-            int hi = (value[i] & 0xff) >>> 4;
-            int lo = value[i] & 0x0f;
-            sb.append(HEX_DIGITS[hi]).append(HEX_DIGITS[lo]);
-        }
-        return sb.toString();
-    }
-
-    public static class Result {
-
-        /** Whether the APK's APK Signature Scheme v2 signature verifies. */
-        public boolean verified;
-
-        public final List<SignerInfo> signers = new ArrayList<>();
-        private final List<IssueWithParams> mWarnings = new ArrayList<>();
-        private final List<IssueWithParams> mErrors = new ArrayList<>();
-
-        public boolean containsErrors() {
-            if (!mErrors.isEmpty()) {
-                return true;
-            }
-            if (!signers.isEmpty()) {
-                for (SignerInfo signer : signers) {
-                    if (signer.containsErrors()) {
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-
-        public void addError(Issue msg, Object... parameters) {
-            mErrors.add(new IssueWithParams(msg, parameters));
-        }
-
-        public void addWarning(Issue msg, Object... parameters) {
-            mWarnings.add(new IssueWithParams(msg, parameters));
-        }
-
-        public List<IssueWithParams> getErrors() {
-            return mErrors;
-        }
-
-        public List<IssueWithParams> getWarnings() {
-            return mWarnings;
-        }
-
-        public static class SignerInfo {
-            public int index;
-            public List<X509Certificate> certs = new ArrayList<>();
-            public List<ContentDigest> contentDigests = new ArrayList<>();
-            public Map<ContentDigestAlgorithm, byte[]> verifiedContentDigests = new HashMap<>();
-            public List<Signature> signatures = new ArrayList<>();
-            public Map<SignatureAlgorithm, byte[]> verifiedSignatures = new HashMap<>();
-            public List<AdditionalAttribute> additionalAttributes = new ArrayList<>();
-            public byte[] signedData;
-
-            private final List<IssueWithParams> mWarnings = new ArrayList<>();
-            private final List<IssueWithParams> mErrors = new ArrayList<>();
-
-            public void addError(Issue msg, Object... parameters) {
-                mErrors.add(new IssueWithParams(msg, parameters));
-            }
-
-            public void addWarning(Issue msg, Object... parameters) {
-                mWarnings.add(new IssueWithParams(msg, parameters));
-            }
-
-            public boolean containsErrors() {
-                return !mErrors.isEmpty();
-            }
-
-            public List<IssueWithParams> getErrors() {
-                return mErrors;
-            }
-
-            public List<IssueWithParams> getWarnings() {
-                return mWarnings;
-            }
-
-            public static class ContentDigest {
-                private final int mSignatureAlgorithmId;
-                private final byte[] mValue;
-
-                public ContentDigest(int signatureAlgorithmId, byte[] value) {
-                    mSignatureAlgorithmId  = signatureAlgorithmId;
-                    mValue = value;
-                }
-
-                public int getSignatureAlgorithmId() {
-                    return mSignatureAlgorithmId;
-                }
-
-                public byte[] getValue() {
-                    return mValue;
-                }
-            }
-
-            public static class Signature {
-                private final int mAlgorithmId;
-                private final byte[] mValue;
-
-                public Signature(int algorithmId, byte[] value) {
-                    mAlgorithmId  = algorithmId;
-                    mValue = value;
-                }
-
-                public int getAlgorithmId() {
-                    return mAlgorithmId;
-                }
-
-                public byte[] getValue() {
-                    return mValue;
-                }
-            }
-
-            public static class AdditionalAttribute {
-                private final int mId;
-                private final byte[] mValue;
-
-                public AdditionalAttribute(int id, byte[] value) {
-                    mId  = id;
-                    mValue = value.clone();
-                }
-
-                public int getId() {
-                    return mId;
-                }
-
-                public byte[] getValue() {
-                    return mValue.clone();
-                }
-            }
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/jar/ManifestParser.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/jar/ManifestParser.java
deleted file mode 100644
index 793300c..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/jar/ManifestParser.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.jar;
-
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.jar.Attributes;
-
-/**
- * JAR manifest and signature file parser.
- *
- * <p>These files consist of a main section followed by individual sections. Individual sections
- * are named, their names referring to JAR entries.
- *
- * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#JAR_Manifest">JAR Manifest format</a>
- */
-public class ManifestParser {
-
-    private final byte[] mManifest;
-    private int mOffset;
-    private int mEndOffset;
-
-    private String mBufferedLine;
-
-    /**
-     * Constructs a new {@code ManifestParser} with the provided input.
-     */
-    public ManifestParser(byte[] data) {
-        this(data, 0, data.length);
-    }
-
-    /**
-     * Constructs a new {@code ManifestParser} with the provided input.
-     */
-    public ManifestParser(byte[] data, int offset, int length) {
-        mManifest = data;
-        mOffset = offset;
-        mEndOffset = offset + length;
-    }
-
-    /**
-     * Returns the remaining sections of this file.
-     */
-    public List<Section> readAllSections() {
-        List<Section> sections = new ArrayList<>();
-        Section section;
-        while ((section = readSection()) != null) {
-            sections.add(section);
-        }
-        return sections;
-    }
-
-    /**
-     * Returns the next section from this file or {@code null} if end of file has been reached.
-     */
-    public Section readSection() {
-        // Locate the first non-empty line
-        int sectionStartOffset;
-        String attr;
-        do {
-            sectionStartOffset = mOffset;
-            attr = readAttribute();
-            if (attr == null) {
-                return null;
-            }
-        } while (attr.length() == 0);
-        List<Attribute> attrs = new ArrayList<>();
-        attrs.add(parseAttr(attr));
-
-        // Read attributes until end of section reached
-        while (true) {
-            attr = readAttribute();
-            if ((attr == null) || (attr.length() == 0)) {
-                // End of section
-                break;
-            }
-            attrs.add(parseAttr(attr));
-        }
-
-        int sectionEndOffset = mOffset;
-        int sectionSizeBytes = sectionEndOffset - sectionStartOffset;
-
-        return new Section(sectionStartOffset, sectionSizeBytes, attrs);
-    }
-
-    private static Attribute parseAttr(String attr) {
-        int delimiterIndex = attr.indexOf(':');
-        if (delimiterIndex == -1) {
-            return new Attribute(attr.trim(), "");
-        } else {
-            return new Attribute(
-                    attr.substring(0, delimiterIndex).trim(),
-                    attr.substring(delimiterIndex + 1).trim());
-        }
-    }
-
-    /**
-     * Returns the next attribute or empty {@code String} if end of section has been reached or
-     * {@code null} if end of input has been reached.
-     */
-    private String readAttribute() {
-        // Check whether end of section was reached during previous invocation
-        if ((mBufferedLine != null) && (mBufferedLine.length() == 0)) {
-            mBufferedLine = null;
-            return "";
-        }
-
-        // Read the next line
-        String line = readLine();
-        if (line == null) {
-            // End of input
-            if (mBufferedLine != null) {
-                String result = mBufferedLine;
-                mBufferedLine = null;
-                return result;
-            }
-            return null;
-        }
-
-        // Consume the read line
-        if (line.length() == 0) {
-            // End of section
-            if (mBufferedLine != null) {
-                String result = mBufferedLine;
-                mBufferedLine = "";
-                return result;
-            }
-            return "";
-        }
-        StringBuilder attrLine;
-        if (mBufferedLine == null) {
-            attrLine = new StringBuilder(line);
-        } else {
-            if (!line.startsWith(" ")) {
-                // The most common case: buffered line is a full attribute
-                String result = mBufferedLine;
-                mBufferedLine = line;
-                return result;
-            }
-            attrLine = new StringBuilder(mBufferedLine);
-            mBufferedLine = null;
-            attrLine.append(line.substring(1));
-        }
-
-        // Everything's buffered in attrLine now. mBufferedLine is null
-
-        // Read more lines
-        while (true) {
-            line = readLine();
-            if (line == null) {
-                // End of input
-                return attrLine.toString();
-            } else if (line.length() == 0) {
-                // End of section
-                mBufferedLine = ""; // make this method return "end of section" next time
-                return attrLine.toString();
-            }
-            if (line.startsWith(" ")) {
-                // Continuation line
-                attrLine.append(line.substring(1));
-            } else {
-                // Next attribute
-                mBufferedLine = line;
-                return attrLine.toString();
-            }
-        }
-    }
-
-    /**
-     * Returns the next line (without line delimiter characters) or {@code null} if end of input has
-     * been reached.
-     */
-    private String readLine() {
-        if (mOffset >= mEndOffset) {
-            return null;
-        }
-        int startOffset = mOffset;
-        int newlineStartOffset = -1;
-        int newlineEndOffset = -1;
-        for (int i = startOffset; i < mEndOffset; i++) {
-            byte b = mManifest[i];
-            if (b == '\r') {
-                newlineStartOffset = i;
-                int nextIndex = i + 1;
-                if ((nextIndex < mEndOffset) && (mManifest[nextIndex] == '\n')) {
-                    newlineEndOffset = nextIndex + 1;
-                    break;
-                }
-                newlineEndOffset = nextIndex;
-                break;
-            } else if (b == '\n') {
-                newlineStartOffset = i;
-                newlineEndOffset = i + 1;
-                break;
-            }
-        }
-        if (newlineStartOffset == -1) {
-            newlineStartOffset = mEndOffset;
-            newlineEndOffset = mEndOffset;
-        }
-        mOffset = newlineEndOffset;
-
-        int lineLengthBytes = newlineStartOffset - startOffset;
-        if (lineLengthBytes == 0) {
-            return "";
-        }
-        return new String(mManifest, startOffset, lineLengthBytes, StandardCharsets.UTF_8);
-    }
-
-
-    /**
-     * Attribute.
-     */
-    public static class Attribute {
-        private final String mName;
-        private final String mValue;
-
-        /**
-         * Constructs a new {@code Attribute} with the provided name and value.
-         */
-        public Attribute(String name, String value) {
-            mName = name;
-            mValue = value;
-        }
-
-        /**
-         * Returns this attribute's name.
-         */
-        public String getName() {
-            return mName;
-        }
-
-        /**
-         * Returns this attribute's value.
-         */
-        public String getValue() {
-            return mValue;
-        }
-    }
-
-    /**
-     * Section.
-     */
-    public static class Section {
-        private final int mStartOffset;
-        private final int mSizeBytes;
-        private final String mName;
-        private final List<Attribute> mAttributes;
-
-        /**
-         * Constructs a new {@code Section}.
-         *
-         * @param startOffset start offset (in bytes) of the section in the input file
-         * @param sizeBytes size (in bytes) of the section in the input file
-         * @param attrs attributes contained in the section
-         */
-        public Section(int startOffset, int sizeBytes, List<Attribute> attrs) {
-            mStartOffset = startOffset;
-            mSizeBytes = sizeBytes;
-            String sectionName = null;
-            if (!attrs.isEmpty()) {
-                Attribute firstAttr = attrs.get(0);
-                if ("Name".equalsIgnoreCase(firstAttr.getName())) {
-                    sectionName = firstAttr.getValue();
-                }
-            }
-            mName = sectionName;
-            mAttributes = Collections.unmodifiableList(new ArrayList<>(attrs));
-        }
-
-        public String getName() {
-            return mName;
-        }
-
-        /**
-         * Returns the offset (in bytes) at which this section starts in the input.
-         */
-        public int getStartOffset() {
-            return mStartOffset;
-        }
-
-        /**
-         * Returns the size (in bytes) of this section in the input.
-         */
-        public int getSizeBytes() {
-            return mSizeBytes;
-        }
-
-        /**
-         * Returns this section's attributes, in the order in which they appear in the input.
-         */
-        public List<Attribute> getAttributes() {
-            return mAttributes;
-        }
-
-        /**
-         * Returns the value of the specified attribute in this section or {@code null} if this
-         * section does not contain a matching attribute.
-         */
-        public String getAttributeValue(Attributes.Name name) {
-            return getAttributeValue(name.toString());
-        }
-
-        /**
-         * Returns the value of the specified attribute in this section or {@code null} if this
-         * section does not contain a matching attribute.
-         *
-         * @param name name of the attribute. Attribute names are case-insensitive.
-         */
-        public String getAttributeValue(String name) {
-            for (Attribute attr : mAttributes) {
-                if (attr.getName().equalsIgnoreCase(name)) {
-                    return attr.getValue();
-                }
-            }
-            return null;
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/jar/ManifestWriter.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/jar/ManifestWriter.java
deleted file mode 100644
index 13b1aaf..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/jar/ManifestWriter.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.jar;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.jar.Attributes;
-
-/**
- * Producer of {@code META-INF/MANIFEST.MF} file.
- *
- * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#JAR_Manifest">JAR Manifest format</a>
- */
-public abstract class ManifestWriter {
-
-    private static final byte[] CRLF = new byte[] {'\r', '\n'};
-    private static final int MAX_LINE_LENGTH = 70;
-
-    private ManifestWriter() {}
-
-    public static void writeMainSection(OutputStream out, Attributes attributes)
-            throws IOException {
-
-        // Main section must start with the Manifest-Version attribute.
-        // See https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File.
-        String manifestVersion = attributes.getValue(Attributes.Name.MANIFEST_VERSION);
-        if (manifestVersion == null) {
-            throw new IllegalArgumentException(
-                    "Mandatory " + Attributes.Name.MANIFEST_VERSION + " attribute missing");
-        }
-        writeAttribute(out, Attributes.Name.MANIFEST_VERSION, manifestVersion);
-
-        if (attributes.size() > 1) {
-            SortedMap<String, String> namedAttributes = getAttributesSortedByName(attributes);
-            namedAttributes.remove(Attributes.Name.MANIFEST_VERSION.toString());
-            writeAttributes(out, namedAttributes);
-        }
-        writeSectionDelimiter(out);
-    }
-
-    public static void writeIndividualSection(OutputStream out, String name, Attributes attributes)
-            throws IOException {
-        writeAttribute(out, "Name", name);
-
-        if (!attributes.isEmpty()) {
-            writeAttributes(out, getAttributesSortedByName(attributes));
-        }
-        writeSectionDelimiter(out);
-    }
-
-    static void writeSectionDelimiter(OutputStream out) throws IOException {
-        out.write(CRLF);
-    }
-
-    static void writeAttribute(OutputStream  out, Attributes.Name name, String value)
-            throws IOException {
-        writeAttribute(out, name.toString(), value);
-    }
-
-    private static void writeAttribute(OutputStream  out, String name, String value)
-            throws IOException {
-        writeLine(out, name + ": " + value);
-    }
-
-    private static void writeLine(OutputStream  out, String line) throws IOException {
-        byte[] lineBytes = line.getBytes(StandardCharsets.UTF_8);
-        int offset = 0;
-        int remaining = lineBytes.length;
-        boolean firstLine = true;
-        while (remaining > 0) {
-            int chunkLength;
-            if (firstLine) {
-                // First line
-                chunkLength = Math.min(remaining, MAX_LINE_LENGTH);
-            } else {
-                // Continuation line
-                out.write(CRLF);
-                out.write(' ');
-                chunkLength = Math.min(remaining, MAX_LINE_LENGTH - 1);
-            }
-            out.write(lineBytes, offset, chunkLength);
-            offset += chunkLength;
-            remaining -= chunkLength;
-            firstLine = false;
-        }
-        out.write(CRLF);
-    }
-
-    static SortedMap<String, String> getAttributesSortedByName(Attributes attributes) {
-        Set<Map.Entry<Object, Object>> attributesEntries = attributes.entrySet();
-        SortedMap<String, String> namedAttributes = new TreeMap<String, String>();
-        for (Map.Entry<Object, Object> attribute : attributesEntries) {
-            String attrName = attribute.getKey().toString();
-            String attrValue = attribute.getValue().toString();
-            namedAttributes.put(attrName, attrValue);
-        }
-        return namedAttributes;
-    }
-
-    static void writeAttributes(
-            OutputStream out, SortedMap<String, String> attributesSortedByName) throws IOException {
-        for (Map.Entry<String, String> attribute : attributesSortedByName.entrySet()) {
-            String attrName = attribute.getKey();
-            String attrValue = attribute.getValue();
-            writeAttribute(out, attrName, attrValue);
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/jar/SignatureFileWriter.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/jar/SignatureFileWriter.java
deleted file mode 100644
index 94ae280..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/jar/SignatureFileWriter.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.jar;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.SortedMap;
-import java.util.jar.Attributes;
-
-/**
- * Producer of JAR signature file ({@code *.SF}).
- *
- * @see <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#JAR_Manifest">JAR Manifest format</a>
- */
-public abstract class SignatureFileWriter {
-    private SignatureFileWriter() {}
-
-    public static void writeMainSection(OutputStream out, Attributes attributes)
-            throws IOException {
-
-        // Main section must start with the Signature-Version attribute.
-        // See https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File.
-        String signatureVersion = attributes.getValue(Attributes.Name.SIGNATURE_VERSION);
-        if (signatureVersion == null) {
-            throw new IllegalArgumentException(
-                    "Mandatory " + Attributes.Name.SIGNATURE_VERSION + " attribute missing");
-        }
-        ManifestWriter.writeAttribute(out, Attributes.Name.SIGNATURE_VERSION, signatureVersion);
-
-        if (attributes.size() > 1) {
-            SortedMap<String, String> namedAttributes =
-                    ManifestWriter.getAttributesSortedByName(attributes);
-            namedAttributes.remove(Attributes.Name.SIGNATURE_VERSION.toString());
-            ManifestWriter.writeAttributes(out, namedAttributes);
-        }
-        writeSectionDelimiter(out);
-    }
-
-    public static void writeIndividualSection(OutputStream out, String name, Attributes attributes)
-            throws IOException {
-        ManifestWriter.writeIndividualSection(out, name, attributes);
-    }
-
-    public static void writeSectionDelimiter(OutputStream out) throws IOException {
-        ManifestWriter.writeSectionDelimiter(out);
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/AndroidSdkVersion.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/AndroidSdkVersion.java
deleted file mode 100644
index 3e9d039..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/AndroidSdkVersion.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.util;
-
-/**
- * Android SDK version / API Level constants.
- */
-public abstract class AndroidSdkVersion {
-
-    /** Hidden constructor to prevent instantiation. */
-    private AndroidSdkVersion() {}
-
-    /** Android 2.3. */
-    public static final int GINGERBREAD = 9;
-
-    /** Android 4.3. The revenge of the beans. */
-    public static final int JELLY_BEAN_MR2 = 18;
-
-    /** Android 5.0. A flat one with beautiful shadows. But still tasty. */
-    public static final int LOLLIPOP = 21;
-
-    // TODO: Update Javadoc / constant name once N is assigned a proper name / version code.
-    /** Android N. */
-    public static final int N = 24;
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/ByteBufferDataSource.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/ByteBufferDataSource.java
deleted file mode 100644
index b2d9ca1..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/ByteBufferDataSource.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.util;
-
-import com.android.apksigner.core.util.DataSink;
-import com.android.apksigner.core.util.DataSource;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * {@link DataSource} backed by a {@link ByteBuffer}.
- */
-public class ByteBufferDataSource implements DataSource {
-
-    private final ByteBuffer mBuffer;
-    private final int mSize;
-
-    /**
-     * Constructs a new {@code ByteBufferDigestSource} based on the data contained in the provided
-     * buffer between the buffer's position and limit.
-     */
-    public ByteBufferDataSource(ByteBuffer buffer) {
-        this(buffer, true);
-    }
-
-    /**
-     * Constructs a new {@code ByteBufferDigestSource} based on the data contained in the provided
-     * buffer between the buffer's position and limit.
-     */
-    private ByteBufferDataSource(ByteBuffer buffer, boolean sliceRequired) {
-        mBuffer = (sliceRequired) ? buffer.slice() : buffer;
-        mSize = buffer.remaining();
-    }
-
-    @Override
-    public long size() {
-        return mSize;
-    }
-
-    @Override
-    public ByteBuffer getByteBuffer(long offset, int size) {
-        checkChunkValid(offset, size);
-
-        // checkChunkValid ensures that it's OK to cast offset to int.
-        int chunkPosition = (int) offset;
-        int chunkLimit = chunkPosition + size;
-        // Creating a slice of ByteBuffer modifies the state of the source ByteBuffer (position
-        // and limit fields, to be more specific). We thus use synchronization around these
-        // state-changing operations to make instances of this class thread-safe.
-        synchronized (mBuffer) {
-            // ByteBuffer.limit(int) and .position(int) check that that the position >= limit
-            // invariant is not broken. Thus, the only way to safely change position and limit
-            // without caring about their current values is to first set position to 0 or set the
-            // limit to capacity.
-            mBuffer.position(0);
-
-            mBuffer.limit(chunkLimit);
-            mBuffer.position(chunkPosition);
-            return mBuffer.slice();
-        }
-    }
-
-    @Override
-    public void copyTo(long offset, int size, ByteBuffer dest) {
-        dest.put(getByteBuffer(offset, size));
-    }
-
-    @Override
-    public void feed(long offset, long size, DataSink sink) throws IOException {
-        if ((size < 0) || (size > mSize)) {
-            throw new IllegalArgumentException("size: " + size + ", source size: " + mSize);
-        }
-        sink.consume(getByteBuffer(offset, (int) size));
-    }
-
-    @Override
-    public ByteBufferDataSource slice(long offset, long size) {
-        if ((offset == 0) && (size == mSize)) {
-            return this;
-        }
-        if ((size < 0) || (size > mSize)) {
-            throw new IllegalArgumentException("size: " + size + ", source size: " + mSize);
-        }
-        return new ByteBufferDataSource(
-                getByteBuffer(offset, (int) size),
-                false // no need to slice -- it's already a slice
-                );
-    }
-
-    private void checkChunkValid(long offset, long size) {
-        if (offset < 0) {
-            throw new IllegalArgumentException("offset: " + offset);
-        }
-        if (size < 0) {
-            throw new IllegalArgumentException("size: " + size);
-        }
-        if (offset > mSize) {
-            throw new IllegalArgumentException(
-                    "offset (" + offset + ") > source size (" + mSize + ")");
-        }
-        long endOffset = offset + size;
-        if (endOffset < offset) {
-            throw new IllegalArgumentException(
-                    "offset (" + offset + ") + size (" + size + ") overflow");
-        }
-        if (endOffset > mSize) {
-            throw new IllegalArgumentException(
-                    "offset (" + offset + ") + size (" + size + ") > source size (" + mSize  +")");
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/ByteBufferSink.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/ByteBufferSink.java
deleted file mode 100644
index 8c57905..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/ByteBufferSink.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.util;
-
-import com.android.apksigner.core.util.DataSink;
-
-import java.io.IOException;
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-
-/**
- * Data sink which stores all received data into the associated {@link ByteBuffer}.
- */
-public class ByteBufferSink implements DataSink {
-
-    private final ByteBuffer mBuffer;
-
-    public ByteBufferSink(ByteBuffer buffer) {
-        mBuffer = buffer;
-    }
-
-    @Override
-    public void consume(byte[] buf, int offset, int length) throws IOException {
-        try {
-            mBuffer.put(buf, offset, length);
-        } catch (BufferOverflowException e) {
-            throw new IOException(
-                    "Insufficient space in output buffer for " + length + " bytes", e);
-        }
-    }
-
-    @Override
-    public void consume(ByteBuffer buf) throws IOException {
-        int length = buf.remaining();
-        try {
-            mBuffer.put(buf);
-        } catch (BufferOverflowException e) {
-            throw new IOException(
-                    "Insufficient space in output buffer for " + length + " bytes", e);
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/DelegatingX509Certificate.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/DelegatingX509Certificate.java
deleted file mode 100644
index 936cfa9..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/DelegatingX509Certificate.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.util;
-
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Principal;
-import java.security.PublicKey;
-import java.security.SignatureException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateNotYetValidException;
-import java.security.cert.X509Certificate;
-import java.util.Date;
-import java.util.Set;
-
-/**
- * {@link X509Certificate} which delegates all method invocations to the provided delegate
- * {@code X509Certificate}.
- */
-public class DelegatingX509Certificate extends X509Certificate {
-    private final X509Certificate mDelegate;
-
-    public DelegatingX509Certificate(X509Certificate delegate) {
-        this.mDelegate = delegate;
-    }
-
-    @Override
-    public Set<String> getCriticalExtensionOIDs() {
-        return mDelegate.getCriticalExtensionOIDs();
-    }
-
-    @Override
-    public byte[] getExtensionValue(String oid) {
-        return mDelegate.getExtensionValue(oid);
-    }
-
-    @Override
-    public Set<String> getNonCriticalExtensionOIDs() {
-        return mDelegate.getNonCriticalExtensionOIDs();
-    }
-
-    @Override
-    public boolean hasUnsupportedCriticalExtension() {
-        return mDelegate.hasUnsupportedCriticalExtension();
-    }
-
-    @Override
-    public void checkValidity()
-            throws CertificateExpiredException, CertificateNotYetValidException {
-        mDelegate.checkValidity();
-    }
-
-    @Override
-    public void checkValidity(Date date)
-            throws CertificateExpiredException, CertificateNotYetValidException {
-        mDelegate.checkValidity(date);
-    }
-
-    @Override
-    public int getVersion() {
-        return mDelegate.getVersion();
-    }
-
-    @Override
-    public BigInteger getSerialNumber() {
-        return mDelegate.getSerialNumber();
-    }
-
-    @Override
-    public Principal getIssuerDN() {
-        return mDelegate.getIssuerDN();
-    }
-
-    @Override
-    public Principal getSubjectDN() {
-        return mDelegate.getSubjectDN();
-    }
-
-    @Override
-    public Date getNotBefore() {
-        return mDelegate.getNotBefore();
-    }
-
-    @Override
-    public Date getNotAfter() {
-        return mDelegate.getNotAfter();
-    }
-
-    @Override
-    public byte[] getTBSCertificate() throws CertificateEncodingException {
-        return mDelegate.getTBSCertificate();
-    }
-
-    @Override
-    public byte[] getSignature() {
-        return mDelegate.getSignature();
-    }
-
-    @Override
-    public String getSigAlgName() {
-        return mDelegate.getSigAlgName();
-    }
-
-    @Override
-    public String getSigAlgOID() {
-        return mDelegate.getSigAlgOID();
-    }
-
-    @Override
-    public byte[] getSigAlgParams() {
-        return mDelegate.getSigAlgParams();
-    }
-
-    @Override
-    public boolean[] getIssuerUniqueID() {
-        return mDelegate.getIssuerUniqueID();
-    }
-
-    @Override
-    public boolean[] getSubjectUniqueID() {
-        return mDelegate.getSubjectUniqueID();
-    }
-
-    @Override
-    public boolean[] getKeyUsage() {
-        return mDelegate.getKeyUsage();
-    }
-
-    @Override
-    public int getBasicConstraints() {
-        return mDelegate.getBasicConstraints();
-    }
-
-    @Override
-    public byte[] getEncoded() throws CertificateEncodingException {
-        return mDelegate.getEncoded();
-    }
-
-    @Override
-    public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException,
-            InvalidKeyException, NoSuchProviderException, SignatureException {
-        mDelegate.verify(key);
-    }
-
-    @Override
-    public void verify(PublicKey key, String sigProvider)
-            throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
-            NoSuchProviderException, SignatureException {
-        mDelegate.verify(key, sigProvider);
-    }
-
-    @Override
-    public String toString() {
-        return mDelegate.toString();
-    }
-
-    @Override
-    public PublicKey getPublicKey() {
-        return mDelegate.getPublicKey();
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/InclusiveIntRange.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/InclusiveIntRange.java
deleted file mode 100644
index baf3655..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/InclusiveIntRange.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.util;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Inclusive interval of integers.
- */
-public class InclusiveIntRange {
-    private final int min;
-    private final int max;
-
-    private InclusiveIntRange(int min, int max) {
-        this.min = min;
-        this.max = max;
-    }
-
-    public int getMin() {
-        return min;
-    }
-
-    public int getMax() {
-        return max;
-    }
-
-    public static InclusiveIntRange fromTo(int min, int max) {
-        return new InclusiveIntRange(min, max);
-    }
-
-    public static InclusiveIntRange from(int min) {
-        return new InclusiveIntRange(min, Integer.MAX_VALUE);
-    }
-
-    public List<InclusiveIntRange> getValuesNotIn(
-            List<InclusiveIntRange> sortedNonOverlappingRanges) {
-        if (sortedNonOverlappingRanges.isEmpty()) {
-            return Collections.singletonList(this);
-        }
-
-        int testValue = min;
-        List<InclusiveIntRange> result = null;
-        for (InclusiveIntRange range : sortedNonOverlappingRanges) {
-            int rangeMax = range.max;
-            if (testValue > rangeMax) {
-                continue;
-            }
-            int rangeMin = range.min;
-            if (testValue < range.min) {
-                if (result == null) {
-                    result = new ArrayList<>();
-                }
-                result.add(fromTo(testValue, rangeMin - 1));
-            }
-            if (rangeMax >= max) {
-                return (result != null) ? result : Collections.emptyList();
-            }
-            testValue = rangeMax + 1;
-        }
-        if (testValue <= max) {
-            if (result == null) {
-                result = new ArrayList<>(1);
-            }
-            result.add(fromTo(testValue, max));
-        }
-        return (result != null) ? result : Collections.emptyList();
-    }
-
-    @Override
-    public String toString() {
-        return "[" + min + ", " + ((max < Integer.MAX_VALUE) ? (max + "]") : "\u221e)");
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/MessageDigestSink.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/MessageDigestSink.java
deleted file mode 100644
index 45bb30e..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/MessageDigestSink.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.apksigner.core.internal.util;
-
-import com.android.apksigner.core.util.DataSink;
-
-import java.nio.ByteBuffer;
-import java.security.MessageDigest;
-
-/**
- * Data sink which feeds all received data into the associated {@link MessageDigest} instances. Each
- * {@code MessageDigest} instance receives the same data.
- */
-public class MessageDigestSink implements DataSink {
-
-    private final MessageDigest[] mMessageDigests;
-
-    public MessageDigestSink(MessageDigest[] digests) {
-        mMessageDigests = digests;
-    }
-
-    @Override
-    public void consume(byte[] buf, int offset, int length) {
-        for (MessageDigest md : mMessageDigests) {
-            md.update(buf, offset, length);
-        }
-    }
-
-    @Override
-    public void consume(ByteBuffer buf) {
-        int originalPosition = buf.position();
-        for (MessageDigest md : mMessageDigests) {
-            // Reset the position back to the original because the previous iteration's
-            // MessageDigest.update set the buffer's position to the buffer's limit.
-            buf.position(originalPosition);
-            md.update(buf);
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/OutputStreamDataSink.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/OutputStreamDataSink.java
deleted file mode 100644
index bf18ca0..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/OutputStreamDataSink.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.util;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-
-import com.android.apksigner.core.util.DataSink;
-
-/**
- * {@link DataSink} which outputs received data into the associated {@link OutputStream}.
- */
-public class OutputStreamDataSink implements DataSink {
-
-    private static final int MAX_READ_CHUNK_SIZE = 65536;
-
-    private final OutputStream mOut;
-
-    /**
-     * Constructs a new {@code OutputStreamDataSink} which outputs received data into the provided
-     * {@link OutputStream}.
-     */
-    public OutputStreamDataSink(OutputStream out) {
-        if (out == null) {
-            throw new NullPointerException("out == null");
-        }
-        mOut = out;
-    }
-
-    /**
-     * Returns {@link OutputStream} into which this data sink outputs received data.
-     */
-    public OutputStream getOutputStream() {
-        return mOut;
-    }
-
-    @Override
-    public void consume(byte[] buf, int offset, int length) throws IOException {
-        mOut.write(buf, offset, length);
-    }
-
-    @Override
-    public void consume(ByteBuffer buf) throws IOException {
-        if (!buf.hasRemaining()) {
-            return;
-        }
-
-        if (buf.hasArray()) {
-            mOut.write(
-                    buf.array(),
-                    buf.arrayOffset() + buf.position(),
-                    buf.remaining());
-            buf.position(buf.limit());
-        } else {
-            byte[] tmp = new byte[Math.min(buf.remaining(), MAX_READ_CHUNK_SIZE)];
-            while (buf.hasRemaining()) {
-                int chunkSize = Math.min(buf.remaining(), tmp.length);
-                buf.get(tmp, 0, chunkSize);
-                mOut.write(tmp, 0, chunkSize);
-            }
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/Pair.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/Pair.java
deleted file mode 100644
index d59af41..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/Pair.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.util;
-
-/**
- * Pair of two elements.
- */
-public final class Pair<A, B> {
-    private final A mFirst;
-    private final B mSecond;
-
-    private Pair(A first, B second) {
-        mFirst = first;
-        mSecond = second;
-    }
-
-    public static <A, B> Pair<A, B> of(A first, B second) {
-        return new Pair<A, B>(first, second);
-    }
-
-    public A getFirst() {
-        return mFirst;
-    }
-
-    public B getSecond() {
-        return mSecond;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((mFirst == null) ? 0 : mFirst.hashCode());
-        result = prime * result + ((mSecond == null) ? 0 : mSecond.hashCode());
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        @SuppressWarnings("rawtypes")
-        Pair other = (Pair) obj;
-        if (mFirst == null) {
-            if (other.mFirst != null) {
-                return false;
-            }
-        } else if (!mFirst.equals(other.mFirst)) {
-            return false;
-        }
-        if (mSecond == null) {
-            if (other.mSecond != null) {
-                return false;
-            }
-        } else if (!mSecond.equals(other.mSecond)) {
-            return false;
-        }
-        return true;
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/RandomAccessFileDataSink.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/RandomAccessFileDataSink.java
deleted file mode 100644
index 2198492..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/RandomAccessFileDataSink.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.util;
-
-import com.android.apksigner.core.util.DataSink;
-
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-
-/**
- * {@link DataSink} which outputs received data into the associated file, sequentially.
- */
-public class RandomAccessFileDataSink implements DataSink {
-
-    private final RandomAccessFile mFile;
-    private final FileChannel mFileChannel;
-    private long mPosition;
-
-    /**
-     * Constructs a new {@code RandomAccessFileDataSink} which stores output starting from the
-     * beginning of the provided file.
-     */
-    public RandomAccessFileDataSink(RandomAccessFile file) {
-        this(file, 0);
-    }
-
-    /**
-     * Constructs a new {@code RandomAccessFileDataSink} which stores output starting from the
-     * specified position of the provided file.
-     */
-    public RandomAccessFileDataSink(RandomAccessFile file, long startPosition) {
-        if (file == null) {
-            throw new NullPointerException("file == null");
-        }
-        if (startPosition < 0) {
-            throw new IllegalArgumentException("startPosition: " + startPosition);
-        }
-        mFile = file;
-        mFileChannel = file.getChannel();
-        mPosition = startPosition;
-    }
-
-    @Override
-    public void consume(byte[] buf, int offset, int length) throws IOException {
-        if (length == 0) {
-            return;
-        }
-
-        synchronized (mFile) {
-            mFile.seek(mPosition);
-            mFile.write(buf, offset, length);
-            mPosition += length;
-        }
-    }
-
-    @Override
-    public void consume(ByteBuffer buf) throws IOException {
-        int length = buf.remaining();
-        if (length == 0) {
-            return;
-        }
-
-        synchronized (mFile) {
-            mFile.seek(mPosition);
-            while (buf.hasRemaining()) {
-                mFileChannel.write(buf);
-            }
-            mPosition += length;
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/RandomAccessFileDataSource.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/RandomAccessFileDataSource.java
deleted file mode 100644
index 208033d..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/RandomAccessFileDataSource.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.util;
-
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-
-import com.android.apksigner.core.util.DataSink;
-import com.android.apksigner.core.util.DataSource;
-
-/**
- * {@link DataSource} backed by a {@link RandomAccessFile}.
- */
-public class RandomAccessFileDataSource implements DataSource {
-
-    private static final int MAX_READ_CHUNK_SIZE = 65536;
-
-    private final RandomAccessFile mFile;
-    private final long mOffset;
-    private final long mSize;
-
-    /**
-     * Constructs a new {@code RandomAccessFileDataSource} based on the data contained in the
-     * specified the whole file. Changes to the contents of the file, including the size of the
-     * file, will be visible in this data source.
-     */
-    public RandomAccessFileDataSource(RandomAccessFile file) {
-        mFile = file;
-        mOffset = 0;
-        mSize = -1;
-    }
-
-    /**
-     * Constructs a new {@code RandomAccessFileDataSource} based on the data contained in the
-     * specified region of the provided file. Changes to the contents of the file will be visible in
-     * this data source.
-     */
-    public RandomAccessFileDataSource(RandomAccessFile file, long offset, long size) {
-        if (offset < 0) {
-            throw new IllegalArgumentException("offset: " + size);
-        }
-        if (size < 0) {
-            throw new IllegalArgumentException("size: " + size);
-        }
-        mFile = file;
-        mOffset = offset;
-        mSize = size;
-    }
-
-    @Override
-    public long size() {
-        if (mSize == -1) {
-            try {
-                return mFile.length();
-            } catch (IOException e) {
-                return 0;
-            }
-        } else {
-            return mSize;
-        }
-    }
-
-    @Override
-    public RandomAccessFileDataSource slice(long offset, long size) {
-        long sourceSize = size();
-        checkChunkValid(offset, size, sourceSize);
-        if ((offset == 0) && (size == sourceSize)) {
-            return this;
-        }
-
-        return new RandomAccessFileDataSource(mFile, mOffset + offset, size);
-    }
-
-    @Override
-    public void feed(long offset, long size, DataSink sink) throws IOException {
-        long sourceSize = size();
-        checkChunkValid(offset, size, sourceSize);
-        if (size == 0) {
-            return;
-        }
-
-        long chunkOffsetInFile = mOffset + offset;
-        long remaining = size;
-        byte[] buf = new byte[(int) Math.min(remaining, MAX_READ_CHUNK_SIZE)];
-        while (remaining > 0) {
-            int chunkSize = (int) Math.min(remaining, buf.length);
-            synchronized (mFile) {
-                mFile.seek(chunkOffsetInFile);
-                mFile.readFully(buf, 0, chunkSize);
-            }
-            sink.consume(buf, 0, chunkSize);
-            chunkOffsetInFile += chunkSize;
-            remaining -= chunkSize;
-        }
-    }
-
-    @Override
-    public void copyTo(long offset, int size, ByteBuffer dest) throws IOException {
-        long sourceSize = size();
-        checkChunkValid(offset, size, sourceSize);
-        if (size == 0) {
-            return;
-        }
-
-        long offsetInFile = mOffset + offset;
-        int remaining = size;
-        FileChannel fileChannel = mFile.getChannel();
-        while (remaining > 0) {
-            int chunkSize;
-            synchronized (mFile) {
-                fileChannel.position(offsetInFile);
-                chunkSize = fileChannel.read(dest);
-            }
-            offsetInFile += chunkSize;
-            remaining -= chunkSize;
-        }
-    }
-
-    @Override
-    public ByteBuffer getByteBuffer(long offset, int size) throws IOException {
-        ByteBuffer result = ByteBuffer.allocate(size);
-        copyTo(offset, size, result);
-        result.flip();
-        return result;
-    }
-
-    private static void checkChunkValid(long offset, long size, long sourceSize) {
-        if (offset < 0) {
-            throw new IllegalArgumentException("offset: " + offset);
-        }
-        if (size < 0) {
-            throw new IllegalArgumentException("size: " + size);
-        }
-        if (offset > sourceSize) {
-            throw new IllegalArgumentException(
-                    "offset (" + offset + ") > source size (" + sourceSize + ")");
-        }
-        long endOffset = offset + size;
-        if (endOffset < offset) {
-            throw new IllegalArgumentException(
-                    "offset (" + offset + ") + size (" + size + ") overflow");
-        }
-        if (endOffset > sourceSize) {
-            throw new IllegalArgumentException(
-                    "offset (" + offset + ") + size (" + size
-                            + ") > source size (" + sourceSize  +")");
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/CentralDirectoryRecord.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/CentralDirectoryRecord.java
deleted file mode 100644
index 141d01e..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/CentralDirectoryRecord.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.zip;
-
-import com.android.apksigner.core.zip.ZipFormatException;
-
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.charset.StandardCharsets;
-import java.util.Comparator;
-
-/**
- * ZIP Central Directory (CD) Record.
- */
-public class CentralDirectoryRecord {
-
-    /**
-     * Comparator which compares records by the offset of the corresponding Local File Header in the
-     * archive.
-     */
-    public static final Comparator<CentralDirectoryRecord> BY_LOCAL_FILE_HEADER_OFFSET_COMPARATOR =
-            new ByLocalFileHeaderOffsetComparator();
-
-    private static final int RECORD_SIGNATURE = 0x02014b50;
-    private static final int HEADER_SIZE_BYTES = 46;
-
-    private static final int LAST_MODIFICATION_TIME_OFFSET =  12;
-    private static final int LOCAL_FILE_HEADER_OFFSET_OFFSET = 42;
-    private static final int NAME_OFFSET = HEADER_SIZE_BYTES;
-
-    private final ByteBuffer mData;
-    private final int mLastModificationTime;
-    private final int mLastModificationDate;
-    private final long mCrc32;
-    private final long mCompressedSize;
-    private final long mUncompressedSize;
-    private final long mLocalFileHeaderOffset;
-    private final String mName;
-    private final int mNameSizeBytes;
-
-    private CentralDirectoryRecord(
-            ByteBuffer data,
-            int lastModificationTime,
-            int lastModificationDate,
-            long crc32,
-            long compressedSize,
-            long uncompressedSize,
-            long localFileHeaderOffset,
-            String name,
-            int nameSizeBytes) {
-        mData = data;
-        mLastModificationDate = lastModificationDate;
-        mLastModificationTime = lastModificationTime;
-        mCrc32 = crc32;
-        mCompressedSize = compressedSize;
-        mUncompressedSize = uncompressedSize;
-        mLocalFileHeaderOffset = localFileHeaderOffset;
-        mName = name;
-        mNameSizeBytes = nameSizeBytes;
-    }
-
-    public int getSize() {
-        return mData.remaining();
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public int getNameSizeBytes() {
-        return mNameSizeBytes;
-    }
-
-    public int getLastModificationTime() {
-        return mLastModificationTime;
-    }
-
-    public int getLastModificationDate() {
-        return mLastModificationDate;
-    }
-
-    public long getCrc32() {
-        return mCrc32;
-    }
-
-    public long getCompressedSize() {
-        return mCompressedSize;
-    }
-
-    public long getUncompressedSize() {
-        return mUncompressedSize;
-    }
-
-    public long getLocalFileHeaderOffset() {
-        return mLocalFileHeaderOffset;
-    }
-
-    /**
-     * Returns the Central Directory Record starting at the current position of the provided buffer
-     * and advances the buffer's position immediately past the end of the record.
-     */
-    public static CentralDirectoryRecord getRecord(ByteBuffer buf) throws ZipFormatException {
-        ZipUtils.assertByteOrderLittleEndian(buf);
-        if (buf.remaining() < HEADER_SIZE_BYTES) {
-            throw new ZipFormatException(
-                    "Input too short. Need at least: " + HEADER_SIZE_BYTES
-                            + " bytes, available: " + buf.remaining() + " bytes",
-                    new BufferUnderflowException());
-        }
-        int originalPosition = buf.position();
-        int recordSignature = buf.getInt();
-        if (recordSignature != RECORD_SIGNATURE) {
-            throw new ZipFormatException(
-                    "Not a Central Directory record. Signature: 0x"
-                            + Long.toHexString(recordSignature & 0xffffffffL));
-        }
-        buf.position(originalPosition + LAST_MODIFICATION_TIME_OFFSET);
-        int lastModificationTime = ZipUtils.getUnsignedInt16(buf);
-        int lastModificationDate = ZipUtils.getUnsignedInt16(buf);
-        long crc32 = ZipUtils.getUnsignedInt32(buf);
-        long compressedSize = ZipUtils.getUnsignedInt32(buf);
-        long uncompressedSize = ZipUtils.getUnsignedInt32(buf);
-        int nameSize = ZipUtils.getUnsignedInt16(buf);
-        int extraSize = ZipUtils.getUnsignedInt16(buf);
-        int commentSize = ZipUtils.getUnsignedInt16(buf);
-        buf.position(originalPosition + LOCAL_FILE_HEADER_OFFSET_OFFSET);
-        long localFileHeaderOffset = ZipUtils.getUnsignedInt32(buf);
-        buf.position(originalPosition);
-        int recordSize = HEADER_SIZE_BYTES + nameSize + extraSize + commentSize;
-        if (recordSize > buf.remaining()) {
-            throw new ZipFormatException(
-                    "Input too short. Need: " + recordSize + " bytes, available: "
-                            + buf.remaining() + " bytes",
-                    new BufferUnderflowException());
-        }
-        String name = getName(buf, originalPosition + NAME_OFFSET, nameSize);
-        buf.position(originalPosition);
-        int originalLimit = buf.limit();
-        int recordEndInBuf = originalPosition + recordSize;
-        ByteBuffer recordBuf;
-        try {
-            buf.limit(recordEndInBuf);
-            recordBuf = buf.slice();
-        } finally {
-            buf.limit(originalLimit);
-        }
-        // Consume this record
-        buf.position(recordEndInBuf);
-        return new CentralDirectoryRecord(
-                recordBuf,
-                lastModificationTime,
-                lastModificationDate,
-                crc32,
-                compressedSize,
-                uncompressedSize,
-                localFileHeaderOffset,
-                name,
-                nameSize);
-    }
-
-    public void copyTo(ByteBuffer output) {
-        output.put(mData.slice());
-    }
-
-    public CentralDirectoryRecord createWithModifiedLocalFileHeaderOffset(
-            long localFileHeaderOffset) {
-        ByteBuffer result = ByteBuffer.allocate(mData.remaining());
-        result.put(mData.slice());
-        result.flip();
-        result.order(ByteOrder.LITTLE_ENDIAN);
-        ZipUtils.setUnsignedInt32(result, LOCAL_FILE_HEADER_OFFSET_OFFSET, localFileHeaderOffset);
-        return new CentralDirectoryRecord(
-                result,
-                mLastModificationTime,
-                mLastModificationDate,
-                mCrc32,
-                mCompressedSize,
-                mUncompressedSize,
-                localFileHeaderOffset,
-                mName,
-                mNameSizeBytes);
-    }
-
-    public static CentralDirectoryRecord createWithDeflateCompressedData(
-            String name,
-            int lastModifiedTime,
-            int lastModifiedDate,
-            long crc32,
-            long compressedSize,
-            long uncompressedSize,
-            long localFileHeaderOffset) {
-        byte[] nameBytes = name.getBytes(StandardCharsets.UTF_8);
-        int recordSize = HEADER_SIZE_BYTES + nameBytes.length;
-        ByteBuffer result = ByteBuffer.allocate(recordSize);
-        result.order(ByteOrder.LITTLE_ENDIAN);
-        result.putInt(RECORD_SIGNATURE);
-        ZipUtils.putUnsignedInt16(result, 0x14); // Version made by
-        ZipUtils.putUnsignedInt16(result, 0x14); // Minimum version needed to extract
-        result.putShort(ZipUtils.GP_FLAG_EFS); // UTF-8 character encoding used for entry name
-        result.putShort(ZipUtils.COMPRESSION_METHOD_DEFLATED);
-        ZipUtils.putUnsignedInt16(result, lastModifiedTime);
-        ZipUtils.putUnsignedInt16(result, lastModifiedDate);
-        ZipUtils.putUnsignedInt32(result, crc32);
-        ZipUtils.putUnsignedInt32(result, compressedSize);
-        ZipUtils.putUnsignedInt32(result, uncompressedSize);
-        ZipUtils.putUnsignedInt16(result, nameBytes.length);
-        ZipUtils.putUnsignedInt16(result, 0); // Extra field length
-        ZipUtils.putUnsignedInt16(result, 0); // File comment length
-        ZipUtils.putUnsignedInt16(result, 0); // Disk number
-        ZipUtils.putUnsignedInt16(result, 0); // Internal file attributes
-        ZipUtils.putUnsignedInt32(result, 0); // External file attributes
-        ZipUtils.putUnsignedInt32(result, localFileHeaderOffset);
-        result.put(nameBytes);
-
-        if (result.hasRemaining()) {
-            throw new RuntimeException("pos: " + result.position() + ", limit: " + result.limit());
-        }
-        result.flip();
-        return new CentralDirectoryRecord(
-                result,
-                lastModifiedTime,
-                lastModifiedDate,
-                crc32,
-                compressedSize,
-                uncompressedSize,
-                localFileHeaderOffset,
-                name,
-                nameBytes.length);
-    }
-
-    static String getName(ByteBuffer record, int position, int nameLengthBytes) {
-        byte[] nameBytes;
-        int nameBytesOffset;
-        if (record.hasArray()) {
-            nameBytes = record.array();
-            nameBytesOffset = record.arrayOffset() + position;
-        } else {
-            nameBytes = new byte[nameLengthBytes];
-            nameBytesOffset = 0;
-            int originalPosition = record.position();
-            try {
-                record.position(position);
-                record.get(nameBytes);
-            } finally {
-                record.position(originalPosition);
-            }
-        }
-        return new String(nameBytes, nameBytesOffset, nameLengthBytes, StandardCharsets.UTF_8);
-    }
-
-    private static class ByLocalFileHeaderOffsetComparator
-            implements Comparator<CentralDirectoryRecord> {
-        @Override
-        public int compare(CentralDirectoryRecord r1, CentralDirectoryRecord r2) {
-            long offset1 = r1.getLocalFileHeaderOffset();
-            long offset2 = r2.getLocalFileHeaderOffset();
-            if (offset1 > offset2) {
-                return 1;
-            } else if (offset1 < offset2) {
-                return -1;
-            } else {
-                return 0;
-            }
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/EocdRecord.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/EocdRecord.java
deleted file mode 100644
index 8777591..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/EocdRecord.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.zip;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * ZIP End of Central Directory record.
- */
-public class EocdRecord {
-    private static final int CD_RECORD_COUNT_ON_DISK_OFFSET = 8;
-    private static final int CD_RECORD_COUNT_TOTAL_OFFSET = 10;
-    private static final int CD_SIZE_OFFSET = 12;
-    private static final int CD_OFFSET_OFFSET = 16;
-
-    public static ByteBuffer createWithModifiedCentralDirectoryInfo(
-            ByteBuffer original,
-            int centralDirectoryRecordCount,
-            long centralDirectorySizeBytes,
-            long centralDirectoryOffset) {
-        ByteBuffer result = ByteBuffer.allocate(original.remaining());
-        result.order(ByteOrder.LITTLE_ENDIAN);
-        result.put(original.slice());
-        result.flip();
-        ZipUtils.setUnsignedInt16(
-                result, CD_RECORD_COUNT_ON_DISK_OFFSET, centralDirectoryRecordCount);
-        ZipUtils.setUnsignedInt16(
-                result, CD_RECORD_COUNT_TOTAL_OFFSET, centralDirectoryRecordCount);
-        ZipUtils.setUnsignedInt32(result, CD_SIZE_OFFSET, centralDirectorySizeBytes);
-        ZipUtils.setUnsignedInt32(result, CD_OFFSET_OFFSET, centralDirectoryOffset);
-        return result;
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/LocalFileRecord.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/LocalFileRecord.java
deleted file mode 100644
index 397a450..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/LocalFileRecord.java
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.zip;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.charset.StandardCharsets;
-import java.util.zip.DataFormatException;
-import java.util.zip.Inflater;
-
-import com.android.apksigner.core.internal.util.ByteBufferSink;
-import com.android.apksigner.core.util.DataSink;
-import com.android.apksigner.core.util.DataSource;
-import com.android.apksigner.core.zip.ZipFormatException;
-
-/**
- * ZIP Local File record.
- *
- * <p>The record consists of the Local File Header, file data, and (if present) Data Descriptor.
- */
-public class LocalFileRecord {
-    private static final int RECORD_SIGNATURE = 0x04034b50;
-    private static final int HEADER_SIZE_BYTES = 30;
-
-    private static final int GP_FLAGS_OFFSET = 6;
-    private static final int COMPRESSION_METHOD_OFFSET = 8;
-    private static final int CRC32_OFFSET = 14;
-    private static final int COMPRESSED_SIZE_OFFSET = 18;
-    private static final int UNCOMPRESSED_SIZE_OFFSET = 22;
-    private static final int NAME_LENGTH_OFFSET = 26;
-    private static final int EXTRA_LENGTH_OFFSET = 28;
-    private static final int NAME_OFFSET = HEADER_SIZE_BYTES;
-
-    private static final int DATA_DESCRIPTOR_SIZE_BYTES_WITHOUT_SIGNATURE = 12;
-    private static final int DATA_DESCRIPTOR_SIGNATURE = 0x08074b50;
-
-    private final String mName;
-    private final int mNameSizeBytes;
-    private final ByteBuffer mExtra;
-
-    private final long mStartOffsetInArchive;
-    private final long mSize;
-
-    private final int mDataStartOffset;
-    private final long mDataSize;
-    private final boolean mDataCompressed;
-    private final long mUncompressedDataSize;
-
-    private LocalFileRecord(
-            String name,
-            int nameSizeBytes,
-            ByteBuffer extra,
-            long startOffsetInArchive,
-            long size,
-            int dataStartOffset,
-            long dataSize,
-            boolean dataCompressed,
-            long uncompressedDataSize) {
-        mName = name;
-        mNameSizeBytes = nameSizeBytes;
-        mExtra = extra;
-        mStartOffsetInArchive = startOffsetInArchive;
-        mSize = size;
-        mDataStartOffset = dataStartOffset;
-        mDataSize = dataSize;
-        mDataCompressed = dataCompressed;
-        mUncompressedDataSize = uncompressedDataSize;
-    }
-
-    public String getName() {
-        return mName;
-    }
-
-    public ByteBuffer getExtra() {
-        return (mExtra.capacity() > 0) ? mExtra.slice() : mExtra;
-    }
-
-    public int getExtraFieldStartOffsetInsideRecord() {
-        return HEADER_SIZE_BYTES + mNameSizeBytes;
-    }
-
-    public long getStartOffsetInArchive() {
-        return mStartOffsetInArchive;
-    }
-
-    public int getDataStartOffsetInRecord() {
-        return mDataStartOffset;
-    }
-
-    /**
-     * Returns the size (in bytes) of this record.
-     */
-    public long getSize() {
-        return mSize;
-    }
-
-    /**
-     * Returns {@code true} if this record's file data is stored in compressed form.
-     */
-    public boolean isDataCompressed() {
-        return mDataCompressed;
-    }
-
-    /**
-     * Returns the Local File record starting at the current position of the provided buffer
-     * and advances the buffer's position immediately past the end of the record. The record
-     * consists of the Local File Header, data, and (if present) Data Descriptor.
-     */
-    public static LocalFileRecord getRecord(
-            DataSource apk,
-            CentralDirectoryRecord cdRecord,
-            long cdStartOffset) throws ZipFormatException, IOException {
-        return getRecord(
-                apk,
-                cdRecord,
-                cdStartOffset,
-                true, // obtain extra field contents
-                true // include Data Descriptor (if present)
-                );
-    }
-
-    /**
-     * Returns the Local File record starting at the current position of the provided buffer
-     * and advances the buffer's position immediately past the end of the record. The record
-     * consists of the Local File Header, data, and (if present) Data Descriptor.
-     */
-    private static LocalFileRecord getRecord(
-            DataSource apk,
-            CentralDirectoryRecord cdRecord,
-            long cdStartOffset,
-            boolean extraFieldContentsNeeded,
-            boolean dataDescriptorIncluded) throws ZipFormatException, IOException {
-        // IMPLEMENTATION NOTE: This method attempts to mimic the behavior of Android platform
-        // exhibited when reading an APK for the purposes of verifying its signatures.
-
-        String entryName = cdRecord.getName();
-        int cdRecordEntryNameSizeBytes = cdRecord.getNameSizeBytes();
-        int headerSizeWithName = HEADER_SIZE_BYTES + cdRecordEntryNameSizeBytes;
-        long headerStartOffset = cdRecord.getLocalFileHeaderOffset();
-        long headerEndOffset = headerStartOffset + headerSizeWithName;
-        if (headerEndOffset >= cdStartOffset) {
-            throw new ZipFormatException(
-                    "Local File Header of " + entryName + " extends beyond start of Central"
-                            + " Directory. LFH end: " + headerEndOffset
-                            + ", CD start: " + cdStartOffset);
-        }
-        ByteBuffer header;
-        try {
-            header = apk.getByteBuffer(headerStartOffset, headerSizeWithName);
-        } catch (IOException e) {
-            throw new IOException("Failed to read Local File Header of " + entryName, e);
-        }
-        header.order(ByteOrder.LITTLE_ENDIAN);
-
-        int recordSignature = header.getInt();
-        if (recordSignature != RECORD_SIGNATURE) {
-            throw new ZipFormatException(
-                    "Not a Local File Header record for entry " + entryName + ". Signature: 0x"
-                            + Long.toHexString(recordSignature & 0xffffffffL));
-        }
-        short gpFlags = header.getShort(GP_FLAGS_OFFSET);
-        boolean dataDescriptorUsed = (gpFlags & ZipUtils.GP_FLAG_DATA_DESCRIPTOR_USED) != 0;
-        long uncompressedDataCrc32FromCdRecord = cdRecord.getCrc32();
-        long compressedDataSizeFromCdRecord = cdRecord.getCompressedSize();
-        long uncompressedDataSizeFromCdRecord = cdRecord.getUncompressedSize();
-        if (!dataDescriptorUsed) {
-            long crc32 = ZipUtils.getUnsignedInt32(header, CRC32_OFFSET);
-            if (crc32 != uncompressedDataCrc32FromCdRecord) {
-                throw new ZipFormatException(
-                        "CRC-32 mismatch between Local File Header and Central Directory for entry "
-                                + entryName + ". LFH: " + crc32
-                                + ", CD: " + uncompressedDataCrc32FromCdRecord);
-            }
-            long compressedSize = ZipUtils.getUnsignedInt32(header, COMPRESSED_SIZE_OFFSET);
-            if (compressedSize != compressedDataSizeFromCdRecord) {
-                throw new ZipFormatException(
-                        "Compressed size mismatch between Local File Header and Central Directory"
-                                + " for entry " + entryName + ". LFH: " + compressedSize
-                                + ", CD: " + compressedDataSizeFromCdRecord);
-            }
-            long uncompressedSize = ZipUtils.getUnsignedInt32(header, UNCOMPRESSED_SIZE_OFFSET);
-            if (uncompressedSize != uncompressedDataSizeFromCdRecord) {
-                throw new ZipFormatException(
-                        "Uncompressed size mismatch between Local File Header and Central Directory"
-                                + " for entry " + entryName + ". LFH: " + uncompressedSize
-                                + ", CD: " + uncompressedDataSizeFromCdRecord);
-            }
-        }
-        int nameLength = ZipUtils.getUnsignedInt16(header, NAME_LENGTH_OFFSET);
-        if (nameLength > cdRecordEntryNameSizeBytes) {
-            throw new ZipFormatException(
-                    "Name mismatch between Local File Header and Central Directory for entry"
-                            + entryName + ". LFH: " + nameLength
-                            + " bytes, CD: " + cdRecordEntryNameSizeBytes + " bytes");
-        }
-        String name = CentralDirectoryRecord.getName(header, NAME_OFFSET, nameLength);
-        if (!entryName.equals(name)) {
-            throw new ZipFormatException(
-                    "Name mismatch between Local File Header and Central Directory. LFH: \""
-                            + name + "\", CD: \"" + entryName + "\"");
-        }
-        int extraLength = ZipUtils.getUnsignedInt16(header, EXTRA_LENGTH_OFFSET);
-
-        short compressionMethod = header.getShort(COMPRESSION_METHOD_OFFSET);
-        boolean compressed;
-        switch (compressionMethod) {
-            case ZipUtils.COMPRESSION_METHOD_STORED:
-                compressed = false;
-                break;
-            case ZipUtils.COMPRESSION_METHOD_DEFLATED:
-                compressed = true;
-                break;
-            default:
-                throw new ZipFormatException(
-                        "Unsupported compression method of entry " + entryName
-                                + ": " + (compressionMethod & 0xffff));
-        }
-
-        long dataStartOffset = headerStartOffset + HEADER_SIZE_BYTES + nameLength + extraLength;
-        long dataSize;
-        if (compressed) {
-            dataSize = compressedDataSizeFromCdRecord;
-        } else {
-            dataSize = uncompressedDataSizeFromCdRecord;
-        }
-        long dataEndOffset = dataStartOffset + dataSize;
-        if (dataEndOffset > cdStartOffset) {
-            throw new ZipFormatException(
-                    "Local File Header data of " + entryName + " overlaps with Central Directory"
-                            + ". LFH data start: " + dataStartOffset
-                            + ", LFH data end: " + dataEndOffset + ", CD start: " + cdStartOffset);
-        }
-
-        ByteBuffer extra = EMPTY_BYTE_BUFFER;
-        if ((extraFieldContentsNeeded) && (extraLength > 0)) {
-            extra = apk.getByteBuffer(
-                    headerStartOffset + HEADER_SIZE_BYTES + nameLength, extraLength);
-        }
-
-        long recordEndOffset = dataEndOffset;
-        // Include the Data Descriptor (if requested and present) into the record.
-        if ((dataDescriptorIncluded) && ((gpFlags & ZipUtils.GP_FLAG_DATA_DESCRIPTOR_USED) != 0)) {
-            // The record's data is supposed to be followed by the Data Descriptor. Unfortunately,
-            // the descriptor's size is not known in advance because the spec lets the signature
-            // field (the first four bytes) be omitted. Thus, there's no 100% reliable way to tell
-            // how long the Data Descriptor record is. Most parsers (including Android) check
-            // whether the first four bytes look like Data Descriptor record signature and, if so,
-            // assume that it is indeed the record's signature. However, this is the wrong
-            // conclusion if the record's CRC-32 (next field after the signature) has the same value
-            // as the signature. In any case, we're doing what Android is doing.
-            long dataDescriptorEndOffset =
-                    dataEndOffset + DATA_DESCRIPTOR_SIZE_BYTES_WITHOUT_SIGNATURE;
-            if (dataDescriptorEndOffset > cdStartOffset) {
-                throw new ZipFormatException(
-                        "Data Descriptor of " + entryName + " overlaps with Central Directory"
-                                + ". Data Descriptor end: " + dataEndOffset
-                                + ", CD start: " + cdStartOffset);
-            }
-            ByteBuffer dataDescriptorPotentialSig = apk.getByteBuffer(dataEndOffset, 4);
-            dataDescriptorPotentialSig.order(ByteOrder.LITTLE_ENDIAN);
-            if (dataDescriptorPotentialSig.getInt() == DATA_DESCRIPTOR_SIGNATURE) {
-                dataDescriptorEndOffset += 4;
-                if (dataDescriptorEndOffset > cdStartOffset) {
-                    throw new ZipFormatException(
-                            "Data Descriptor of " + entryName + " overlaps with Central Directory"
-                                    + ". Data Descriptor end: " + dataEndOffset
-                                    + ", CD start: " + cdStartOffset);
-                }
-            }
-            recordEndOffset = dataDescriptorEndOffset;
-        }
-
-        long recordSize = recordEndOffset - headerStartOffset;
-        int dataStartOffsetInRecord = HEADER_SIZE_BYTES + nameLength + extraLength;
-
-        return new LocalFileRecord(
-                entryName,
-                cdRecordEntryNameSizeBytes,
-                extra,
-                headerStartOffset,
-                recordSize,
-                dataStartOffsetInRecord,
-                dataSize,
-                compressed,
-                uncompressedDataSizeFromCdRecord);
-    }
-
-    /**
-     * Outputs this record and returns returns the number of bytes output.
-     */
-    public long outputRecord(DataSource sourceApk, DataSink output) throws IOException {
-        long size = getSize();
-        sourceApk.feed(getStartOffsetInArchive(), size, output);
-        return size;
-    }
-
-    /**
-     * Outputs this record, replacing its extra field with the provided one, and returns returns the
-     * number of bytes output.
-     */
-    public long outputRecordWithModifiedExtra(
-            DataSource sourceApk,
-            ByteBuffer extra,
-            DataSink output) throws IOException {
-        long recordStartOffsetInSource = getStartOffsetInArchive();
-        int extraStartOffsetInRecord = getExtraFieldStartOffsetInsideRecord();
-        int extraSizeBytes = extra.remaining();
-        int headerSize = extraStartOffsetInRecord + extraSizeBytes;
-        ByteBuffer header = ByteBuffer.allocate(headerSize);
-        header.order(ByteOrder.LITTLE_ENDIAN);
-        sourceApk.copyTo(recordStartOffsetInSource, extraStartOffsetInRecord, header);
-        header.put(extra.slice());
-        header.flip();
-        ZipUtils.setUnsignedInt16(header, EXTRA_LENGTH_OFFSET, extraSizeBytes);
-
-        long outputByteCount = header.remaining();
-        output.consume(header);
-        long remainingRecordSize = getSize() - mDataStartOffset;
-        sourceApk.feed(recordStartOffsetInSource + mDataStartOffset, remainingRecordSize, output);
-        outputByteCount += remainingRecordSize;
-        return outputByteCount;
-    }
-
-    /**
-     * Outputs the specified Local File Header record with its data and returns the number of bytes
-     * output.
-     */
-    public static long outputRecordWithDeflateCompressedData(
-            String name,
-            int lastModifiedTime,
-            int lastModifiedDate,
-            byte[] compressedData,
-            long crc32,
-            long uncompressedSize,
-            DataSink output) throws IOException {
-        byte[] nameBytes = name.getBytes(StandardCharsets.UTF_8);
-        int recordSize = HEADER_SIZE_BYTES + nameBytes.length;
-        ByteBuffer result = ByteBuffer.allocate(recordSize);
-        result.order(ByteOrder.LITTLE_ENDIAN);
-        result.putInt(RECORD_SIGNATURE);
-        ZipUtils.putUnsignedInt16(result,  0x14); // Minimum version needed to extract
-        result.putShort(ZipUtils.GP_FLAG_EFS); // General purpose flag: UTF-8 encoded name
-        result.putShort(ZipUtils.COMPRESSION_METHOD_DEFLATED);
-        ZipUtils.putUnsignedInt16(result, lastModifiedTime);
-        ZipUtils.putUnsignedInt16(result, lastModifiedDate);
-        ZipUtils.putUnsignedInt32(result, crc32);
-        ZipUtils.putUnsignedInt32(result, compressedData.length);
-        ZipUtils.putUnsignedInt32(result, uncompressedSize);
-        ZipUtils.putUnsignedInt16(result, nameBytes.length);
-        ZipUtils.putUnsignedInt16(result, 0); // Extra field length
-        result.put(nameBytes);
-        if (result.hasRemaining()) {
-            throw new RuntimeException("pos: " + result.position() + ", limit: " + result.limit());
-        }
-        result.flip();
-
-        long outputByteCount = result.remaining();
-        output.consume(result);
-        outputByteCount += compressedData.length;
-        output.consume(compressedData, 0, compressedData.length);
-        return outputByteCount;
-    }
-
-    private static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.allocate(0);
-
-    /**
-     * Sends uncompressed data of this record into the the provided data sink.
-     */
-    public void outputUncompressedData(
-            DataSource lfhSection,
-            DataSink sink) throws IOException, ZipFormatException {
-        long dataStartOffsetInArchive = mStartOffsetInArchive + mDataStartOffset;
-        try {
-            if (mDataCompressed) {
-                try (InflateSinkAdapter inflateAdapter = new InflateSinkAdapter(sink)) {
-                    lfhSection.feed(dataStartOffsetInArchive, mDataSize, inflateAdapter);
-                    long actualUncompressedSize = inflateAdapter.getOutputByteCount();
-                    if (actualUncompressedSize != mUncompressedDataSize) {
-                        throw new ZipFormatException(
-                                "Unexpected size of uncompressed data of " + mName
-                                        + ". Expected: " + mUncompressedDataSize + " bytes"
-                                        + ", actual: " + actualUncompressedSize + " bytes");
-                    }
-                }
-            } else {
-                lfhSection.feed(dataStartOffsetInArchive, mDataSize, sink);
-                // No need to check whether output size is as expected because DataSource.feed is
-                // guaranteed to output exactly the number of bytes requested.
-            }
-        } catch (IOException e) {
-            throw new IOException(
-                    "Failed to read data of " + ((mDataCompressed) ? "compressed" : "uncompressed")
-                        + " entry " + mName,
-                    e);
-        }
-        // Interestingly, Android doesn't check that uncompressed data's CRC-32 is as expected. We
-        // thus don't check either.
-    }
-
-    /**
-     * Sends uncompressed data pointed to by the provided ZIP Central Directory (CD) record into the
-     * provided data sink.
-     */
-    public static void outputUncompressedData(
-            DataSource source,
-            CentralDirectoryRecord cdRecord,
-            long cdStartOffsetInArchive,
-            DataSink sink) throws ZipFormatException, IOException {
-        // IMPLEMENTATION NOTE: This method attempts to mimic the behavior of Android platform
-        // exhibited when reading an APK for the purposes of verifying its signatures.
-        // When verifying an APK, Android doesn't care reading the extra field or the Data
-        // Descriptor.
-        LocalFileRecord lfhRecord =
-                getRecord(
-                        source,
-                        cdRecord,
-                        cdStartOffsetInArchive,
-                        false, // don't care about the extra field
-                        false // don't read the Data Descriptor
-                        );
-        lfhRecord.outputUncompressedData(source, sink);
-    }
-
-    /**
-     * Returns the uncompressed data pointed to by the provided ZIP Central Directory (CD) record.
-     */
-    public static byte[] getUncompressedData(
-            DataSource source,
-            CentralDirectoryRecord cdRecord,
-            long cdStartOffsetInArchive) throws ZipFormatException, IOException {
-        if (cdRecord.getUncompressedSize() > Integer.MAX_VALUE) {
-            throw new IOException(
-                    cdRecord.getName() + " too large: " + cdRecord.getUncompressedSize());
-        }
-        byte[] result = new byte[(int) cdRecord.getUncompressedSize()];
-        ByteBuffer resultBuf = ByteBuffer.wrap(result);
-        ByteBufferSink resultSink = new ByteBufferSink(resultBuf);
-        outputUncompressedData(
-                source,
-                cdRecord,
-                cdStartOffsetInArchive,
-                resultSink);
-        return result;
-    }
-
-    /**
-     * {@link DataSink} which inflates received data and outputs the deflated data into the provided
-     * delegate sink.
-     */
-    private static class InflateSinkAdapter implements DataSink, Closeable {
-        private final DataSink mDelegate;
-
-        private Inflater mInflater = new Inflater(true);
-        private byte[] mOutputBuffer;
-        private byte[] mInputBuffer;
-        private long mOutputByteCount;
-        private boolean mClosed;
-
-        private InflateSinkAdapter(DataSink delegate) {
-            mDelegate = delegate;
-        }
-
-        @Override
-        public void consume(byte[] buf, int offset, int length) throws IOException {
-            checkNotClosed();
-            mInflater.setInput(buf, offset, length);
-            if (mOutputBuffer == null) {
-                mOutputBuffer = new byte[65536];
-            }
-            while (!mInflater.finished()) {
-                int outputChunkSize;
-                try {
-                    outputChunkSize = mInflater.inflate(mOutputBuffer);
-                } catch (DataFormatException e) {
-                    throw new IOException("Failed to inflate data", e);
-                }
-                if (outputChunkSize == 0) {
-                    return;
-                }
-                mDelegate.consume(mOutputBuffer, 0, outputChunkSize);
-                mOutputByteCount += outputChunkSize;
-            }
-        }
-
-        @Override
-        public void consume(ByteBuffer buf) throws IOException {
-            checkNotClosed();
-            if (buf.hasArray()) {
-                consume(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining());
-                buf.position(buf.limit());
-            } else {
-                if (mInputBuffer == null) {
-                    mInputBuffer = new byte[65536];
-                }
-                while (buf.hasRemaining()) {
-                    int chunkSize = Math.min(buf.remaining(), mInputBuffer.length);
-                    buf.get(mInputBuffer, 0, chunkSize);
-                    consume(mInputBuffer, 0, chunkSize);
-                }
-            }
-        }
-
-        public long getOutputByteCount() {
-            return mOutputByteCount;
-        }
-
-        @Override
-        public void close() throws IOException {
-            mClosed = true;
-            mInputBuffer = null;
-            mOutputBuffer = null;
-            if (mInflater != null) {
-                mInflater.end();
-                mInflater = null;
-            }
-        }
-
-        private void checkNotClosed() {
-            if (mClosed) {
-                throw new IllegalStateException("Closed");
-            }
-        }
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/ZipUtils.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/ZipUtils.java
deleted file mode 100644
index 6a0c501..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/ZipUtils.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.internal.zip;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.zip.CRC32;
-import java.util.zip.Deflater;
-
-import com.android.apksigner.core.internal.util.Pair;
-import com.android.apksigner.core.util.DataSource;
-
-/**
- * Assorted ZIP format helpers.
- *
- * <p>NOTE: Most helper methods operating on {@code ByteBuffer} instances expect that the byte
- * order of these buffers is little-endian.
- */
-public abstract class ZipUtils {
-    private ZipUtils() {}
-
-    public static final short COMPRESSION_METHOD_STORED = 0;
-    public static final short COMPRESSION_METHOD_DEFLATED = 8;
-
-    public static final short GP_FLAG_DATA_DESCRIPTOR_USED = 0x08;
-    public static final short GP_FLAG_EFS = 0x0800;
-
-    private static final int ZIP_EOCD_REC_MIN_SIZE = 22;
-    private static final int ZIP_EOCD_REC_SIG = 0x06054b50;
-    private static final int ZIP_EOCD_CENTRAL_DIR_TOTAL_RECORD_COUNT_OFFSET = 10;
-    private static final int ZIP_EOCD_CENTRAL_DIR_SIZE_FIELD_OFFSET = 12;
-    private static final int ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET = 16;
-    private static final int ZIP_EOCD_COMMENT_LENGTH_FIELD_OFFSET = 20;
-
-    private static final int ZIP64_EOCD_LOCATOR_SIZE = 20;
-    private static final int ZIP64_EOCD_LOCATOR_SIG = 0x07064b50;
-
-    private static final int UINT16_MAX_VALUE = 0xffff;
-
-    /**
-     * Sets the offset of the start of the ZIP Central Directory in the archive.
-     *
-     * <p>NOTE: Byte order of {@code zipEndOfCentralDirectory} must be little-endian.
-     */
-    public static void setZipEocdCentralDirectoryOffset(
-            ByteBuffer zipEndOfCentralDirectory, long offset) {
-        assertByteOrderLittleEndian(zipEndOfCentralDirectory);
-        setUnsignedInt32(
-                zipEndOfCentralDirectory,
-                zipEndOfCentralDirectory.position() + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET,
-                offset);
-    }
-
-    /**
-     * Returns the offset of the start of the ZIP Central Directory in the archive.
-     *
-     * <p>NOTE: Byte order of {@code zipEndOfCentralDirectory} must be little-endian.
-     */
-    public static long getZipEocdCentralDirectoryOffset(ByteBuffer zipEndOfCentralDirectory) {
-        assertByteOrderLittleEndian(zipEndOfCentralDirectory);
-        return getUnsignedInt32(
-                zipEndOfCentralDirectory,
-                zipEndOfCentralDirectory.position() + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET);
-    }
-
-    /**
-     * Returns the size (in bytes) of the ZIP Central Directory.
-     *
-     * <p>NOTE: Byte order of {@code zipEndOfCentralDirectory} must be little-endian.
-     */
-    public static long getZipEocdCentralDirectorySizeBytes(ByteBuffer zipEndOfCentralDirectory) {
-        assertByteOrderLittleEndian(zipEndOfCentralDirectory);
-        return getUnsignedInt32(
-                zipEndOfCentralDirectory,
-                zipEndOfCentralDirectory.position() + ZIP_EOCD_CENTRAL_DIR_SIZE_FIELD_OFFSET);
-    }
-
-    /**
-     * Returns the total number of records in ZIP Central Directory.
-     *
-     * <p>NOTE: Byte order of {@code zipEndOfCentralDirectory} must be little-endian.
-     */
-    public static int getZipEocdCentralDirectoryTotalRecordCount(
-            ByteBuffer zipEndOfCentralDirectory) {
-        assertByteOrderLittleEndian(zipEndOfCentralDirectory);
-        return getUnsignedInt16(
-                zipEndOfCentralDirectory,
-                zipEndOfCentralDirectory.position()
-                        + ZIP_EOCD_CENTRAL_DIR_TOTAL_RECORD_COUNT_OFFSET);
-    }
-
-    /**
-     * Returns the ZIP End of Central Directory record of the provided ZIP file.
-     *
-     * @return contents of the ZIP End of Central Directory record and the record's offset in the
-     *         file or {@code null} if the file does not contain the record.
-     *
-     * @throws IOException if an I/O error occurs while reading the file.
-     */
-    public static Pair<ByteBuffer, Long> findZipEndOfCentralDirectoryRecord(DataSource zip)
-            throws IOException {
-        // ZIP End of Central Directory (EOCD) record is located at the very end of the ZIP archive.
-        // The record can be identified by its 4-byte signature/magic which is located at the very
-        // beginning of the record. A complication is that the record is variable-length because of
-        // the comment field.
-        // The algorithm for locating the ZIP EOCD record is as follows. We search backwards from
-        // end of the buffer for the EOCD record signature. Whenever we find a signature, we check
-        // the candidate record's comment length is such that the remainder of the record takes up
-        // exactly the remaining bytes in the buffer. The search is bounded because the maximum
-        // size of the comment field is 65535 bytes because the field is an unsigned 16-bit number.
-
-        long fileSize = zip.size();
-        if (fileSize < ZIP_EOCD_REC_MIN_SIZE) {
-            return null;
-        }
-
-        // Optimization: 99.99% of APKs have a zero-length comment field in the EoCD record and thus
-        // the EoCD record offset is known in advance. Try that offset first to avoid unnecessarily
-        // reading more data.
-        Pair<ByteBuffer, Long> result = findZipEndOfCentralDirectoryRecord(zip, 0);
-        if (result != null) {
-            return result;
-        }
-
-        // EoCD does not start where we expected it to. Perhaps it contains a non-empty comment
-        // field. Expand the search. The maximum size of the comment field in EoCD is 65535 because
-        // the comment length field is an unsigned 16-bit number.
-        return findZipEndOfCentralDirectoryRecord(zip, UINT16_MAX_VALUE);
-    }
-
-    /**
-     * Returns the ZIP End of Central Directory record of the provided ZIP file.
-     *
-     * @param maxCommentSize maximum accepted size (in bytes) of EoCD comment field. The permitted
-     *        value is from 0 to 65535 inclusive. The smaller the value, the faster this method
-     *        locates the record, provided its comment field is no longer than this value.
-     *
-     * @return contents of the ZIP End of Central Directory record and the record's offset in the
-     *         file or {@code null} if the file does not contain the record.
-     *
-     * @throws IOException if an I/O error occurs while reading the file.
-     */
-    private static Pair<ByteBuffer, Long> findZipEndOfCentralDirectoryRecord(
-            DataSource zip, int maxCommentSize) throws IOException {
-        // ZIP End of Central Directory (EOCD) record is located at the very end of the ZIP archive.
-        // The record can be identified by its 4-byte signature/magic which is located at the very
-        // beginning of the record. A complication is that the record is variable-length because of
-        // the comment field.
-        // The algorithm for locating the ZIP EOCD record is as follows. We search backwards from
-        // end of the buffer for the EOCD record signature. Whenever we find a signature, we check
-        // the candidate record's comment length is such that the remainder of the record takes up
-        // exactly the remaining bytes in the buffer. The search is bounded because the maximum
-        // size of the comment field is 65535 bytes because the field is an unsigned 16-bit number.
-
-        if ((maxCommentSize < 0) || (maxCommentSize > UINT16_MAX_VALUE)) {
-            throw new IllegalArgumentException("maxCommentSize: " + maxCommentSize);
-        }
-
-        long fileSize = zip.size();
-        if (fileSize < ZIP_EOCD_REC_MIN_SIZE) {
-            // No space for EoCD record in the file.
-            return null;
-        }
-        // Lower maxCommentSize if the file is too small.
-        maxCommentSize = (int) Math.min(maxCommentSize, fileSize - ZIP_EOCD_REC_MIN_SIZE);
-
-        int maxEocdSize = ZIP_EOCD_REC_MIN_SIZE + maxCommentSize;
-        long bufOffsetInFile = fileSize - maxEocdSize;
-        ByteBuffer buf = zip.getByteBuffer(bufOffsetInFile, maxEocdSize);
-        buf.order(ByteOrder.LITTLE_ENDIAN);
-        int eocdOffsetInBuf = findZipEndOfCentralDirectoryRecord(buf);
-        if (eocdOffsetInBuf == -1) {
-            // No EoCD record found in the buffer
-            return null;
-        }
-        // EoCD found
-        buf.position(eocdOffsetInBuf);
-        ByteBuffer eocd = buf.slice();
-        eocd.order(ByteOrder.LITTLE_ENDIAN);
-        return Pair.of(eocd, bufOffsetInFile + eocdOffsetInBuf);
-    }
-
-    /**
-     * Returns the position at which ZIP End of Central Directory record starts in the provided
-     * buffer or {@code -1} if the record is not present.
-     *
-     * <p>NOTE: Byte order of {@code zipContents} must be little-endian.
-     */
-    private static int findZipEndOfCentralDirectoryRecord(ByteBuffer zipContents) {
-        assertByteOrderLittleEndian(zipContents);
-
-        // ZIP End of Central Directory (EOCD) record is located at the very end of the ZIP archive.
-        // The record can be identified by its 4-byte signature/magic which is located at the very
-        // beginning of the record. A complication is that the record is variable-length because of
-        // the comment field.
-        // The algorithm for locating the ZIP EOCD record is as follows. We search backwards from
-        // end of the buffer for the EOCD record signature. Whenever we find a signature, we check
-        // the candidate record's comment length is such that the remainder of the record takes up
-        // exactly the remaining bytes in the buffer. The search is bounded because the maximum
-        // size of the comment field is 65535 bytes because the field is an unsigned 16-bit number.
-
-        int archiveSize = zipContents.capacity();
-        if (archiveSize < ZIP_EOCD_REC_MIN_SIZE) {
-            return -1;
-        }
-        int maxCommentLength = Math.min(archiveSize - ZIP_EOCD_REC_MIN_SIZE, UINT16_MAX_VALUE);
-        int eocdWithEmptyCommentStartPosition = archiveSize - ZIP_EOCD_REC_MIN_SIZE;
-        for (int expectedCommentLength = 0; expectedCommentLength < maxCommentLength;
-                expectedCommentLength++) {
-            int eocdStartPos = eocdWithEmptyCommentStartPosition - expectedCommentLength;
-            if (zipContents.getInt(eocdStartPos) == ZIP_EOCD_REC_SIG) {
-                int actualCommentLength =
-                        getUnsignedInt16(
-                                zipContents, eocdStartPos + ZIP_EOCD_COMMENT_LENGTH_FIELD_OFFSET);
-                if (actualCommentLength == expectedCommentLength) {
-                    return eocdStartPos;
-                }
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Returns {@code true} if the provided file contains a ZIP64 End of Central Directory
-     * Locator.
-     *
-     * @param zipEndOfCentralDirectoryPosition offset of the ZIP End of Central Directory record
-     *        in the file.
-     *
-     * @throws IOException if an I/O error occurs while reading the data source
-     */
-    public static final boolean isZip64EndOfCentralDirectoryLocatorPresent(
-            DataSource zip, long zipEndOfCentralDirectoryPosition) throws IOException {
-
-        // ZIP64 End of Central Directory Locator immediately precedes the ZIP End of Central
-        // Directory Record.
-        long locatorPosition = zipEndOfCentralDirectoryPosition - ZIP64_EOCD_LOCATOR_SIZE;
-        if (locatorPosition < 0) {
-            return false;
-        }
-
-        ByteBuffer sig = zip.getByteBuffer(locatorPosition, 4);
-        sig.order(ByteOrder.LITTLE_ENDIAN);
-        return sig.getInt(0) == ZIP64_EOCD_LOCATOR_SIG;
-    }
-
-    static void assertByteOrderLittleEndian(ByteBuffer buffer) {
-        if (buffer.order() != ByteOrder.LITTLE_ENDIAN) {
-            throw new IllegalArgumentException("ByteBuffer byte order must be little endian");
-        }
-    }
-
-    public static int getUnsignedInt16(ByteBuffer buffer, int offset) {
-        return buffer.getShort(offset) & 0xffff;
-    }
-
-    public static int getUnsignedInt16(ByteBuffer buffer) {
-        return buffer.getShort() & 0xffff;
-    }
-
-    static void setUnsignedInt16(ByteBuffer buffer, int offset, int value) {
-        if ((value < 0) || (value > 0xffff)) {
-            throw new IllegalArgumentException("uint16 value of out range: " + value);
-        }
-        buffer.putShort(offset, (short) value);
-    }
-
-    static void setUnsignedInt32(ByteBuffer buffer, int offset, long value) {
-        if ((value < 0) || (value > 0xffffffffL)) {
-            throw new IllegalArgumentException("uint32 value of out range: " + value);
-        }
-        buffer.putInt(offset, (int) value);
-    }
-
-    public static void putUnsignedInt16(ByteBuffer buffer, int value) {
-        if ((value < 0) || (value > 0xffff)) {
-            throw new IllegalArgumentException("uint16 value of out range: " + value);
-        }
-        buffer.putShort((short) value);
-    }
-
-    static long getUnsignedInt32(ByteBuffer buffer, int offset) {
-        return buffer.getInt(offset) & 0xffffffffL;
-    }
-
-    static long getUnsignedInt32(ByteBuffer buffer) {
-        return buffer.getInt() & 0xffffffffL;
-    }
-
-    static void putUnsignedInt32(ByteBuffer buffer, long value) {
-        if ((value < 0) || (value > 0xffffffffL)) {
-            throw new IllegalArgumentException("uint32 value of out range: " + value);
-        }
-        buffer.putInt((int) value);
-    }
-
-    public static DeflateResult deflate(ByteBuffer input) {
-        byte[] inputBuf;
-        int inputOffset;
-        int inputLength = input.remaining();
-        if (input.hasArray()) {
-            inputBuf = input.array();
-            inputOffset = input.arrayOffset() + input.position();
-            input.position(input.limit());
-        } else {
-            inputBuf = new byte[inputLength];
-            inputOffset = 0;
-            input.get(inputBuf);
-        }
-        CRC32 crc32 = new CRC32();
-        crc32.update(inputBuf, inputOffset, inputLength);
-        long crc32Value = crc32.getValue();
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        Deflater deflater = new Deflater(9, true);
-        deflater.setInput(inputBuf, inputOffset, inputLength);
-        deflater.finish();
-        byte[] buf = new byte[65536];
-        while (!deflater.finished()) {
-            int chunkSize = deflater.deflate(buf);
-            out.write(buf, 0, chunkSize);
-        }
-        return new DeflateResult(inputLength, crc32Value, out.toByteArray());
-    }
-
-    public static class DeflateResult {
-        public final int inputSizeBytes;
-        public final long inputCrc32;
-        public final byte[] output;
-
-        public DeflateResult(int inputSizeBytes, long inputCrc32, byte[] output) {
-            this.inputSizeBytes = inputSizeBytes;
-            this.inputCrc32 = inputCrc32;
-            this.output = output;
-        }
-    }
-}
\ No newline at end of file
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/util/DataSink.java b/tools/apksigner/core/src/com/android/apksigner/core/util/DataSink.java
deleted file mode 100644
index 35a61fc..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/util/DataSink.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.util;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * Consumer of input data which may be provided in one go or in chunks.
- */
-public interface DataSink {
-
-    /**
-     * Consumes the provided chunk of data.
-     *
-     * <p>This data sink guarantees to not hold references to the provided buffer after this method
-     * terminates.
-     */
-    void consume(byte[] buf, int offset, int length) throws IOException;
-
-    /**
-     * Consumes all remaining data in the provided buffer and advances the buffer's position
-     * to the buffer's limit.
-     *
-     * <p>This data sink guarantees to not hold references to the provided buffer after this method
-     * terminates.
-     */
-    void consume(ByteBuffer buf) throws IOException;
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/util/DataSinks.java b/tools/apksigner/core/src/com/android/apksigner/core/util/DataSinks.java
deleted file mode 100644
index 4aefedb..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/util/DataSinks.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.util;
-
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
-
-import com.android.apksigner.core.internal.util.OutputStreamDataSink;
-import com.android.apksigner.core.internal.util.RandomAccessFileDataSink;
-
-/**
- * Utility methods for working with {@link DataSink} abstraction.
- */
-public abstract class DataSinks {
-    private DataSinks() {}
-
-    /**
-     * Returns a {@link DataSink} which outputs received data into the provided
-     * {@link OutputStream}.
-     */
-    public static DataSink asDataSink(OutputStream out) {
-        return new OutputStreamDataSink(out);
-    }
-
-    /**
-     * Returns a {@link DataSink} which outputs received data into the provided file, sequentially,
-     * starting at the beginning of the file.
-     */
-    public static DataSink asDataSink(RandomAccessFile file) {
-        return new RandomAccessFileDataSink(file);
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/util/DataSource.java b/tools/apksigner/core/src/com/android/apksigner/core/util/DataSource.java
deleted file mode 100644
index e268dd2..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/util/DataSource.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.util;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * Abstract representation of a source of data.
- *
- * <p>This abstraction serves three purposes:
- * <ul>
- * <li>Transparent handling of different types of sources, such as {@code byte[]},
- *     {@link java.nio.ByteBuffer}, {@link java.io.RandomAccessFile}, memory-mapped file.</li>
- * <li>Support sources larger than 2 GB. If all sources were smaller than 2 GB, {@code ByteBuffer}
- *     may have worked as the unifying abstraction.</li>
- * <li>Support sources which do not fit into logical memory as a contiguous region.</li>
- * </ul>
- *
- * <p>There are following ways to obtain a chunk of data from the data source:
- * <ul>
- * <li>Stream the chunk's data into a {@link DataSink} using
- *     {@link #feed(long, long, DataSink) feed}. This is best suited for scenarios where there is no
- *     need to have the chunk's data accessible at the same time, for example, when computing the
- *     digest of the chunk. If you need to keep the chunk's data around after {@code feed}
- *     completes, you must create a copy during {@code feed}. However, in that case the following
- *     methods of obtaining the chunk's data may be more appropriate.</li>
- * <li>Obtain a {@link ByteBuffer} containing the chunk's data using
- *     {@link #getByteBuffer(long, int) getByteBuffer}. Depending on the data source, the chunk's
- *     data may or may not be copied by this operation. This is best suited for scenarios where
- *     you need to access the chunk's data in arbitrary order, but don't need to modify the data and
- *     thus don't require a copy of the data.</li>
- * <li>Copy the chunk's data to a {@link ByteBuffer} using
- *     {@link #copyTo(long, int, ByteBuffer) copyTo}. This is best suited for scenarios where
- *     you require a copy of the chunk's data, such as to when you need to modify the data.
- *     </li>
- * </ul>
- */
-public interface DataSource {
-
-    /**
-     * Returns the amount of data (in bytes) contained in this data source.
-     */
-    long size();
-
-    /**
-     * Feeds the specified chunk from this data source into the provided sink.
-     *
-     * @param offset index (in bytes) at which the chunk starts inside data source
-     * @param size size (in bytes) of the chunk
-     */
-    void feed(long offset, long size, DataSink sink) throws IOException;
-
-    /**
-     * Returns a buffer holding the contents of the specified chunk of data from this data source.
-     * Changes to the data source are not guaranteed to be reflected in the returned buffer.
-     * Similarly, changes in the buffer are not guaranteed to be reflected in the data source.
-     *
-     * <p>The returned buffer's position is {@code 0}, and the buffer's limit and capacity is
-     * {@code size}.
-     *
-     * @param offset index (in bytes) at which the chunk starts inside data source
-     * @param size size (in bytes) of the chunk
-     */
-    ByteBuffer getByteBuffer(long offset, int size) throws IOException;
-
-    /**
-     * Copies the specified chunk from this data source into the provided destination buffer,
-     * advancing the destination buffer's position by {@code size}.
-     *
-     * @param offset index (in bytes) at which the chunk starts inside data source
-     * @param size size (in bytes) of the chunk
-     */
-    void copyTo(long offset, int size, ByteBuffer dest) throws IOException;
-
-    /**
-     * Returns a data source representing the specified region of data of this data source. Changes
-     * to data represented by this data source will also be visible in the returned data source.
-     *
-     * @param offset index (in bytes) at which the region starts inside data source
-     * @param size size (in bytes) of the region
-     */
-    DataSource slice(long offset, long size);
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/util/DataSources.java b/tools/apksigner/core/src/com/android/apksigner/core/util/DataSources.java
deleted file mode 100644
index 1cbb0af..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/util/DataSources.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.android.apksigner.core.util;
-
-import com.android.apksigner.core.internal.util.ByteBufferDataSource;
-import com.android.apksigner.core.internal.util.RandomAccessFileDataSource;
-
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-
-/**
- * Utility methods for working with {@link DataSource} abstraction.
- */
-public abstract class DataSources {
-    private DataSources() {}
-
-    /**
-     * Returns a {@link DataSource} backed by the provided {@link ByteBuffer}. The data source
-     * represents the data contained between the position and limit of the buffer. Changes to the
-     * buffer's contents will be visible in the data source.
-     */
-    public static DataSource asDataSource(ByteBuffer buffer) {
-        if (buffer == null) {
-            throw new NullPointerException();
-        }
-        return new ByteBufferDataSource(buffer);
-    }
-
-    /**
-     * Returns a {@link DataSource} backed by the provided {@link RandomAccessFile}. Changes to the
-     * file, including changes to size of file, will be visible in the data source.
-     */
-    public static DataSource asDataSource(RandomAccessFile file) {
-        if (file == null) {
-            throw new NullPointerException();
-        }
-        return new RandomAccessFileDataSource(file);
-    }
-
-    /**
-     * Returns a {@link DataSource} backed by the provided region of the {@link RandomAccessFile}.
-     * Changes to the file will be visible in the data source.
-     */
-    public static DataSource asDataSource(RandomAccessFile file, long offset, long size) {
-        if (file == null) {
-            throw new NullPointerException();
-        }
-        return new RandomAccessFileDataSource(file, offset, size);
-    }
-}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/zip/ZipFormatException.java b/tools/apksigner/core/src/com/android/apksigner/core/zip/ZipFormatException.java
deleted file mode 100644
index 7da57d9..0000000
--- a/tools/apksigner/core/src/com/android/apksigner/core/zip/ZipFormatException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.apksigner.core.zip;
-
-/**
- * Indicates that a ZIP archive is not well-formed.
- */
-public class ZipFormatException extends Exception {
-    private static final long serialVersionUID = 1L;
-
-    public ZipFormatException(String message) {
-        super(message);
-    }
-
-    public ZipFormatException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/tools/signapk/Android.mk b/tools/signapk/Android.mk
index eff066c..4506e2f 100644
--- a/tools/signapk/Android.mk
+++ b/tools/signapk/Android.mk
@@ -22,7 +22,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_JAR_MANIFEST := SignApk.mf
 LOCAL_STATIC_JAVA_LIBRARIES := \
-    apksigner-core \
+    apksig \
     bouncycastle-host \
     bouncycastle-bcpkix-host \
     conscrypt-host
diff --git a/tools/signapk/src/com/android/signapk/SignApk.java b/tools/signapk/src/com/android/signapk/SignApk.java
index f1f340d..84fddec 100644
--- a/tools/signapk/src/com/android/signapk/SignApk.java
+++ b/tools/signapk/src/com/android/signapk/SignApk.java
@@ -34,12 +34,12 @@
 import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
 import org.conscrypt.OpenSSLProvider;
 
-import com.android.apksigner.core.ApkSignerEngine;
-import com.android.apksigner.core.DefaultApkSignerEngine;
-import com.android.apksigner.core.apk.ApkUtils;
-import com.android.apksigner.core.util.DataSink;
-import com.android.apksigner.core.util.DataSources;
-import com.android.apksigner.core.zip.ZipFormatException;
+import com.android.apksig.ApkSignerEngine;
+import com.android.apksig.DefaultApkSignerEngine;
+import com.android.apksig.apk.ApkUtils;
+import com.android.apksig.util.DataSink;
+import com.android.apksig.util.DataSources;
+import com.android.apksig.zip.ZipFormatException;
 
 import java.io.Console;
 import java.io.BufferedReader;
