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
new file mode 100644
index 0000000..8cc8c90
--- /dev/null
+++ b/tools/apksigner/core/src/com/android/apksigner/core/apk/ApkUtils.java
@@ -0,0 +1,158 @@
+/*
+ * 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/zip/ZipUtils.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/zip/ZipUtils.java
index 7b47e50..51110b6 100644
--- 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
@@ -16,9 +16,14 @@
 
 package com.android.apksigner.core.internal.zip;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
+import com.android.apksigner.core.internal.util.ByteBufferSink;
+import com.android.apksigner.core.internal.util.Pair;
+import com.android.apksigner.core.util.DataSource;
+
 /**
  * Assorted ZIP format helpers.
  *
@@ -28,7 +33,20 @@
 public abstract class ZipUtils {
     private ZipUtils() {}
 
+    public static final short COMPRESSION_METHOD_STORED = 0;
+    public static final short COMPRESSION_METHOD_DEFLATED = 8;
+
+    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.
@@ -44,16 +62,221 @@
                 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);
+
+        ByteBuffer buf = ByteBuffer.allocate(ZIP_EOCD_REC_MIN_SIZE + maxCommentSize);
+        buf.order(ByteOrder.LITTLE_ENDIAN);
+        long bufOffsetInFile = fileSize - buf.capacity();
+        zip.feed(bufOffsetInFile, buf.remaining(), new ByteBufferSink(buf));
+        buf.flip();
+        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 = ByteBuffer.allocate(4);
+        sig.order(ByteOrder.LITTLE_ENDIAN);
+        zip.feed(locatorPosition, sig.remaining(), new ByteBufferSink(sig));
+        sig.flip();
+        return sig.getInt(0) == ZIP64_EOCD_LOCATOR_SIG;
+    }
+
     private static void assertByteOrderLittleEndian(ByteBuffer buffer) {
         if (buffer.order() != ByteOrder.LITTLE_ENDIAN) {
             throw new IllegalArgumentException("ByteBuffer byte order must be little endian");
         }
     }
 
+    private static int getUnsignedInt16(ByteBuffer buffer, int offset) {
+        return buffer.getShort(offset) & 0xffff;
+    }
+
     private 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(buffer.position() + offset, (int) value);
+        buffer.putInt(offset, (int) value);
+    }
+
+    private static long getUnsignedInt32(ByteBuffer buffer, int offset) {
+        return buffer.getInt(offset) & 0xffffffffL;
     }
 }
\ No newline at end of file
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
new file mode 100644
index 0000000..7da57d9
--- /dev/null
+++ b/tools/apksigner/core/src/com/android/apksigner/core/zip/ZipFormatException.java
@@ -0,0 +1,32 @@
+/*
+ * 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 ac217c7..eff066c 100644
--- a/tools/signapk/Android.mk
+++ b/tools/signapk/Android.mk
@@ -21,7 +21,11 @@
 LOCAL_MODULE := signapk
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_JAR_MANIFEST := SignApk.mf
-LOCAL_STATIC_JAVA_LIBRARIES := bouncycastle-host bouncycastle-bcpkix-host conscrypt-host
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    apksigner-core \
+    bouncycastle-host \
+    bouncycastle-bcpkix-host \
+    conscrypt-host
 LOCAL_REQUIRED_MODULES := libconscrypt_openjdk_jni
 include $(BUILD_HOST_JAVA_LIBRARY)
 
diff --git a/tools/signapk/src/com/android/signapk/ApkSignerV2.java b/tools/signapk/src/com/android/signapk/ApkSignerV2.java
deleted file mode 100644
index 7b617db..0000000
--- a/tools/signapk/src/com/android/signapk/ApkSignerV2.java
+++ /dev/null
@@ -1,725 +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.signapk;
-
-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.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.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.MGF1ParameterSpec;
-import java.security.spec.PSSParameterSpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.ArrayList;
-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.
- */
-public abstract class ApkSignerV2 {
-    /*
-     * 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.
-     */
-
-    public static final int SIGNATURE_RSA_PSS_WITH_SHA256 = 0x0101;
-    public static final int SIGNATURE_RSA_PSS_WITH_SHA512 = 0x0102;
-    public static final int SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA256 = 0x0103;
-    public static final int SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA512 = 0x0104;
-    public static final int SIGNATURE_ECDSA_WITH_SHA256 = 0x0201;
-    public static final int SIGNATURE_ECDSA_WITH_SHA512 = 0x0202;
-    public static final int SIGNATURE_DSA_WITH_SHA256 = 0x0301;
-
-    /**
-     * {@code .SF} file header section attribute indicating that the APK is signed not just with
-     * JAR signature scheme but also with APK Signature Scheme v2 or newer. This attribute
-     * facilitates v2 signature stripping detection.
-     *
-     * <p>The attribute contains a comma-separated set of signature scheme IDs.
-     */
-    public static final String SF_ATTRIBUTE_ANDROID_APK_SIGNED_NAME = "X-Android-APK-Signed";
-    public static final String SF_ATTRIBUTE_ANDROID_APK_SIGNED_VALUE = "2";
-
-    private static final int CONTENT_DIGEST_CHUNKED_SHA256 = 0;
-    private static final int CONTENT_DIGEST_CHUNKED_SHA512 = 1;
-
-    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;
-
-    private ApkSignerV2() {}
-
-    /**
-     * Signer configuration.
-     */
-    public static final 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 (see {@code SIGNATURE_...} constants).
-         */
-        public List<Integer> signatureAlgorithms;
-    }
-
-    /**
-     * Signs the provided APK using APK Signature Scheme v2 and returns the signed APK as a list of
-     * consecutive chunks.
-     *
-     * <p>NOTE: To enable APK signature verifier to detect v2 signature stripping, header sections
-     * of META-INF/*.SF files of APK being signed must contain the
-     * {@code X-Android-APK-Signed: true} attribute.
-     *
-     * @param inputApk contents of the APK to be signed. The APK starts at the current position
-     *        of the buffer and ends at the limit of the buffer.
-     * @param signerConfigs signer configurations, one for each signer.
-     *
-     * @throws ApkParseException if the APK cannot be parsed.
-     * @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 ByteBuffer[] sign(
-            ByteBuffer inputApk,
-            List<SignerConfig> signerConfigs)
-                    throws ApkParseException, InvalidKeyException, SignatureException {
-        // Slice/create a view in the inputApk to make sure that:
-        // 1. inputApk is what's between position and limit of the original inputApk, and
-        // 2. changes to position, limit, and byte order are not reflected in the original.
-        ByteBuffer originalInputApk = inputApk;
-        inputApk = originalInputApk.slice();
-        inputApk.order(ByteOrder.LITTLE_ENDIAN);
-
-        // Locate ZIP End of Central Directory (EoCD), Central Directory, and check that Central
-        // Directory is immediately followed by the ZIP End of Central Directory.
-        int eocdOffset = ZipUtils.findZipEndOfCentralDirectoryRecord(inputApk);
-        if (eocdOffset == -1) {
-            throw new ApkParseException("Failed to locate ZIP End of Central Directory");
-        }
-        if (ZipUtils.isZip64EndOfCentralDirectoryLocatorPresent(inputApk, eocdOffset)) {
-            throw new ApkParseException("ZIP64 format not supported");
-        }
-        inputApk.position(eocdOffset);
-        long centralDirSizeLong = ZipUtils.getZipEocdCentralDirectorySizeBytes(inputApk);
-        if (centralDirSizeLong > Integer.MAX_VALUE) {
-            throw new ApkParseException(
-                    "ZIP Central Directory size out of range: " + centralDirSizeLong);
-        }
-        int centralDirSize = (int) centralDirSizeLong;
-        long centralDirOffsetLong = ZipUtils.getZipEocdCentralDirectoryOffset(inputApk);
-        if (centralDirOffsetLong > Integer.MAX_VALUE) {
-            throw new ApkParseException(
-                    "ZIP Central Directory offset in file out of range: " + centralDirOffsetLong);
-        }
-        int centralDirOffset = (int) centralDirOffsetLong;
-        int expectedEocdOffset = centralDirOffset + centralDirSize;
-        if (expectedEocdOffset < centralDirOffset) {
-            throw new ApkParseException(
-                    "ZIP Central Directory extent too large. Offset: " + centralDirOffset
-                            + ", size: " + centralDirSize);
-        }
-        if (eocdOffset != expectedEocdOffset) {
-            throw new ApkParseException(
-                    "ZIP Central Directory not immeiately followed by ZIP End of"
-                            + " Central Directory. CD end: " + expectedEocdOffset
-                            + ", EoCD start: " + eocdOffset);
-        }
-
-        // Create ByteBuffers holding the contents of everything before ZIP Central Directory,
-        // ZIP Central Directory, and ZIP End of Central Directory.
-        inputApk.clear();
-        ByteBuffer beforeCentralDir = getByteBuffer(inputApk, centralDirOffset);
-        ByteBuffer centralDir = getByteBuffer(inputApk, eocdOffset - centralDirOffset);
-        // Create a copy of End of Central Directory because we'll need modify its contents later.
-        byte[] eocdBytes = new byte[inputApk.remaining()];
-        inputApk.get(eocdBytes);
-        ByteBuffer eocd = ByteBuffer.wrap(eocdBytes);
-        eocd.order(inputApk.order());
-
-        // Figure which which digests to use for APK contents.
-        Set<Integer> contentDigestAlgorithms = new HashSet<>();
-        for (SignerConfig signerConfig : signerConfigs) {
-            for (int signatureAlgorithm : signerConfig.signatureAlgorithms) {
-                contentDigestAlgorithms.add(
-                        getSignatureAlgorithmContentDigestAlgorithm(signatureAlgorithm));
-            }
-        }
-
-        // Compute digests of APK contents.
-        Map<Integer, byte[]> contentDigests; // digest algorithm ID -> digest
-        try {
-            contentDigests =
-                    computeContentDigests(
-                            contentDigestAlgorithms,
-                            new ByteBuffer[] {beforeCentralDir, centralDir, eocd});
-        } 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.
-        ByteBuffer apkSigningBlock =
-                ByteBuffer.wrap(generateApkSigningBlock(signerConfigs, contentDigests));
-
-        // Update Central Directory Offset in End of Central Directory Record. Central Directory
-        // follows the APK Signing Block and thus is shifted by the size of the APK Signing Block.
-        centralDirOffset += apkSigningBlock.remaining();
-        eocd.clear();
-        ZipUtils.setZipEocdCentralDirectoryOffset(eocd, centralDirOffset);
-
-        // Follow the Java NIO pattern for ByteBuffer whose contents have been consumed.
-        originalInputApk.position(originalInputApk.limit());
-
-        // Reset positions (to 0) and limits (to capacity) in the ByteBuffers below to follow the
-        // Java NIO pattern for ByteBuffers which are ready for their contents to be read by caller.
-        // Contrary to the name, this does not clear the contents of these ByteBuffer.
-        beforeCentralDir.clear();
-        centralDir.clear();
-        eocd.clear();
-
-        // Insert APK Signing Block immediately before the ZIP Central Directory.
-        return new ByteBuffer[] {
-            beforeCentralDir,
-            apkSigningBlock,
-            centralDir,
-            eocd,
-        };
-    }
-
-    private static Map<Integer, byte[]> computeContentDigests(
-            Set<Integer> digestAlgorithms,
-            ByteBuffer[] contents) throws 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.
-
-        int chunkCount = 0;
-        for (ByteBuffer input : contents) {
-            chunkCount += getChunkCount(input.remaining(), CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES);
-        }
-
-        final Map<Integer, byte[]> digestsOfChunks = new HashMap<>(digestAlgorithms.size());
-        for (int digestAlgorithm : digestAlgorithms) {
-            int digestOutputSizeBytes = getContentDigestAlgorithmOutputSizeBytes(digestAlgorithm);
-            byte[] concatenationOfChunkCountAndChunkDigests =
-                    new byte[5 + chunkCount * digestOutputSizeBytes];
-            concatenationOfChunkCountAndChunkDigests[0] = 0x5a;
-            setUnsignedInt32LittleEngian(
-                    chunkCount, concatenationOfChunkCountAndChunkDigests, 1);
-            digestsOfChunks.put(digestAlgorithm, concatenationOfChunkCountAndChunkDigests);
-        }
-
-        int chunkIndex = 0;
-        byte[] chunkContentPrefix = new byte[5];
-        chunkContentPrefix[0] = (byte) 0xa5;
-        // Optimization opportunity: digests of chunks can be computed in parallel.
-        for (ByteBuffer input : contents) {
-            while (input.hasRemaining()) {
-                int chunkSize =
-                        Math.min(input.remaining(), CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES);
-                final ByteBuffer chunk = getByteBuffer(input, chunkSize);
-                for (int digestAlgorithm : digestAlgorithms) {
-                    String jcaAlgorithmName =
-                            getContentDigestAlgorithmJcaDigestAlgorithm(digestAlgorithm);
-                    MessageDigest md;
-                    try {
-                        md = MessageDigest.getInstance(jcaAlgorithmName);
-                    } catch (NoSuchAlgorithmException e) {
-                        throw new DigestException(
-                                jcaAlgorithmName + " MessageDigest not supported", e);
-                    }
-                    // Reset position to 0 and limit to capacity. Position would've been modified
-                    // by the preceding iteration of this loop. NOTE: Contrary to the method name,
-                    // this does not modify the contents of the chunk.
-                    chunk.clear();
-                    setUnsignedInt32LittleEngian(chunk.remaining(), chunkContentPrefix, 1);
-                    md.update(chunkContentPrefix);
-                    md.update(chunk);
-                    byte[] concatenationOfChunkCountAndChunkDigests =
-                            digestsOfChunks.get(digestAlgorithm);
-                    int expectedDigestSizeBytes =
-                            getContentDigestAlgorithmOutputSizeBytes(digestAlgorithm);
-                    int actualDigestSizeBytes =
-                            md.digest(
-                                    concatenationOfChunkCountAndChunkDigests,
-                                    5 + chunkIndex * expectedDigestSizeBytes,
-                                    expectedDigestSizeBytes);
-                    if (actualDigestSizeBytes != expectedDigestSizeBytes) {
-                        throw new DigestException(
-                                "Unexpected output size of " + md.getAlgorithm()
-                                        + " digest: " + actualDigestSizeBytes);
-                    }
-                }
-                chunkIndex++;
-            }
-        }
-
-        Map<Integer, byte[]> result = new HashMap<>(digestAlgorithms.size());
-        for (Map.Entry<Integer, byte[]> entry : digestsOfChunks.entrySet()) {
-            int digestAlgorithm = entry.getKey();
-            byte[] concatenationOfChunkCountAndChunkDigests = entry.getValue();
-            String jcaAlgorithmName = getContentDigestAlgorithmJcaDigestAlgorithm(digestAlgorithm);
-            MessageDigest md;
-            try {
-                md = MessageDigest.getInstance(jcaAlgorithmName);
-            } catch (NoSuchAlgorithmException e) {
-                throw new DigestException(jcaAlgorithmName + " MessageDigest not supported", e);
-            }
-            result.put(digestAlgorithm, md.digest(concatenationOfChunkCountAndChunkDigests));
-        }
-        return result;
-    }
-
-    private static final int getChunkCount(int inputSize, int chunkSize) {
-        return (inputSize + chunkSize - 1) / chunkSize;
-    }
-
-    private static void setUnsignedInt32LittleEngian(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<Integer, byte[]> contentDigests) throws 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<Integer, byte[]> contentDigests) throws 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<Integer, byte[]> contentDigests) throws 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 (int signatureAlgorithm : signerConfig.signatureAlgorithms) {
-            int contentDigestAlgorithm =
-                    getSignatureAlgorithmContentDigestAlgorithm(signatureAlgorithm);
-            byte[] contentDigest = contentDigests.get(contentDigestAlgorithm);
-            if (contentDigest == null) {
-                throw new RuntimeException(
-                        getContentDigestAlgorithmJcaDigestAlgorithm(contentDigestAlgorithm)
-                        + " content digest for "
-                        + getSignatureAlgorithmJcaSignatureAlgorithm(signatureAlgorithm)
-                        + " not computed");
-            }
-            digests.add(Pair.create(signatureAlgorithm, 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<>();
-        for (int signatureAlgorithm : signerConfig.signatureAlgorithms) {
-            Pair<String, ? extends AlgorithmParameterSpec> signatureParams =
-                    getSignatureAlgorithmJcaSignatureAlgorithm(signatureAlgorithm);
-            String jcaSignatureAlgorithm = signatureParams.getFirst();
-            AlgorithmParameterSpec jcaSignatureAlgorithmParams = signatureParams.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 sign using " + jcaSignatureAlgorithm, e);
-            } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException
-                    | SignatureException e) {
-                throw new SignatureException("Failed 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 (NoSuchAlgorithmException | InvalidAlgorithmParameterException
-                    | SignatureException e) {
-                throw new SignatureException("Failed to verify generated " + jcaSignatureAlgorithm
-                        + " signature using public key from certificate", e);
-            }
-
-            signer.signatures.add(Pair.create(signatureAlgorithm, 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 {
-        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 (NoSuchAlgorithmException | 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;
-    }
-
-    public static List<byte[]> encodeCertificates(List<X509Certificate> certificates)
-            throws CertificateEncodingException {
-        List<byte[]> result = new ArrayList<>();
-        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();
-    }
-
-    /**
-     * 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) {
-        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 Pair<String, ? extends AlgorithmParameterSpec>
-            getSignatureAlgorithmJcaSignatureAlgorithm(int sigAlgorithm) {
-        switch (sigAlgorithm) {
-            case SIGNATURE_RSA_PSS_WITH_SHA256:
-                return Pair.create(
-                        "SHA256withRSA/PSS",
-                        new PSSParameterSpec(
-                                "SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 256 / 8, 1));
-            case SIGNATURE_RSA_PSS_WITH_SHA512:
-                return Pair.create(
-                        "SHA512withRSA/PSS",
-                        new PSSParameterSpec(
-                                "SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 512 / 8, 1));
-            case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA256:
-                return Pair.create("SHA256withRSA", null);
-            case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA512:
-                return Pair.create("SHA512withRSA", null);
-            case SIGNATURE_ECDSA_WITH_SHA256:
-                return Pair.create("SHA256withECDSA", null);
-            case SIGNATURE_ECDSA_WITH_SHA512:
-                return Pair.create("SHA512withECDSA", null);
-            case SIGNATURE_DSA_WITH_SHA256:
-                return Pair.create("SHA256withDSA", null);
-            default:
-                throw new IllegalArgumentException(
-                        "Unknown signature algorithm: 0x"
-                                + Long.toHexString(sigAlgorithm & 0xffffffff));
-        }
-    }
-
-    private static int getSignatureAlgorithmContentDigestAlgorithm(int sigAlgorithm) {
-        switch (sigAlgorithm) {
-            case SIGNATURE_RSA_PSS_WITH_SHA256:
-            case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA256:
-            case SIGNATURE_ECDSA_WITH_SHA256:
-            case SIGNATURE_DSA_WITH_SHA256:
-                return CONTENT_DIGEST_CHUNKED_SHA256;
-            case SIGNATURE_RSA_PSS_WITH_SHA512:
-            case SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA512:
-            case SIGNATURE_ECDSA_WITH_SHA512:
-                return CONTENT_DIGEST_CHUNKED_SHA512;
-            default:
-                throw new IllegalArgumentException(
-                        "Unknown signature algorithm: 0x"
-                                + Long.toHexString(sigAlgorithm & 0xffffffff));
-        }
-    }
-
-    private static String getContentDigestAlgorithmJcaDigestAlgorithm(int digestAlgorithm) {
-        switch (digestAlgorithm) {
-            case CONTENT_DIGEST_CHUNKED_SHA256:
-                return "SHA-256";
-            case CONTENT_DIGEST_CHUNKED_SHA512:
-                return "SHA-512";
-            default:
-                throw new IllegalArgumentException(
-                        "Unknown content digest algorthm: " + digestAlgorithm);
-        }
-    }
-
-    private static int getContentDigestAlgorithmOutputSizeBytes(int digestAlgorithm) {
-        switch (digestAlgorithm) {
-            case CONTENT_DIGEST_CHUNKED_SHA256:
-                return 256 / 8;
-            case CONTENT_DIGEST_CHUNKED_SHA512:
-                return 512 / 8;
-            default:
-                throw new IllegalArgumentException(
-                        "Unknown content digest algorthm: " + digestAlgorithm);
-        }
-    }
-
-    /**
-     * Indicates that APK file could not be parsed.
-     */
-    public static class ApkParseException extends Exception {
-        private static final long serialVersionUID = 1L;
-
-        public ApkParseException(String message) {
-            super(message);
-        }
-
-        public ApkParseException(String message, Throwable cause) {
-            super(message, cause);
-        }
-    }
-}
diff --git a/tools/signapk/src/com/android/signapk/Pair.java b/tools/signapk/src/com/android/signapk/Pair.java
deleted file mode 100644
index e4a6c92..0000000
--- a/tools/signapk/src/com/android/signapk/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.signapk;
-
-/**
- * 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> create(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/signapk/src/com/android/signapk/SignApk.java b/tools/signapk/src/com/android/signapk/SignApk.java
index a7c9fc3..d84d070 100644
--- a/tools/signapk/src/com/android/signapk/SignApk.java
+++ b/tools/signapk/src/com/android/signapk/SignApk.java
@@ -23,7 +23,6 @@
 import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
 import org.bouncycastle.cert.jcajce.JcaCertStore;
 import org.bouncycastle.cms.CMSException;
-import org.bouncycastle.cms.CMSProcessableByteArray;
 import org.bouncycastle.cms.CMSSignedData;
 import org.bouncycastle.cms.CMSSignedDataGenerator;
 import org.bouncycastle.cms.CMSTypedData;
@@ -33,9 +32,15 @@
 import org.bouncycastle.operator.OperatorCreationException;
 import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
 import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
-import org.bouncycastle.util.encoders.Base64;
 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 java.io.Console;
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
@@ -49,19 +54,14 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
-import java.io.PrintStream;
 import java.lang.reflect.Constructor;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
-import java.security.DigestOutputStream;
 import java.security.GeneralSecurityException;
-import java.security.InvalidKeyException;
 import java.security.Key;
 import java.security.KeyFactory;
-import java.security.MessageDigest;
 import java.security.PrivateKey;
 import java.security.Provider;
-import java.security.PublicKey;
 import java.security.Security;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateFactory;
@@ -71,17 +71,12 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import java.util.TimeZone;
-import java.util.TreeMap;
-import java.util.jar.Attributes;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
 import java.util.regex.Pattern;
 
 import javax.crypto.Cipher;
@@ -113,11 +108,6 @@
  * APK Signature Scheme v2.
  */
 class SignApk {
-    private static final String CERT_SF_NAME = "META-INF/CERT.SF";
-    private static final String CERT_SIG_NAME = "META-INF/CERT.%s";
-    private static final String CERT_SF_MULTI_NAME = "META-INF/CERT%d.SF";
-    private static final String CERT_SIG_MULTI_NAME = "META-INF/CERT%d.%s";
-
     private static final String OTACERT_NAME = "META-INF/com/android/otacert";
 
     /**
@@ -137,36 +127,6 @@
     private static final int USE_SHA1 = 1;
     private static final int USE_SHA256 = 2;
 
-    /** Digest algorithm used when signing the APK using APK Signature Scheme v2. */
-    private static final String APK_SIG_SCHEME_V2_DIGEST_ALGORITHM = "SHA-256";
-
-    /**
-     * Returns the digest algorithm ID (one of {@code USE_SHA1} or {@code USE_SHA256}) to be used
-     * for v1 signing (JAR signing) an APK using the private key corresponding to the provided
-     * certificate.
-     *
-     * @param minSdkVersion minimum Android platform API Level supported by the APK (see
-     *        minSdkVersion attribute in AndroidManifest.xml). The higher the minSdkVersion, the
-     *        stronger hash may be used for signing the APK.
-     */
-    private static int getV1DigestAlgorithmForApk(X509Certificate cert, int minSdkVersion) {
-        String keyAlgorithm = cert.getPublicKey().getAlgorithm();
-        if ("RSA".equalsIgnoreCase(keyAlgorithm)) {
-            // RSA can be used only with SHA-1 prior to API Level 18.
-            return (minSdkVersion < 18) ? USE_SHA1 : USE_SHA256;
-        } else if ("EC".equalsIgnoreCase(keyAlgorithm)) {
-            // ECDSA cannot be used prior to API Level 18 at all. It can only be used with SHA-1
-            // on API Levels 18, 19, and 20.
-            if (minSdkVersion < 18) {
-                throw new IllegalArgumentException(
-                        "ECDSA signatures only supported for minSdkVersion 18 and higher");
-            }
-            return (minSdkVersion < 21) ? USE_SHA1 : USE_SHA256;
-        } else {
-            throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm);
-        }
-    }
-
     /**
      * Returns the digest algorithm ID (one of {@code USE_SHA1} or {@code USE_SHA256}) to be used
      * for signing an OTA update package using the private key corresponding to the provided
@@ -187,10 +147,10 @@
 
     /**
      * Returns the JCA {@link java.security.Signature} algorithm to be used for signing and OTA
-     * or v1 signing an APK using the private key corresponding to the provided certificate and the
+     * update package using the private key corresponding to the provided certificate and the
      * provided digest algorithm (see {@code USE_SHA1} and {@code USE_SHA256} constants).
      */
