diff --git a/core/main.mk b/core/main.mk
index c455320..6401efc 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -107,6 +107,8 @@
 include build/core/ninja.mk
 else # KATI
 
+include $(SOONG_MAKEVARS_MK)
+
 # Write the build number to a file so it can be read back in
 # without changing the command line every time.  Avoids rebuilds
 # when using ninja.
diff --git a/core/ninja.mk b/core/ninja.mk
index 9e78c46..5136f4e 100644
--- a/core/ninja.mk
+++ b/core/ninja.mk
@@ -159,7 +159,7 @@
 endif
 $(KATI_BUILD_NINJA): $(CKATI) $(MAKEPARALLEL) $(DUMMY_OUT_MKS) run_soong FORCE
 	@echo Running kati to generate build$(KATI_NINJA_SUFFIX).ninja...
-	+$(hide) $(KATI_MAKEPARALLEL) $(CKATI) --ninja --ninja_dir=$(OUT_DIR) --ninja_suffix=$(KATI_NINJA_SUFFIX) --regen --ignore_dirty=$(OUT_DIR)/% --no_ignore_dirty=$(SOONG_ANDROID_MK) --ignore_optional_include=$(OUT_DIR)/%.P --detect_android_echo $(KATI_FIND_EMULATOR) -f build/core/main.mk $(KATI_GOALS) --gen_all_targets BUILDING_WITH_NINJA=true SOONG_ANDROID_MK=$(SOONG_ANDROID_MK)
+	+$(hide) $(KATI_MAKEPARALLEL) $(CKATI) --ninja --ninja_dir=$(OUT_DIR) --ninja_suffix=$(KATI_NINJA_SUFFIX) --regen --ignore_dirty=$(OUT_DIR)/% --no_ignore_dirty=$(SOONG_ANDROID_MK) --no_ignore_dirty=$(SOONG_MAKEVARS_MK) --ignore_optional_include=$(OUT_DIR)/%.P --detect_android_echo $(KATI_FIND_EMULATOR) -f build/core/main.mk $(KATI_GOALS) --gen_all_targets BUILDING_WITH_NINJA=true SOONG_ANDROID_MK=$(SOONG_ANDROID_MK) SOONG_MAKEVARS_MK=$(SOONG_MAKEVARS_MK)
 
 .PHONY: FORCE
 FORCE:
diff --git a/core/soong.mk b/core/soong.mk
index 990a861..f1d765c 100644
--- a/core/soong.mk
+++ b/core/soong.mk
@@ -3,12 +3,13 @@
 SOONG_BOOTSTRAP := $(SOONG_OUT_DIR)/.soong.bootstrap
 SOONG_BUILD_NINJA := $(SOONG_OUT_DIR)/build.ninja
 SOONG_IN_MAKE := $(SOONG_OUT_DIR)/.soong.in_make
+SOONG_MAKEVARS_MK := $(SOONG_OUT_DIR)/make_vars-$(TARGET_PRODUCT).mk
 SOONG_VARIABLES := $(SOONG_OUT_DIR)/soong.variables
 
 # Only include the Soong-generated Android.mk if we're merging the
 # Soong-defined binaries with Kati-defined binaries.
 ifeq ($(USE_SOONG),true)
-SOONG_ANDROID_MK := $(SOONG_OUT_DIR)/Android.mk
+SOONG_ANDROID_MK := $(SOONG_OUT_DIR)/Android-$(TARGET_PRODUCT).mk
 endif
 
 # We need to rebootstrap soong if SOONG_OUT_DIR or the reverse path from