-    private static String getJcaSignatureAlgorithmForV1SigningOrOta(
+    private static String getJcaSignatureAlgorithmForOta(
             X509Certificate cert, int hash) {
         String sigAlgDigestPrefix;
         switch (hash) {
@@ -214,11 +174,6 @@
         }
     }
 
-    /* Files matching this pattern are not copied to the output. */
-    private static final Pattern STRIP_PATTERN =
-            Pattern.compile("^(META-INF/((.*)[.](SF|RSA|DSA|EC)|com/android/otacert))|("
-                    + Pattern.quote(JarFile.MANIFEST_NAME) + ")$");
-
     private static X509Certificate readPublicKey(File file)
         throws IOException, GeneralSecurityException {
         FileInputStream input = new FileInputStream(file);
@@ -324,89 +279,6 @@
     }
 
     /**
-     * Add the hash(es) of every file to the manifest, creating it if
-     * necessary.
-     */
-    private static Manifest addDigestsToManifest(
-            JarFile jar, Pattern ignoredFilenamePattern, int hashes)
-                    throws IOException, GeneralSecurityException {
-        Manifest input = jar.getManifest();
-        Manifest output = new Manifest();
-        Attributes main = output.getMainAttributes();
-        if (input != null) {
-            main.putAll(input.getMainAttributes());
-        } else {
-            main.putValue("Manifest-Version", "1.0");
-            main.putValue("Created-By", "1.0 (Android SignApk)");
-        }
-
-        MessageDigest md_sha1 = null;
-        MessageDigest md_sha256 = null;
-        if ((hashes & USE_SHA1) != 0) {
-            md_sha1 = MessageDigest.getInstance("SHA1");
-        }
-        if ((hashes & USE_SHA256) != 0) {
-            md_sha256 = MessageDigest.getInstance("SHA256");
-        }
-
-        byte[] buffer = new byte[4096];
-        int num;
-
-        // We sort the input entries by name, and add them to the
-        // output manifest in sorted order.  We expect that the output
-        // map will be deterministic.
-
-        TreeMap<String, JarEntry> byName = new TreeMap<String, JarEntry>();
-
-        for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements(); ) {
-            JarEntry entry = e.nextElement();
-            byName.put(entry.getName(), entry);
-        }
-
-        for (JarEntry entry: byName.values()) {
-            String name = entry.getName();
-            if (!entry.isDirectory()
-                    && (ignoredFilenamePattern == null
-                            || !ignoredFilenamePattern.matcher(name).matches())) {
-                InputStream data = jar.getInputStream(entry);
-                while ((num = data.read(buffer)) > 0) {
-                    if (md_sha1 != null) md_sha1.update(buffer, 0, num);
-                    if (md_sha256 != null) md_sha256.update(buffer, 0, num);
-                }
-
-                Attributes attr = null;
-                if (input != null) attr = input.getAttributes(name);
-                attr = attr != null ? new Attributes(attr) : new Attributes();
-                // Remove any previously computed digests from this entry's attributes.
-                for (Iterator<Object> i = attr.keySet().iterator(); i.hasNext();) {
-                    Object key = i.next();
-                    if (!(key instanceof Attributes.Name)) {
-                        continue;
-                    }
-                    String attributeNameLowerCase =
-                            ((Attributes.Name) key).toString().toLowerCase(Locale.US);
-                    if (attributeNameLowerCase.endsWith("-digest")) {
-                        i.remove();
-                    }
-                }
-                // Add SHA-1 digest if requested
-                if (md_sha1 != null) {
-                    attr.putValue("SHA1-Digest",
-                                  new String(Base64.encode(md_sha1.digest()), "ASCII"));
-                }
-                // Add SHA-256 digest if requested
-                if (md_sha256 != null) {
-                    attr.putValue("SHA-256-Digest",
-                                  new String(Base64.encode(md_sha256.digest()), "ASCII"));
-                }
-                output.getEntries().put(name, attr);
-            }
-        }
-
-        return output;
-    }
-
-    /**
      * Add a copy of the public key to the archive; this should
      * exactly match one of the files in
      * /system/etc/security/otacerts.zip on the device.  (The same
@@ -416,7 +288,7 @@
     private static void addOtacert(JarOutputStream outputJar,
                                    File publicKeyFile,
                                    long timestamp)
-        throws IOException, GeneralSecurityException {
+        throws IOException {
 
         JarEntry je = new JarEntry(OTACERT_NAME);
         je.setTime(timestamp);
@@ -431,94 +303,6 @@
     }
 
 
-    /** Write to another stream and track how many bytes have been
-     *  written.
-     */
-    private static class CountOutputStream extends FilterOutputStream {
-        private int mCount;
-
-        public CountOutputStream(OutputStream out) {
-            super(out);
-            mCount = 0;
-        }
-
-        @Override
-        public void write(int b) throws IOException {
-            super.write(b);
-            mCount++;
-        }
-
-        @Override
-        public void write(byte[] b, int off, int len) throws IOException {
-            super.write(b, off, len);
-            mCount += len;
-        }
-
-        public int size() {
-            return mCount;
-        }
-    }
-
-    /** Write a .SF file with a digest of the specified manifest. */
-    private static void writeSignatureFile(Manifest manifest, OutputStream out,
-            int hash, boolean additionallySignedUsingAnApkSignatureScheme)
-        throws IOException, GeneralSecurityException {
-        Manifest sf = new Manifest();
-        Attributes main = sf.getMainAttributes();
-        main.putValue("Signature-Version", "1.0");
-        main.putValue("Created-By", "1.0 (Android SignApk)");
-        if (additionallySignedUsingAnApkSignatureScheme) {
-            // Add APK Signature Scheme v2 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.
-            main.putValue(
-                    ApkSignerV2.SF_ATTRIBUTE_ANDROID_APK_SIGNED_NAME,
-                    ApkSignerV2.SF_ATTRIBUTE_ANDROID_APK_SIGNED_VALUE);
-        }
-
-        MessageDigest md = MessageDigest.getInstance(
-            hash == USE_SHA256 ? "SHA256" : "SHA1");
-        PrintStream print = new PrintStream(
-            new DigestOutputStream(new ByteArrayOutputStream(), md),
-            true, "UTF-8");
-
-        // Digest of the entire manifest
-        manifest.write(print);
-        print.flush();
-        main.putValue(hash == USE_SHA256 ? "SHA-256-Digest-Manifest" : "SHA1-Digest-Manifest",
-                      new String(Base64.encode(md.digest()), "ASCII"));
-
-        Map<String, Attributes> entries = manifest.getEntries();
-        for (Map.Entry<String, Attributes> entry : entries.entrySet()) {
-            // Digest of the manifest stanza for this entry.
-            print.print("Name: " + entry.getKey() + "\r\n");
-            for (Map.Entry<Object, Object> att : entry.getValue().entrySet()) {
-                print.print(att.getKey() + ": " + att.getValue() + "\r\n");
-            }
-            print.print("\r\n");
-            print.flush();
-
-            Attributes sfAttr = new Attributes();
-            sfAttr.putValue(hash == USE_SHA256 ? "SHA-256-Digest" : "SHA1-Digest",
-                            new String(Base64.encode(md.digest()), "ASCII"));
-            sf.getEntries().put(entry.getKey(), sfAttr);
-        }
-
-        CountOutputStream cout = new CountOutputStream(out);
-        sf.write(cout);
-
-        // 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 ((cout.size() % 1024) == 0) {
-            cout.write('\r');
-            cout.write('\n');
-        }
-    }
-
     /** Sign data and write the digital signature to 'out'. */
     private static void writeSignatureBlock(
         CMSTypedData data, X509Certificate publicKey, PrivateKey privateKey, int hash,
@@ -534,7 +318,7 @@
         CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
         ContentSigner signer =
                 new JcaContentSignerBuilder(
-                        getJcaSignatureAlgorithmForV1SigningOrOta(publicKey, hash))
+                        getJcaSignatureAlgorithmForOta(publicKey, hash))
                         .build(privateKey);
         gen.addSignerInfoGenerator(
             new JcaSignerInfoGeneratorBuilder(
@@ -552,12 +336,39 @@
     }
 
     /**
+     * Adds ZIP entries which represent the v1 signature (JAR signature scheme).
+     */
+    private static void addV1Signature(
+            ApkSignerEngine apkSigner,
+            ApkSignerEngine.OutputJarSignatureRequest v1Signature,
+            JarOutputStream out,
+            long timestamp) throws IOException {
+        for (ApkSignerEngine.OutputJarSignatureRequest.JarEntry entry
+                : v1Signature.getAdditionalJarEntries()) {
+            String entryName = entry.getName();
+            JarEntry outEntry = new JarEntry(entryName);
+            outEntry.setTime(timestamp);
+            out.putNextEntry(outEntry);
+            byte[] entryData = entry.getData();
+            out.write(entryData);
+            ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest =
+                    apkSigner.outputJarEntry(entryName);
+            if (inspectEntryRequest != null) {
+                inspectEntryRequest.getDataSink().consume(entryData, 0, entryData.length);
+                inspectEntryRequest.done();
+            }
+        }
+    }
+
+    /**
      * Copy all JAR entries from input to output. We set the modification times in the output to a
      * fixed time, so as to reduce variation in the output file and make incremental OTAs more
      * efficient.
      */
-    private static void copyFiles(JarFile in,
+    private static void copyFiles(
+            JarFile in,
             Pattern ignoredFilenamePattern,
+            ApkSignerEngine apkSigner,
             JarOutputStream out,
             long timestamp,
             int defaultAlignment) throws IOException {
@@ -589,12 +400,21 @@
         // the start of the file and makes it easier to do alignment
         // on them (since only stored entries are aligned).
 
+        List<String> remainingNames = new ArrayList<>(names.size());
         for (String name : names) {
             JarEntry inEntry = in.getJarEntry(name);
-            JarEntry outEntry = null;
-            if (inEntry.getMethod() != JarEntry.STORED) continue;
+            if (inEntry.getMethod() != JarEntry.STORED) {
+                // Defer outputting this entry until we're ready to output compressed entries.
+                remainingNames.add(name);
+                continue;
+            }
+
+            if (!shouldOutputApkEntry(apkSigner, in, inEntry, buffer)) {
+                continue;
+            }
+
             // Preserve the STORED method of the input entry.
-            outEntry = new JarEntry(inEntry);
+            JarEntry outEntry = new JarEntry(inEntry);
             outEntry.setTime(timestamp);
             // Discard comment and extra fields of this entry to
             // simplify alignment logic below and for consistency with
@@ -638,33 +458,97 @@
             offset += extra.length;
 
             out.putNextEntry(outEntry);
+            ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest =
+                    (apkSigner != null) ? apkSigner.outputJarEntry(name) : null;
+            DataSink entryDataSink =
+                    (inspectEntryRequest != null) ? inspectEntryRequest.getDataSink() : null;
 
-            InputStream data = in.getInputStream(inEntry);
-            while ((num = data.read(buffer)) > 0) {
-                out.write(buffer, 0, num);
-                offset += num;
+            try (InputStream data = in.getInputStream(inEntry)) {
+                while ((num = data.read(buffer)) > 0) {
+                    out.write(buffer, 0, num);
+                    if (entryDataSink != null) {
+                        entryDataSink.consume(buffer, 0, num);
+                    }
+                    offset += num;
+                }
             }
             out.flush();
+            if (inspectEntryRequest != null) {
+                inspectEntryRequest.done();
+            }
         }
 
         // Copy all the non-STORED entries.  We don't attempt to
         // maintain the 'offset' variable past this point; we don't do
         // alignment on these entries.
 
-        for (String name : names) {
+        for (String name : remainingNames) {
             JarEntry inEntry = in.getJarEntry(name);
-            JarEntry outEntry = null;
-            if (inEntry.getMethod() == JarEntry.STORED) continue;
+            if (!shouldOutputApkEntry(apkSigner, in, inEntry, buffer)) {
+                continue;
+            }
+
             // Create a new entry so that the compressed len is recomputed.
-            outEntry = new JarEntry(name);
+            JarEntry outEntry = new JarEntry(name);
             outEntry.setTime(timestamp);
             out.putNextEntry(outEntry);
+            ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest =
+                    (apkSigner != null) ? apkSigner.outputJarEntry(name) : null;
+            DataSink entryDataSink =
+                    (inspectEntryRequest != null) ? inspectEntryRequest.getDataSink() : null;
 
             InputStream data = in.getInputStream(inEntry);
             while ((num = data.read(buffer)) > 0) {
                 out.write(buffer, 0, num);
+                if (entryDataSink != null) {
+                    entryDataSink.consume(buffer, 0, num);
+                }
             }
             out.flush();
+            if (inspectEntryRequest != null) {
+                inspectEntryRequest.done();
+            }
+        }
+    }
+
+    private static boolean shouldOutputApkEntry(
+            ApkSignerEngine apkSigner, JarFile inFile, JarEntry inEntry, byte[] tmpbuf)
+                    throws IOException {
+        if (apkSigner == null) {
+            return true;
+        }
+
+        ApkSignerEngine.InputJarEntryInstructions instructions =
+                apkSigner.inputJarEntry(inEntry.getName());
+        ApkSignerEngine.InspectJarEntryRequest inspectEntryRequest =
+                instructions.getInspectJarEntryRequest();
+        if (inspectEntryRequest != null) {
+            provideJarEntry(inFile, inEntry, inspectEntryRequest, tmpbuf);
+        }
+        switch (instructions.getOutputPolicy()) {
+            case OUTPUT:
+                return true;
+            case SKIP:
+            case OUTPUT_BY_ENGINE:
+                return false;
+            default:
+                throw new RuntimeException(
+                        "Unsupported output policy: " + instructions.getOutputPolicy());
+        }
+    }
+
+    private static void provideJarEntry(
+            JarFile jarFile,
+            JarEntry jarEntry,
+            ApkSignerEngine.InspectJarEntryRequest request,
+            byte[] tmpbuf) throws IOException {
+        DataSink dataSink = request.getDataSink();
+        try (InputStream in = jarFile.getInputStream(jarEntry)) {
+            int chunkSize;
+            while ((chunkSize = in.read(tmpbuf)) > 0) {
+                dataSink.consume(tmpbuf, 0, chunkSize);
+            }
+            request.done();
         }
     }
 
@@ -756,6 +640,11 @@
         private final ASN1ObjectIdentifier type;
         private WholeFileSignerOutputStream signer;
 
+        // Files matching this pattern are not copied to the output.
+        private static final Pattern STRIP_PATTERN =
+                Pattern.compile("^(META-INF/((.*)[.](SF|RSA|DSA|EC)|com/android/otacert))|("
+                        + Pattern.quote(JarFile.MANIFEST_NAME) + ")$");
+
         public CMSSigner(JarFile inputJar, File publicKeyFile,
                          X509Certificate publicKey, PrivateKey privateKey, int hash,
                          long timestamp, OutputStream outputStream) {
@@ -789,7 +678,7 @@
                 signer = new WholeFileSignerOutputStream(out, outputStream);
                 JarOutputStream outputJar = new JarOutputStream(signer);
 
-                copyFiles(inputJar, STRIP_PATTERN, outputJar, timestamp, 0);
+                copyFiles(inputJar, STRIP_PATTERN, null, outputJar, timestamp, 0);
                 addOtacert(outputJar, publicKeyFile, timestamp);
 
                 signer.notifyClosing();
@@ -883,47 +772,6 @@
         temp.writeTo(outputStream);
     }
 
-    private static void signFile(Manifest manifest,
-                                 X509Certificate[] publicKey, PrivateKey[] privateKey, int[] hash,
-                                 long timestamp,
-                                 boolean additionallySignedUsingAnApkSignatureScheme,
-                                 JarOutputStream outputJar)
-        throws Exception {
-
-        // MANIFEST.MF
-        JarEntry je = new JarEntry(JarFile.MANIFEST_NAME);
-        je.setTime(timestamp);
-        outputJar.putNextEntry(je);
-        manifest.write(outputJar);
-
-        int numKeys = publicKey.length;
-        for (int k = 0; k < numKeys; ++k) {
-            // CERT.SF / CERT#.SF
-            je = new JarEntry(numKeys == 1 ? CERT_SF_NAME :
-                              (String.format(CERT_SF_MULTI_NAME, k)));
-            je.setTime(timestamp);
-            outputJar.putNextEntry(je);
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            writeSignatureFile(
-                    manifest,
-                    baos,
-                    hash[k],
-                    additionallySignedUsingAnApkSignatureScheme);
-            byte[] signedData = baos.toByteArray();
-            outputJar.write(signedData);
-
-            // CERT.{EC,RSA} / CERT#.{EC,RSA}
-            final String keyType = publicKey[k].getPublicKey().getAlgorithm();
-            je = new JarEntry(numKeys == 1 ?
-                              (String.format(CERT_SIG_NAME, keyType)) :
-                              (String.format(CERT_SIG_MULTI_NAME, k, keyType)));
-            je.setTime(timestamp);
-            outputJar.putNextEntry(je);
-            writeSignatureBlock(new CMSProcessableByteArray(signedData),
-                                publicKey[k], privateKey[k], hash[k], outputJar);
-        }
-    }
-
     /**
      * Tries to load a JSE Provider by class name. This is for custom PrivateKey
      * types that might be stored in PKCS#11-like storage.
@@ -976,81 +824,68 @@
         Security.insertProviderAt((Provider) o, 1);
     }
 
-    /**
-     * Converts the provided lists of private keys, their X.509 certificates, and digest algorithms
-     * into a list of APK Signature Scheme v2 {@code SignerConfig} instances.
-     */
-    public static List<ApkSignerV2.SignerConfig> createV2SignerConfigs(
-            PrivateKey[] privateKeys, X509Certificate[] certificates, String[] digestAlgorithms)
-                    throws InvalidKeyException {
+    private static List<DefaultApkSignerEngine.SignerConfig> createSignerConfigs(
+            PrivateKey[] privateKeys, X509Certificate[] certificates) {
         if (privateKeys.length != certificates.length) {
             throw new IllegalArgumentException(
                     "The number of private keys must match the number of certificates: "
                             + privateKeys.length + " vs" + certificates.length);
         }
-        List<ApkSignerV2.SignerConfig> result = new ArrayList<>(privateKeys.length);
+        List<DefaultApkSignerEngine.SignerConfig> signerConfigs = new ArrayList<>();
+        String signerNameFormat = (privateKeys.length == 1) ? "CERT" : "CERT%s";
         for (int i = 0; i < privateKeys.length; i++) {
-            PrivateKey privateKey = privateKeys[i];
-            X509Certificate certificate = certificates[i];
-            PublicKey publicKey = certificate.getPublicKey();
-            String keyAlgorithm = privateKey.getAlgorithm();
-            if (!keyAlgorithm.equalsIgnoreCase(publicKey.getAlgorithm())) {
-                throw new InvalidKeyException(
-                        "Key algorithm of private key #" + (i + 1) + " does not match key"
-                        + " algorithm of public key #" + (i + 1) + ": " + keyAlgorithm
-                        + " vs " + publicKey.getAlgorithm());
-            }
-            ApkSignerV2.SignerConfig signerConfig = new ApkSignerV2.SignerConfig();
-            signerConfig.privateKey = privateKey;
-            signerConfig.certificates = Collections.singletonList(certificate);
-            List<Integer> signatureAlgorithms = new ArrayList<>(digestAlgorithms.length);
-            for (String digestAlgorithm : digestAlgorithms) {
-                try {
-                    signatureAlgorithms.add(
-                            getV2SignatureAlgorithm(keyAlgorithm, digestAlgorithm));
-                } catch (IllegalArgumentException e) {
-                    throw new InvalidKeyException(
-                            "Unsupported key and digest algorithm combination for signer #"
-                                    + (i + 1),
-                            e);
-                }
-            }
-            signerConfig.signatureAlgorithms = signatureAlgorithms;
-            result.add(signerConfig);
+            String signerName = String.format(Locale.US, signerNameFormat, (i + 1));
+            DefaultApkSignerEngine.SignerConfig signerConfig =
+                    new DefaultApkSignerEngine.SignerConfig.Builder(
+                            signerName,
+                            privateKeys[i],
+                            Collections.singletonList(certificates[i]))
+                            .build();
+            signerConfigs.add(signerConfig);
         }
-        return result;
+        return signerConfigs;
     }
 
-    private static int getV2SignatureAlgorithm(String keyAlgorithm, String digestAlgorithm) {
-        if ("SHA-256".equalsIgnoreCase(digestAlgorithm)) {
-            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).
-                return ApkSignerV2.SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA256;
-            } else if ("EC".equalsIgnoreCase(keyAlgorithm)) {
-                return ApkSignerV2.SIGNATURE_ECDSA_WITH_SHA256;
-            } else if ("DSA".equalsIgnoreCase(keyAlgorithm)) {
-                return ApkSignerV2.SIGNATURE_DSA_WITH_SHA256;
-            } else {
-                throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm);
-            }
-        } else if ("SHA-512".equalsIgnoreCase(digestAlgorithm)) {
-            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).
-                return ApkSignerV2.SIGNATURE_RSA_PKCS1_V1_5_WITH_SHA512;
-            } else if ("EC".equalsIgnoreCase(keyAlgorithm)) {
-                return ApkSignerV2.SIGNATURE_ECDSA_WITH_SHA512;
-            } else if ("DSA".equalsIgnoreCase(keyAlgorithm)) {
-                throw new IllegalArgumentException("SHA-512 is not supported with DSA");
-            } else {
-                throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm);
-            }
-        } else {
-            throw new IllegalArgumentException("Unsupported digest algorithm: " + digestAlgorithm);
+    private static class ZipSections {
+        ByteBuffer beforeCentralDir;
+        ByteBuffer centralDir;
+        ByteBuffer eocd;
+    }
+
+    private static ZipSections findMainZipSections(ByteBuffer apk)
+            throws IOException, ZipFormatException {
+        apk.slice();
+        ApkUtils.ZipSections sections = ApkUtils.findZipSections(DataSources.asDataSource(apk));
+        long centralDirStartOffset = sections.getZipCentralDirectoryOffset();
+        long centralDirSizeBytes = sections.getZipCentralDirectorySizeBytes();
+        long centralDirEndOffset = centralDirStartOffset + centralDirSizeBytes;
+        long eocdStartOffset = sections.getZipEndOfCentralDirectoryOffset();
+        if (centralDirEndOffset != eocdStartOffset) {
+            throw new ZipFormatException(
+                    "ZIP Central Directory is not immediately followed by End of Central Directory"
+                            + ". CD end: " + centralDirEndOffset
+                            + ", EoCD start: " + eocdStartOffset);
         }
+        apk.position(0);
+        apk.limit((int) centralDirStartOffset);
+        ByteBuffer beforeCentralDir = apk.slice();
+
+        apk.position((int) centralDirStartOffset);
+        apk.limit((int) centralDirEndOffset);
+        ByteBuffer centralDir = apk.slice();
+
+        apk.position((int) eocdStartOffset);
+        apk.limit(apk.capacity());
+        ByteBuffer eocd = apk.slice();
+
+        apk.position(0);
+        apk.limit(apk.capacity());
+
+        ZipSections result = new ZipSections();
+        result.beforeCentralDir = beforeCentralDir;
+        result.centralDir = centralDir;
+        result.eocd = eocd;
+        return result;
     }
 
     private static void usage() {
@@ -1167,57 +1002,80 @@
                         timestamp,
                         outputFile);
             } else {
-                // Generate, in memory, an APK signed using standard JAR Signature Scheme.
-                ByteArrayOutputStream v1SignedApkBuf = new ByteArrayOutputStream();
-                JarOutputStream outputJar = new JarOutputStream(v1SignedApkBuf);
-                // Use maximum compression for compressed entries because the APK lives forever on
-                // the system partition.
-                outputJar.setLevel(9);
-                int v1DigestAlgorithmBitSet = 0;
-                int[] v1DigestAlgorithm = new int[numKeys];
-                for (int i = 0; i < numKeys; ++i) {
-                    v1DigestAlgorithm[i] = getV1DigestAlgorithmForApk(publicKey[i], minSdkVersion);
-                    v1DigestAlgorithmBitSet |= v1DigestAlgorithm[i];
-                }
-                Manifest manifest =
-                        addDigestsToManifest(inputJar, STRIP_PATTERN, v1DigestAlgorithmBitSet);
-                copyFiles(inputJar, STRIP_PATTERN, outputJar, timestamp, alignment);
-                signFile(
-                        manifest,
-                        publicKey, privateKey, v1DigestAlgorithm,
-                        timestamp, signUsingApkSignatureSchemeV2,
-                        outputJar);
-                outputJar.close();
-                ByteBuffer v1SignedApk = ByteBuffer.wrap(v1SignedApkBuf.toByteArray());
-                v1SignedApkBuf.reset();
+                try (ApkSignerEngine apkSigner =
+                        new DefaultApkSignerEngine.Builder(
+                                createSignerConfigs(privateKey, publicKey), minSdkVersion)
+                                .setV1SigningEnabled(true)
+                                .setV2SigningEnabled(signUsingApkSignatureSchemeV2)
+                                .setOtherSignersSignaturesPreserved(false)
+                                .build()) {
+                    // We don't preserve the input APK's APK Signing Block (which contains v2
+                    // signatures)
+                    apkSigner.inputApkSigningBlock(null);
 
-                ByteBuffer[] outputChunks;
-                if (signUsingApkSignatureSchemeV2) {
-                    // Additionally sign the APK using the APK Signature Scheme v2.
-                    ByteBuffer apkContents = v1SignedApk;
-                    List<ApkSignerV2.SignerConfig> signerConfigs =
-                            createV2SignerConfigs(
-                                    privateKey,
-                                    publicKey,
-                                    new String[] {APK_SIG_SCHEME_V2_DIGEST_ALGORITHM});
-                    outputChunks = ApkSignerV2.sign(apkContents, signerConfigs);
-                } else {
-                    // Output the JAR-signed APK as is.
-                    outputChunks = new ByteBuffer[] {v1SignedApk};
+                    // Build the output APK in memory, by copying input APK's ZIP entries across
+                    // and then signing the output APK.
+                    ByteArrayOutputStream v1SignedApkBuf = new ByteArrayOutputStream();
+                    JarOutputStream outputJar = new JarOutputStream(v1SignedApkBuf);
+                    // Use maximum compression for compressed entries because the APK lives forever
+                    // on the system partition.
+                    outputJar.setLevel(9);
+                    copyFiles(inputJar, null, apkSigner, outputJar, timestamp, alignment);
+                    ApkSignerEngine.OutputJarSignatureRequest addV1SignatureRequest =
+                            apkSigner.outputJarEntries();
+                    if (addV1SignatureRequest != null) {
+                        addV1Signature(apkSigner, addV1SignatureRequest, outputJar, timestamp);
+                        addV1SignatureRequest.done();
+                    }
+                    outputJar.close();
+                    ByteBuffer v1SignedApk = ByteBuffer.wrap(v1SignedApkBuf.toByteArray());
+                    v1SignedApkBuf.reset();
+                    ByteBuffer[] outputChunks = new ByteBuffer[] {v1SignedApk};
+
+                    ZipSections zipSections = findMainZipSections(v1SignedApk);
+                    ApkSignerEngine.OutputApkSigningBlockRequest addV2SignatureRequest =
+                            apkSigner.outputZipSections(
+                                    DataSources.asDataSource(zipSections.beforeCentralDir),
+                                    DataSources.asDataSource(zipSections.centralDir),
+                                    DataSources.asDataSource(zipSections.eocd));
+                    if (addV2SignatureRequest != null) {
+                        // Need to insert the returned APK Signing Block before ZIP Central
+                        // Directory.
+                        byte[] apkSigningBlock = addV2SignatureRequest.getApkSigningBlock();
+                        // Because the APK Signing Block is inserted before the Central Directory,
+                        // we need to adjust accordingly the offset of Central Directory inside the
+                        // ZIP End of Central Directory (EoCD) record.
+                        ByteBuffer modifiedEocd = ByteBuffer.allocate(zipSections.eocd.remaining());
+                        modifiedEocd.put(zipSections.eocd);
+                        modifiedEocd.flip();
+                        modifiedEocd.order(ByteOrder.LITTLE_ENDIAN);
+                        ApkUtils.setZipEocdCentralDirectoryOffset(
+                                modifiedEocd,
+                                zipSections.beforeCentralDir.remaining() + apkSigningBlock.length);
+                        outputChunks =
+                                new ByteBuffer[] {
+                                        zipSections.beforeCentralDir,
+                                        ByteBuffer.wrap(apkSigningBlock),
+                                        zipSections.centralDir,
+                                        modifiedEocd};
+                        addV2SignatureRequest.done();
+                    }
+
+                    // This assumes outputChunks are array-backed. To avoid this assumption, the
+                    // code could be rewritten to use FileChannel.
+                    for (ByteBuffer outputChunk : outputChunks) {
+                        outputFile.write(
+                                outputChunk.array(),
+                                outputChunk.arrayOffset() + outputChunk.position(),
+                                outputChunk.remaining());
+                        outputChunk.position(outputChunk.limit());
+                    }
+
+                    outputFile.close();
+                    outputFile = null;
+                    apkSigner.outputDone();
                 }
 
-                // This assumes outputChunks are array-backed. To avoid this assumption, the
-                // code could be rewritten to use FileChannel.
-                for (ByteBuffer outputChunk : outputChunks) {
-                    outputFile.write(
-                            outputChunk.array(),
-                            outputChunk.arrayOffset() + outputChunk.position(),
-                            outputChunk.remaining());
-                    outputChunk.position(outputChunk.limit());
-                }
-
-                outputFile.close();
-                outputFile = null;
                 return;
             }
         } catch (Exception e) {
diff --git a/tools/signapk/src/com/android/signapk/ZipUtils.java b/tools/signapk/src/com/android/signapk/ZipUtils.java
deleted file mode 100644
index 7575a77..0000000
--- a/tools/signapk/src/com/android/signapk/ZipUtils.java
+++ /dev/null
@@ -1,162 +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.signapk;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * 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() {}
-
-    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_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;
-
-    /**
-     * 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.
-     */
-    public 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 buffer contains a ZIP64 End of Central Directory
-     * Locator.
-     *
-     * <p>NOTE: Byte order of {@code zipContents} must be little-endian.
-     */
-    public static final boolean isZip64EndOfCentralDirectoryLocatorPresent(
-            ByteBuffer zipContents, int zipEndOfCentralDirectoryPosition) {
-        assertByteOrderLittleEndian(zipContents);
-
-        // ZIP64 End of Central Directory Locator immediately precedes the ZIP End of Central
-        // Directory Record.
-
-        int locatorPosition = zipEndOfCentralDirectoryPosition - ZIP64_EOCD_LOCATOR_SIZE;
-        if (locatorPosition < 0) {
-            return false;
-        }
-
-        return zipContents.getInt(locatorPosition) == ZIP64_EOCD_LOCATOR_SIG;
-    }
-
-    /**
-     * 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);
-    }
-
-    /**
-     * 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 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);
-    }
-
-    private static void assertByteOrderLittleEndian(ByteBuffer buffer) {
-        if (buffer.order() != ByteOrder.LITTLE_ENDIAN) {
-            throw new IllegalArgumentException("ByteBuffer byte order must be little endian");
-        }
-    }
-
-    private static int getUnsignedInt16(ByteBuffer buffer, int offset) {
-        return buffer.getShort(offset) & 0xffff;
-    }
-
-    private static long getUnsignedInt32(ByteBuffer buffer, int offset) {
-        return buffer.getInt(offset) & 0xffffffffL;
-    }
-
-    private 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(buffer.position() + offset, (int) value);
-    }
-}