@@ -37,6 +38,8 @@
 	$(hide) mkdir -p $(dir $@)
 	$(hide) (\
 	echo '{'; \
+	echo '    "Make_suffix": "-$(TARGET_PRODUCT)",'; \
+	echo ''; \
 	echo '    "Platform_sdk_version": $(PLATFORM_SDK_VERSION),'; \
 	echo '    "Unbundled_build": $(if $(TARGET_BUILD_APPS),true,false),'; \
 	echo '    "Brillo": $(if $(BRILLO),true,false),'; \
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java b/tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java
new file mode 100644
index 0000000..30d4011
--- /dev/null
+++ b/tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java
@@ -0,0 +1,870 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.apksigner.core;
+
+import com.android.apksigner.core.internal.apk.v1.DigestAlgorithm;
+import com.android.apksigner.core.internal.apk.v1.V1SchemeSigner;
+import com.android.apksigner.core.internal.apk.v2.MessageDigestSink;
+import com.android.apksigner.core.internal.apk.v2.V2SchemeSigner;
+import com.android.apksigner.core.internal.util.ByteArrayOutputStreamSink;
+import com.android.apksigner.core.internal.util.Pair;
+import com.android.apksigner.core.util.DataSink;
+import com.android.apksigner.core.util.DataSource;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Default implementation of {@link ApkSignerEngine}.
+ *
+ * <p>Use {@link Builder} to obtain instances of this engine.
+ */
+public class DefaultApkSignerEngine implements ApkSignerEngine {
+
+    // IMPLEMENTATION NOTE: This engine generates a signed APK as follows:
+    // 1. The engine asks its client to output input JAR entries which are not part of JAR
+    //    signature.
+    // 2. If JAR signing (v1 signing) is enabled, the engine inspects the output JAR entries to
+    //    compute their digests, to be placed into output META-INF/MANIFEST.MF. It also inspects
+    //    the contents of input and output META-INF/MANIFEST.MF to borrow the main section of the
+    //    file. It does not care about individual (i.e., JAR entry-specific) sections. It then
+    //    emits the v1 signature (a set of JAR entries) and asks the client to output them.
+    // 3. If APK Signature Scheme v2 (v2 signing) is enabled, the engine emits an APK Signing Block
+    //    from outputZipSections() and asks its client to insert this block into the output.
+
+    private final boolean mV1SigningEnabled;
+    private final boolean mV2SigningEnabled;
+    private final boolean mOtherSignersSignaturesPreserved;
+    private final List<V1SchemeSigner.SignerConfig> mV1SignerConfigs;
+    private final DigestAlgorithm mV1ContentDigestAlgorithm;
+    private final List<V2SchemeSigner.SignerConfig> mV2SignerConfigs;
+
+    private boolean mClosed;
+
+    private boolean mV1SignaturePending;
+
+    /**
+     * Names of JAR entries which this engine is expected to output as part of v1 signing.
+     */
+    private final Set<String> mSignatureExpectedOutputJarEntryNames;
+
+    /** Requests for digests of output JAR entries. */
+    private final Map<String, GetJarEntryDataDigestRequest> mOutputJarEntryDigestRequests =
+            new HashMap<>();
+
+    /** Digests of output JAR entries. */
+    private final Map<String, byte[]> mOutputJarEntryDigests = new HashMap<>();
+
+    /** Data of JAR entries emitted by this engine as v1 signature. */
+    private final Map<String, byte[]> mEmittedSignatureJarEntryData = new HashMap<>();
+
+    /** Requests for data of output JAR entries which comprise the v1 signature. */
+    private final Map<String, GetJarEntryDataRequest> mOutputSignatureJarEntryDataRequests =
+            new HashMap<>();
+    /**
+     * Request to obtain the data of MANIFEST.MF or {@code null} if the request hasn't been issued.
+     */
+    private GetJarEntryDataRequest mInputJarManifestEntryDataRequest;
+
+    /**
+     * Request to output the emitted v1 signature or {@code null} if the request hasn't been issued.
+     */
+    private OutputJarSignatureRequestImpl mAddV1SignatureRequest;
+
+    private boolean mV2SignaturePending;
+
+    /**
+     * Request to output the emitted v2 signature or {@code null} if the request hasn't been issued.
+     */
+    private OutputApkSigningBlockRequestImpl mAddV2SignatureRequest;
+
+    private DefaultApkSignerEngine(
+            List<SignerConfig> signerConfigs,
+            int minSdkVersion,
+            boolean v1SigningEnabled,
+            boolean v2SigningEnabled,
+            boolean otherSignersSignaturesPreserved) throws InvalidKeyException {
+        if (signerConfigs.isEmpty()) {
+            throw new IllegalArgumentException("At least one signer config must be provided");
+        }
+        if (otherSignersSignaturesPreserved) {
+            throw new UnsupportedOperationException(
+                    "Preserving other signer's signatures is not yet implemented");
+        }
+
+        mV1SigningEnabled = v1SigningEnabled;
+        mV2SigningEnabled = v2SigningEnabled;
+        mOtherSignersSignaturesPreserved = otherSignersSignaturesPreserved;
+        mV1SignerConfigs =
+                (v1SigningEnabled)
+                        ? new ArrayList<>(signerConfigs.size()) : Collections.emptyList();
+        mV2SignerConfigs =
+                (v2SigningEnabled)
+                        ? new ArrayList<>(signerConfigs.size()) : Collections.emptyList();
+        mV1ContentDigestAlgorithm =
+                (v1SigningEnabled)
+                        ? V1SchemeSigner.getSuggestedContentDigestAlgorithm(minSdkVersion) : null;
+        for (SignerConfig signerConfig : signerConfigs) {
+            List<X509Certificate> certificates = signerConfig.getCertificates();
+            PublicKey publicKey = certificates.get(0).getPublicKey();
+
+            if (v1SigningEnabled) {
+                DigestAlgorithm v1SignatureDigestAlgorithm =
+                        V1SchemeSigner.getSuggestedSignatureDigestAlgorithm(
+                                publicKey, minSdkVersion);
+                V1SchemeSigner.SignerConfig v1SignerConfig = new V1SchemeSigner.SignerConfig();
+                v1SignerConfig.name = signerConfig.getName();
+                v1SignerConfig.privateKey = signerConfig.getPrivateKey();
+                v1SignerConfig.certificates = certificates;
+                v1SignerConfig.contentDigestAlgorithm = mV1ContentDigestAlgorithm;
+                v1SignerConfig.signatureDigestAlgorithm = v1SignatureDigestAlgorithm;
+                mV1SignerConfigs.add(v1SignerConfig);
+            }
+
+            if (v2SigningEnabled) {
+                V2SchemeSigner.SignerConfig v2SignerConfig = new V2SchemeSigner.SignerConfig();
+                v2SignerConfig.privateKey = signerConfig.getPrivateKey();
+                v2SignerConfig.certificates = certificates;
+                v2SignerConfig.signatureAlgorithms =
+                        V2SchemeSigner.getSuggestedSignatureAlgorithms(publicKey, minSdkVersion);
+                mV2SignerConfigs.add(v2SignerConfig);
+            }
+        }
+        mSignatureExpectedOutputJarEntryNames =
+                (v1SigningEnabled)
+                        ? V1SchemeSigner.getOutputEntryNames(mV1SignerConfigs)
+                        : Collections.emptySet();
+    }
+
+    @Override
+    public void inputApkSigningBlock(DataSource apkSigningBlock) {
+        checkNotClosed();
+
+        if ((apkSigningBlock == null) || (apkSigningBlock.size() == 0)) {
+            return;
+        }
+
+        if (mOtherSignersSignaturesPreserved) {
+            // TODO: Preserve blocks other than APK Signature Scheme v2 blocks of signers configured
+            // in this engine.
+            return;
+        }
+        // TODO: Preserve blocks other than APK Signature Scheme v2 blocks.
+    }
+
+    @Override
+    public InputJarEntryInstructions inputJarEntry(String entryName) {
+        checkNotClosed();
+
+        InputJarEntryInstructions.OutputPolicy outputPolicy =
+                getInputJarEntryOutputPolicy(entryName);
+        switch (outputPolicy) {
+            case SKIP:
+                return new InputJarEntryInstructions(InputJarEntryInstructions.OutputPolicy.SKIP);
+            case OUTPUT:
+                return new InputJarEntryInstructions(InputJarEntryInstructions.OutputPolicy.OUTPUT);
+            case OUTPUT_BY_ENGINE:
+                if (V1SchemeSigner.MANIFEST_ENTRY_NAME.equals(entryName)) {
+                    // We copy the main section of the JAR manifest from input to output. Thus, this
+                    // invalidates v1 signature and we need to see the entry's data.
+                    mInputJarManifestEntryDataRequest = new GetJarEntryDataRequest(entryName);
+                    return new InputJarEntryInstructions(
+                            InputJarEntryInstructions.OutputPolicy.OUTPUT_BY_ENGINE,
+                            mInputJarManifestEntryDataRequest);
+                }
+                return new InputJarEntryInstructions(
+                        InputJarEntryInstructions.OutputPolicy.OUTPUT_BY_ENGINE);
+            default:
+                throw new RuntimeException("Unsupported output policy: " + outputPolicy);
+        }
+    }
+
+    @Override
+    public InspectJarEntryRequest outputJarEntry(String entryName) {
+        checkNotClosed();
+        invalidateV2Signature();
+        if (!mV1SigningEnabled) {
+            // No need to inspect JAR entries when v1 signing is not enabled.
+            return null;
+        }
+        // v1 signing is enabled
+
+        if (V1SchemeSigner.isJarEntryDigestNeededInManifest(entryName)) {
+            // This entry is covered by v1 signature. We thus need to inspect the entry's data to
+            // compute its digest(s) for v1 signature.
+
+            // TODO: Handle the case where other signer's v1 signatures are present and need to be
+            // preserved. In that scenario we can't modify MANIFEST.MF and add/remove JAR entries
+            // covered by v1 signature.
+            invalidateV1Signature();
+            GetJarEntryDataDigestRequest dataDigestRequest =
+                    new GetJarEntryDataDigestRequest(
+                            entryName,
+                            V1SchemeSigner.getMessageDigestInstance(mV1ContentDigestAlgorithm));
+            mOutputJarEntryDigestRequests.put(entryName, dataDigestRequest);
+            mOutputJarEntryDigests.remove(entryName);
+            return dataDigestRequest;
+        }
+
+        if (mSignatureExpectedOutputJarEntryNames.contains(entryName)) {
+            // This entry is part of v1 signature generated by this engine. We need to check whether
+            // the entry's data is as output by the engine.
+            invalidateV1Signature();
+            GetJarEntryDataRequest dataRequest;
+            if (V1SchemeSigner.MANIFEST_ENTRY_NAME.equals(entryName)) {
+                dataRequest = new GetJarEntryDataRequest(entryName);
+                mInputJarManifestEntryDataRequest = dataRequest;
+            } else {
+                // If this entry is part of v1 signature which has been emitted by this engine,
+                // check whether the output entry's data matches what the engine emitted.
+                dataRequest =
+                        (mEmittedSignatureJarEntryData.containsKey(entryName))
+                                ? new GetJarEntryDataRequest(entryName) : null;
+            }
+
+            if (dataRequest != null) {
+                mOutputSignatureJarEntryDataRequests.put(entryName, dataRequest);
+            }
+            return dataRequest;
+        }
+
+        // This entry is not covered by v1 signature and isn't part of v1 signature.
+        return null;
+    }
+
+    @Override
+    public InputJarEntryInstructions.OutputPolicy inputJarEntryRemoved(String entryName) {
+        checkNotClosed();
+        return getInputJarEntryOutputPolicy(entryName);
+    }
+
+    @Override
+    public void outputJarEntryRemoved(String entryName) {
+        checkNotClosed();
+        invalidateV2Signature();
+        if (!mV1SigningEnabled) {
+            return;
+        }
+
+        if (V1SchemeSigner.isJarEntryDigestNeededInManifest(entryName)) {
+            // This entry is covered by v1 signature.
+            invalidateV1Signature();
+            mOutputJarEntryDigests.remove(entryName);
+            mOutputJarEntryDigestRequests.remove(entryName);
+            mOutputSignatureJarEntryDataRequests.remove(entryName);
+            return;
+        }
+
+        if (mSignatureExpectedOutputJarEntryNames.contains(entryName)) {
+            // This entry is part of the v1 signature generated by this engine.
+            invalidateV1Signature();
+            return;
+        }
+    }
+
+    @Override
+    public OutputJarSignatureRequest outputJarEntries()
+            throws InvalidKeyException, SignatureException {
+        checkNotClosed();
+
+        if (!mV1SignaturePending) {
+            return null;
+        }
+
+        if ((mInputJarManifestEntryDataRequest != null)
+                && (!mInputJarManifestEntryDataRequest.isDone())) {
+            throw new IllegalStateException(
+                    "Still waiting to inspect input APK's "
+                            + mInputJarManifestEntryDataRequest.getEntryName());
+        }
+
+        for (GetJarEntryDataDigestRequest digestRequest
+                : mOutputJarEntryDigestRequests.values()) {
+            String entryName = digestRequest.getEntryName();
+            if (!digestRequest.isDone()) {
+                throw new IllegalStateException(
+                        "Still waiting to inspect output APK's " + entryName);
+            }
+            mOutputJarEntryDigests.put(entryName, digestRequest.getDigest());
+        }
+        mOutputJarEntryDigestRequests.clear();
+
+        for (GetJarEntryDataRequest dataRequest : mOutputSignatureJarEntryDataRequests.values()) {
+            if (!dataRequest.isDone()) {
+                throw new IllegalStateException(
+                        "Still waiting to inspect output APK's " + dataRequest.getEntryName());
+            }
+        }
+
+        List<Integer> apkSigningSchemeIds =
+                (mV2SigningEnabled) ? Collections.singletonList(2) : Collections.emptyList();
+        byte[] inputJarManifest =
+                (mInputJarManifestEntryDataRequest != null)
+                    ? mInputJarManifestEntryDataRequest.getData() : null;
+
+        // Check whether the most recently used signature (if present) is still fine.
+        List<Pair<String, byte[]>> signatureZipEntries;
+        if ((mAddV1SignatureRequest == null) || (!mAddV1SignatureRequest.isDone())) {
+            try {
+                signatureZipEntries =
+                        V1SchemeSigner.sign(
+                                mV1SignerConfigs,
+                                mV1ContentDigestAlgorithm,
+                                mOutputJarEntryDigests,
+                                apkSigningSchemeIds,
+                                inputJarManifest);
+            } catch (CertificateEncodingException e) {
+                throw new SignatureException("Failed to generate v1 signature", e);
+            }
+        } else {
+            V1SchemeSigner.OutputManifestFile newManifest =
+                    V1SchemeSigner.generateManifestFile(
+                            mV1ContentDigestAlgorithm, mOutputJarEntryDigests, inputJarManifest);
+            byte[] emittedSignatureManifest =
+                    mEmittedSignatureJarEntryData.get(V1SchemeSigner.MANIFEST_ENTRY_NAME);
+            if (!Arrays.equals(newManifest.contents, emittedSignatureManifest)) {
+                // Emitted v1 signature is no longer valid.
+                try {
+                    signatureZipEntries =
+                            V1SchemeSigner.signManifest(
+                                    mV1SignerConfigs,
+                                    mV1ContentDigestAlgorithm,
+                                    apkSigningSchemeIds,
+                                    newManifest);
+                } catch (CertificateEncodingException e) {
+                    throw new SignatureException("Failed to generate v1 signature", e);
+                }
+            } else {
+                // Emitted v1 signature is still valid. Check whether the signature is there in the
+                // output.
+                signatureZipEntries = new ArrayList<>();
+                for (Map.Entry<String, byte[]> expectedOutputEntry
+                        : mEmittedSignatureJarEntryData.entrySet()) {
+                    String entryName = expectedOutputEntry.getKey();
+                    byte[] expectedData = expectedOutputEntry.getValue();
+                    GetJarEntryDataRequest actualDataRequest =
+                            mOutputSignatureJarEntryDataRequests.get(entryName);
+                    if (actualDataRequest == null) {
+                        // This signature entry hasn't been output.
+                        signatureZipEntries.add(Pair.of(entryName, expectedData));
+                        continue;
+                    }
+                    byte[] actualData = actualDataRequest.getData();
+                    if (!Arrays.equals(expectedData, actualData)) {
+                        signatureZipEntries.add(Pair.of(entryName, expectedData));
+                    }
+                }
+                if (signatureZipEntries.isEmpty()) {
+                    // v1 signature in the output is valid
+                    return null;
+                }
+                // v1 signature in the output is not valid.
+            }
+        }
+
+        if (signatureZipEntries.isEmpty()) {
+            // v1 signature in the output is valid
+            mV1SignaturePending = false;
+            return null;
+        }
+
+        List<OutputJarSignatureRequest.JarEntry> sigEntries =
+                new ArrayList<>(signatureZipEntries.size());
+        for (Pair<String, byte[]> entry : signatureZipEntries) {
+            String entryName = entry.getFirst();
+            byte[] entryData = entry.getSecond();
+            sigEntries.add(new OutputJarSignatureRequest.JarEntry(entryName, entryData));
+            mEmittedSignatureJarEntryData.put(entryName, entryData);
+        }
+        mAddV1SignatureRequest = new OutputJarSignatureRequestImpl(sigEntries);
+        return mAddV1SignatureRequest;
+    }
+
+    @Override
+    public OutputApkSigningBlockRequest outputZipSections(
+            DataSource zipEntries,
+            DataSource zipCentralDirectory,
+            DataSource zipEocd) throws IOException, InvalidKeyException, SignatureException {
+        checkNotClosed();
+        checkV1SigningDoneIfEnabled();
+        if (!mV2SigningEnabled) {
+            return null;
+        }
+        invalidateV2Signature();
+
+        byte[] apkSigningBlock =
+                V2SchemeSigner.generateApkSigningBlock(
+                        zipEntries, zipCentralDirectory, zipEocd, mV2SignerConfigs);
+
+        mAddV2SignatureRequest = new OutputApkSigningBlockRequestImpl(apkSigningBlock);
+        return mAddV2SignatureRequest;
+    }
+
+    @Override
+    public void outputDone() {
+        checkNotClosed();
+        checkV1SigningDoneIfEnabled();
+        checkV2SigningDoneIfEnabled();
+    }
+
+    @Override
+    public void close() {
+        mClosed = true;
+
+        mAddV1SignatureRequest = null;
+        mInputJarManifestEntryDataRequest = null;
+        mOutputJarEntryDigestRequests.clear();
+        mOutputJarEntryDigests.clear();
+        mEmittedSignatureJarEntryData.clear();
+        mOutputSignatureJarEntryDataRequests.clear();
+
+        mAddV2SignatureRequest = null;
+    }
+
+    private void invalidateV1Signature() {
+        if (mV1SigningEnabled) {
+            mV1SignaturePending = true;
+        }
+        invalidateV2Signature();
+    }
+
+    private void invalidateV2Signature() {
+        if (mV2SigningEnabled) {
+            mV2SignaturePending = true;
+            mAddV2SignatureRequest = null;
+        }
+    }
+
+    private void checkNotClosed() {
+        if (mClosed) {
+            throw new IllegalStateException("Engine closed");
+        }
+    }
+
+    private void checkV1SigningDoneIfEnabled() {
+        if (!mV1SignaturePending) {
+            return;
+        }
+
+        if (mAddV1SignatureRequest == null) {
+            throw new IllegalStateException(
+                    "v1 signature (JAR signature) not yet generated. Skipped outputJarEntries()?");
+        }
+        if (!mAddV1SignatureRequest.isDone()) {
+            throw new IllegalStateException(
+                    "v1 signature (JAR signature) addition requested by outputJarEntries() hasn't"
+                            + " been fulfilled");
+        }
+        for (Map.Entry<String, byte[]> expectedOutputEntry
+                : mEmittedSignatureJarEntryData.entrySet()) {
+            String entryName = expectedOutputEntry.getKey();
+            byte[] expectedData = expectedOutputEntry.getValue();
+            GetJarEntryDataRequest actualDataRequest =
+                    mOutputSignatureJarEntryDataRequests.get(entryName);
+            if (actualDataRequest == null) {
+                throw new IllegalStateException(
+                        "APK entry " + entryName + " not yet output despite this having been"
+                                + " requested");
+            } else if (!actualDataRequest.isDone()) {
+                throw new IllegalStateException(
+                        "Still waiting to inspect output APK's " + entryName);
+            }
+            byte[] actualData = actualDataRequest.getData();
+            if (!Arrays.equals(expectedData, actualData)) {
+                throw new IllegalStateException(
+                        "Output APK entry " + entryName + " data differs from what was requested");
+            }
+        }
+        mV1SignaturePending = false;
+    }
+
+    private void checkV2SigningDoneIfEnabled() {
+        if (!mV2SignaturePending) {
+            return;
+        }
+        if (mAddV2SignatureRequest == null) {
+            throw new IllegalStateException(
+                    "v2 signature (APK Signature Scheme v2 signature) not yet generated."
+                            + " Skipped outputZipSections()?");
+        }
+        if (!mAddV2SignatureRequest.isDone()) {
+            throw new IllegalStateException(
+                    "v2 signature (APK Signature Scheme v2 signature) addition requested by"
+                            + " outputZipSections() hasn't been fulfilled yet");
+        }
+        mAddV2SignatureRequest = null;
+        mV2SignaturePending = false;
+    }
+
+    /**
+     * Returns the output policy for the provided input JAR entry.
+     */
+    private InputJarEntryInstructions.OutputPolicy getInputJarEntryOutputPolicy(String entryName) {
+        if (mSignatureExpectedOutputJarEntryNames.contains(entryName)) {
+            return InputJarEntryInstructions.OutputPolicy.OUTPUT_BY_ENGINE;
+        }
+        if ((mOtherSignersSignaturesPreserved)
+                || (V1SchemeSigner.isJarEntryDigestNeededInManifest(entryName))) {
+            return InputJarEntryInstructions.OutputPolicy.OUTPUT;
+        }
+        return InputJarEntryInstructions.OutputPolicy.SKIP;
+    }
+
+    private static class OutputJarSignatureRequestImpl implements OutputJarSignatureRequest {
+        private final List<JarEntry> mAdditionalJarEntries;
+        private volatile boolean mDone;
+
+        private OutputJarSignatureRequestImpl(List<JarEntry> additionalZipEntries) {
+            mAdditionalJarEntries =
+                    Collections.unmodifiableList(new ArrayList<>(additionalZipEntries));
+        }
+
+        @Override
+        public List<JarEntry> getAdditionalJarEntries() {
+            return mAdditionalJarEntries;
+        }
+
+        @Override
+        public void done() {
+            mDone = true;
+        }
+
+        private boolean isDone() {
+            return mDone;
+        }
+    }
+
+    private static class OutputApkSigningBlockRequestImpl implements OutputApkSigningBlockRequest {
+        private final byte[] mApkSigningBlock;
+        private volatile boolean mDone;
+
+        private OutputApkSigningBlockRequestImpl(byte[] apkSigingBlock) {
+            mApkSigningBlock = apkSigingBlock.clone();
+        }
+
+        @Override
+        public byte[] getApkSigningBlock() {
+            return mApkSigningBlock.clone();
+        }
+
+        @Override
+        public void done() {
+            mDone = true;
+        }
+
+        private boolean isDone() {
+            return mDone;
+        }
+    }
+
+    /**
+     * JAR entry inspection request which obtain the entry's uncompressed data.
+     */
+    private static class GetJarEntryDataRequest implements InspectJarEntryRequest {
+        private final String mEntryName;
+        private final Object mLock = new Object();
+        private final ByteArrayOutputStreamSink mBuf = new ByteArrayOutputStreamSink();
+
+        private boolean mDone;
+
+        private GetJarEntryDataRequest(String entryName) {
+            mEntryName = entryName;
+        }
+
+        @Override
+        public String getEntryName() {
+            return mEntryName;
+        }
+
+        @Override
+        public DataSink getDataSink() {
+            synchronized (mLock) {
+                checkNotDone();
+                return mBuf;
+            }
+        }
+
+        @Override
+        public void done() {
+            synchronized (mLock) {
+                if (mDone) {
+                    return;
+                }
+                mDone = true;
+            }
+        }
+
+        private boolean isDone() {
+            synchronized (mLock) {
+                return mDone;
+            }
+        }
+
+        private void checkNotDone() throws IllegalStateException {
+            synchronized (mLock) {
+                if (mDone) {
+                    throw new IllegalStateException("Already done");
+                }
+            }
+        }
+
+        private byte[] getData() {
+            synchronized (mLock) {
+                if (!mDone) {
+                    throw new IllegalStateException("Not yet done");
+                }
+                return mBuf.getData();
+            }
+        }
+    }
+
+    /**
+     * JAR entry inspection request which obtains the digest of the entry's uncompressed data.
+     */
+    private static class GetJarEntryDataDigestRequest implements InspectJarEntryRequest {
+        private final String mEntryName;
+        private final MessageDigest mMessageDigest;
+        private final DataSink mDataSink;
+        private final Object mLock = new Object();
+
+        private boolean mDone;
+        private byte[] mDigest;
+
+        private GetJarEntryDataDigestRequest(String entryName, MessageDigest digest) {
+            mEntryName = entryName;
+            mMessageDigest = digest;
+            mDataSink = new MessageDigestSink(new MessageDigest[] {mMessageDigest});
+        }
+
+        @Override
+        public String getEntryName() {
+            return mEntryName;
+        }
+
+        @Override
+        public DataSink getDataSink() {
+            synchronized (mLock) {
+                checkNotDone();
+                return mDataSink;
+            }
+        }
+
+        @Override
+        public void done() {
+            synchronized (mLock) {
+                if (mDone) {
+                    return;
+                }
+                mDone = true;
+                mDigest = mMessageDigest.digest();
+            }
+        }
+
+        private boolean isDone() {
+            synchronized (mLock) {
+                return mDone;
+            }
+        }
+
+        private void checkNotDone() throws IllegalStateException {
+            synchronized (mLock) {
+                if (mDone) {
+                    throw new IllegalStateException("Already done");
+                }
+            }
+        }
+
+        private byte[] getDigest() {
+            synchronized (mLock) {
+                if (!mDone) {
+                    throw new IllegalStateException("Not yet done");
+                }
+                return mDigest.clone();
+            }
+        }
+    }
+
+    /**
+     * Configuration of a signer.
+     *
+     * <p>Use {@link Builder} to obtain configuration instances.
+     */
+    public static class SignerConfig {
+        private final String mName;
+        private final PrivateKey mPrivateKey;
+        private final List<X509Certificate> mCertificates;
+
+        private SignerConfig(
+                String name,
+                PrivateKey privateKey,
+                List<X509Certificate> certificates) {
+            mName = name;
+            mPrivateKey = privateKey;
+            mCertificates = Collections.unmodifiableList(new ArrayList<>(certificates));
+        }
+
+        /**
+         * Returns the name of this signer.
+         */
+        public String getName() {
+            return mName;
+        }
+
+        /**
+         * Returns the signing key of this signer.
+         */
+        public PrivateKey getPrivateKey() {
+            return mPrivateKey;
+        }
+
+        /**
+         * Returns the certificate(s) of this signer. The first certificate's public key corresponds
+         * to this signer's private key.
+         */
+        public List<X509Certificate> getCertificates() {
+            return mCertificates;
+        }
+
+        /**
+         * Builder of {@link SignerConfig} instances.
+         */
+        public static class Builder {
+            private final String mName;
+            private final PrivateKey mPrivateKey;
+            private final List<X509Certificate> mCertificates;
+
+            /**
+             * Constructs a new {@code Builder}.
+             *
+             * @param name signer's name. The name is reflected in the name of files comprising the
+             *        JAR signature of the APK.
+             * @param privateKey signing key
+             * @param certificates list of one or more X.509 certificates. The subject public key of
+             *        the first certificate must correspond to the {@code privateKey}.
+             */
+            public Builder(
+                    String name,
+                    PrivateKey privateKey,
+                    List<X509Certificate> certificates) {
+                mName = name;
+                mPrivateKey = privateKey;
+                mCertificates = new ArrayList<>(certificates);
+            }
+
+            /**
+             * Returns a new {@code SignerConfig} instance configured based on the configuration of
+             * this builder.
+             */
+            public SignerConfig build() {
+                return new SignerConfig(
+                        mName,
+                        mPrivateKey,
+                        mCertificates);
+            }
+        }
+    }
+
+    /**
+     * Builder of {@link DefaultApkSignerEngine} instances.
+     */
+    public static class Builder {
+        private final List<SignerConfig> mSignerConfigs;
+        private final int mMinSdkVersion;
+
+        private boolean mV1SigningEnabled = true;
+        private boolean mV2SigningEnabled = true;
+        private boolean mOtherSignersSignaturesPreserved;
+
+        /**
+         * Constructs a new {@code Builder}.
+         *
+         * @param signerConfigs information about signers with which the APK will be signed. At
+         *        least one signer configuration must be provided.
+         * @param minSdkVersion API Level of the oldest Android platform on which the APK is
+         *        supposed to be installed. See {@code minSdkVersion} attribute in the APK's
+         *        {@code AndroidManifest.xml}. The higher the version, the stronger signing features
+         *        will be enabled.
+         */
+        public Builder(
+                List<SignerConfig> signerConfigs,
+                int minSdkVersion) {
+            if (signerConfigs.isEmpty()) {
+                throw new IllegalArgumentException("At least one signer config must be provided");
+            }
+            mSignerConfigs = new ArrayList<>(signerConfigs);
+            mMinSdkVersion = minSdkVersion;
+        }
+
+        /**
+         * Returns a new {@code DefaultApkSignerEngine} instance configured based on the
+         * configuration of this builder.
+         */
+        public DefaultApkSignerEngine build() throws InvalidKeyException {
+            return new DefaultApkSignerEngine(
+                    mSignerConfigs,
+                    mMinSdkVersion,
+                    mV1SigningEnabled,
+                    mV2SigningEnabled,
+                    mOtherSignersSignaturesPreserved);
+        }
+
+        /**
+         * Sets whether the APK should be signed using JAR signing (aka v1 signature scheme).
+         *
+         * <p>By default, the APK will be signed using this scheme.
+         */
+        public Builder setV1SigningEnabled(boolean enabled) {
+            mV1SigningEnabled = enabled;
+            return this;
+        }
+
+        /**
+         * Sets whether the APK should be signed using APK Signature Scheme v2 (aka v2 signature
+         * scheme).
+         *
+         * <p>By default, the APK will be signed using this scheme.
+         */
+        public Builder setV2SigningEnabled(boolean enabled) {
+            mV2SigningEnabled = enabled;
+            return this;
+        }
+
+        /**
+         * Sets whether signatures produced by signers other than the ones configured in this engine
+         * should be copied from the input APK to the output APK.
+         *
+         * <p>By default, signatures of other signers are omitted from the output APK.
+         */
+        public Builder setOtherSignersSignaturesPreserved(boolean preserved) {
+            mOtherSignersSignaturesPreserved = preserved;
+            return this;
+        }
+    }
+}
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/MessageDigestSink.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/MessageDigestSink.java
index 182b4ed..9ef04bf 100644
--- a/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/MessageDigestSink.java
+++ b/tools/apksigner/core/src/com/android/apksigner/core/internal/apk/v2/MessageDigestSink.java
@@ -24,11 +24,11 @@
  * Data sink which feeds all received data into the associated {@link MessageDigest} instances. Each
  * {@code MessageDigest} instance receives the same data.
  */
-class MessageDigestSink implements DataSink {
+public class MessageDigestSink implements DataSink {
 
     private final MessageDigest[] mMessageDigests;
 
-    MessageDigestSink(MessageDigest[] digests) {
+    public MessageDigestSink(MessageDigest[] digests) {
         mMessageDigests = digests;
     }
 
diff --git a/tools/apksigner/core/src/com/android/apksigner/core/internal/util/ByteArrayOutputStreamSink.java b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/ByteArrayOutputStreamSink.java
new file mode 100644
index 0000000..ca79df7
--- /dev/null
+++ b/tools/apksigner/core/src/com/android/apksigner/core/internal/util/ByteArrayOutputStreamSink.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.apksigner.core.internal.util;
+
+import com.android.apksigner.core.util.DataSink;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+
+/**
+ * Data sink which stores all input data into an internal {@link ByteArrayOutputStream}, thus
+ * accepting an arbitrary amount of data.
+ */
+public class ByteArrayOutputStreamSink implements DataSink {
+
+    private final ByteArrayOutputStream mBuf = new ByteArrayOutputStream();
+
+    @Override
+    public void consume(byte[] buf, int offset, int length) {
+        mBuf.write(buf, offset, length);
+    }
+
+    @Override
+    public void consume(ByteBuffer buf) {
+        if (!buf.hasRemaining()) {
+            return;
+        }
+
+        if (buf.hasArray()) {
+            mBuf.write(
+                    buf.array(),
+                    buf.arrayOffset() + buf.position(),
+                    buf.remaining());
+            buf.position(buf.limit());
+        } else {
+            byte[] tmp = new byte[buf.remaining()];
+            buf.get(tmp);
+            mBuf.write(tmp, 0, tmp.length);
+        }
+    }
+
+    /**
+     * Returns the data received so far.
+     */
+    public byte[] getData() {
+        return mBuf.toByteArray();
+    }
+}
