diff --git a/core/Makefile b/core/Makefile
index 6fb2458..83a008c 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1678,11 +1678,12 @@
 
 ifeq ($(AB_OTA_UPDATER),true)
 # Build zlib fingerprint if using the AB Updater.
-$(BUILT_TARGET_FILES_PACKAGE): $(TARGET_OUT_COMMON_GEN)/zlib_fingerprint
+updater_dep := $(TARGET_OUT_COMMON_GEN)/zlib_fingerprint
 else
 # Build OTA tools if not using the AB Updater.
-$(BUILT_TARGET_FILES_PACKAGE): $(built_ota_tools)
+updater_dep := $(built_ota_tools)
 endif
+$(BUILT_TARGET_FILES_PACKAGE): $(updater_dep)
 
 # If we are using recovery as boot, output recovery files to BOOT/.
 ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
@@ -1705,6 +1706,7 @@
 		$(SELINUX_FC) \
 		$(APKCERTS_FILE) \
 		$(HOST_OUT_EXECUTABLES)/fs_config \
+		build/tools/releasetools/add_img_to_target_files \
 		| $(ACP)
 	@echo "Package target files: $@"
 	$(hide) rm -rf $@ $(zip_root)
@@ -1873,6 +1875,17 @@
 	@# Include the build type in META/misc_info.txt so the server can easily differentiate production builds.
 	$(hide) echo "build_type=$(TARGET_BUILD_VARIANT)" >> $(zip_root)/META/misc_info.txt
 	$(hide) echo "ab_update=true" >> $(zip_root)/META/misc_info.txt
+ifdef BRILLO_VENDOR_PARTITIONS
+	$(hide) mkdir -p $(zip_root)/VENDOR_IMAGES
+	$(hide) for f in $(BRILLO_VENDOR_PARTITIONS); do \
+	  pair1="$$(echo $$f | awk -F':' '{print $$1}')"; \
+	  pair2="$$(echo $$f | awk -F':' '{print $$2}')"; \
+	  src=$${pair1}/$${pair2}; \
+	  dest=$(zip_root)/VENDOR_IMAGES/$${pair2}; \
+	  mkdir -p $$(dirname "$${dest}"); \
+	  $(ACP) $${src} $${dest}; \
+	done;
+endif
 ifdef OSRELEASED_DIRECTORY
 	$(hide) $(ACP) $(TARGET_OUT_ETC)/$(OSRELEASED_DIRECTORY)/product_id $(zip_root)/META/product_id.txt
 	$(hide) $(ACP) $(TARGET_OUT_ETC)/$(OSRELEASED_DIRECTORY)/product_version $(zip_root)/META/product_version.txt
@@ -1923,7 +1936,8 @@
 
 $(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)
 
-$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE)
+$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) \
+		build/tools/releasetools/ota_from_target_files
 	@echo "Package OTA: $@"
 	$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
 	   ./build/tools/releasetools/ota_from_target_files -v \
@@ -1949,7 +1963,8 @@
 
 INTERNAL_UPDATE_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip
 
-$(INTERNAL_UPDATE_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE)
+$(INTERNAL_UPDATE_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) \
+		build/tools/releasetools/img_from_target_files
 	@echo "Package: $@"
 	$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
 	   ./build/tools/releasetools/img_from_target_files -v \
@@ -1972,7 +1987,11 @@
 SYMBOLS_ZIP := $(PRODUCT_OUT)/$(name).zip
 # For apps_only build we'll establish the dependency later in build/core/main.mk.
 ifndef TARGET_BUILD_APPS
-$(SYMBOLS_ZIP): $(INSTALLED_SYSTEMIMAGE) $(INSTALLED_BOOTIMAGE_TARGET)
+$(SYMBOLS_ZIP): $(INSTALLED_SYSTEMIMAGE) \
+		$(INSTALLED_BOOTIMAGE_TARGET) \
+		$(INSTALLED_USERDATAIMAGE_TARGET) \
+		$(INSTALLED_VENDORIMAGE_TARGET) \
+		$(updater_dep)
 endif
 $(SYMBOLS_ZIP):
 	@echo "Package symbols: $@"
diff --git a/core/clang/tidy.mk b/core/clang/tidy.mk
index e61b878..019e6f0 100644
--- a/core/clang/tidy.mk
+++ b/core/clang/tidy.mk
@@ -15,22 +15,25 @@
 #
 
 # Most Android source files are not clang-tidy clean yet.
-# Global tidy checks include only google* minus google-readability*.
+# Global tidy checks include only google* and misc-macro-parentheses,
+# but not google-readability*.
 DEFAULT_GLOBAL_TIDY_CHECKS := \
-  -*,google*,-google-readability*
+  -*,google*,-google-readability*,misc-macro-parentheses
 
-# Disable google style rules usually not followed by external projects.
+# Disable style rules usually not followed by external projects.
 # Every word in DEFAULT_LOCAL_TIDY_CHECKS list has the following format:
 #   <local_path_prefix>:,<tidy-check-pattern>
 # The tidy-check-patterns of all matching local_path_prefixes will be used.
 # For example, external/google* projects will have:
 #   ,-google-build-using-namespace,-google-explicit-constructor
-#   ,-google-runtime-int,google-runtime-int
-# where google-runtime-int is enabled at the end.
+#   ,-google-runtime-int,-misc-macro-parentheses,
+#   ,google-runtime-int,misc-macro-parentheses
+# where google-runtime-int and misc-macro-parentheses are enabled at the end.
 DEFAULT_LOCAL_TIDY_CHECKS := \
   external/:,-google-build-using-namespace \
   external/:,-google-explicit-constructor,-google-runtime-int \
-  external/google:,google-runtime-int \
+  external/:,-misc-macro-parentheses \
+  external/google:,google-runtime-int,misc-macro-parentheses \
   external/webrtc/:,google-runtime-int \
   hardware/qcom:,-google-build-using-namespace \
   hardware/qcom:,-google-explicit-constructor,-google-runtime-int \
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();
+    }
+}
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index f98a281..9e44263 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -395,8 +395,9 @@
     banner("partition-table")
     AddPartitionTable(output_zip)
 
-  # For devices using A/B update, copy over images from RADIO/ to IMAGES/ and
-  # make sure we have all the needed images ready under IMAGES/.
+  # For devices using A/B update, copy over images from RADIO/ and/or
+  # VENDOR_IMAGES/ to IMAGES/ and make sure we have all the needed
+  # images ready under IMAGES/. All images should have '.img' as extension.
   ab_partitions = os.path.join(OPTIONS.input_tmp, "META", "ab_partitions.txt")
   if os.path.exists(ab_partitions):
     with open(ab_partitions, 'r') as f:
@@ -404,9 +405,17 @@
     for line in lines:
       img_name = line.strip() + ".img"
       img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
+      img_vendor_dir = os.path.join(
+        OPTIONS.input_tmp, "VENDOR_IMAGES")
       if os.path.exists(img_radio_path):
         common.ZipWrite(output_zip, img_radio_path,
                         os.path.join("IMAGES", img_name))
+      else:
+        for root, _, files in os.walk(img_vendor_dir):
+          if img_name in files:
+            common.ZipWrite(output_zip, os.path.join(root, img_name),
+              os.path.join("IMAGES", img_name))
+            break
 
       # Zip spec says: All slashes MUST be forward slashes.
       img_path = 'IMAGES/' + img_name
diff --git a/tools/rgb2565/to565.c b/tools/rgb2565/to565.c
index abf9cdb..94d62ef 100644
--- a/tools/rgb2565/to565.c
+++ b/tools/rgb2565/to565.c
@@ -65,11 +65,11 @@
         out = to565(rb, gb, bb);
         write(1, &out, 2);
 
-#define apply_error(ch) {                                               \
-            next_error[(i-1)*3+ch] += e * 3 / 16;                       \
-            next_error[(i)*3+ch] += e * 5 / 16;                         \
-            next_error[(i+1)*3+ch] += e * 1 / 16;                       \
-            error[(i+1)*3+ch] += e - ((e*1/16) + (e*3/16) + (e*5/16));  \
+#define apply_error(ch) {                                                \
+            next_error[(i-1)*3+(ch)] += e * 3 / 16;                      \
+            next_error[(i)*3+(ch)] += e * 5 / 16;                        \
+            next_error[(i+1)*3+(ch)] += e * 1 / 16;                      \
+            error[(i+1)*3+(ch)] += e - ((e*1/16) + (e*3/16) + (e*5/16)); \
         }
 
         e = r - from565_r(out);
diff --git a/tools/warn.py b/tools/warn.py
index d4b2f57..135cd51 100755
--- a/tools/warn.py
+++ b/tools/warn.py
@@ -1,12 +1,20 @@
 #!/usr/bin/env python
 # This file uses the following encoding: utf-8
 
+import argparse
 import sys
 import re
 
-if len(sys.argv) == 1:
-    print 'usage: ' + sys.argv[0] + ' <build.log>'
-    sys.exit()
+parser = argparse.ArgumentParser(description='Convert a build log into HTML')
+parser.add_argument('--url',
+                    help='Root URL of an Android source code tree prefixed '
+                    'before files in warnings')
+parser.add_argument('--separator',
+                    help='Separator between the end of a URL and the line '
+                    'number argument. e.g. #')
+parser.add_argument(dest='buildlog', metavar='build.log',
+                    help='Path to build.log file')
+args = parser.parse_args()
 
 # if you add another level, don't forget to give it a color below
 class severity:
@@ -781,7 +789,7 @@
     output('<tr bgcolor="' + row_colors[cur_row_color] + '"><td colspan="2">',)
     cur_row_color = 1 - cur_row_color
     output(text,)
-    output('</td></tr>')
+    output('</td></tr>\n')
 
 def begintable(text, backgroundcolor, extraanchor):
     global anchor
@@ -879,6 +887,19 @@
     if tablestarted:
         endtable()
 
+def warningwithurl(line):
+    if not args.url:
+        return line
+    m = re.search( r'^([^ :]+):(\d+):(.+)', line, re.M|re.I)
+    if not m:
+        return line
+    filepath = m.group(1)
+    linenumber = m.group(2)
+    warning = m.group(3)
+    if args.separator:
+        return '<a href="' + args.url + '/' + filepath + args.separator + linenumber + '">' + filepath + ':' + linenumber + '</a>:' + warning
+    else:
+        return '<a href="' + args.url + '/' + filepath + '">' + filepath + '</a>:' + linenumber + ':' + warning
 
 # dump a category, provided it is not marked as 'SKIP' and has more than 0 occurrences
 def dumpcategory(cat):
@@ -888,7 +909,7 @@
             header[1:1] = [' (related option: ' + cat['option'] +')']
         begintable(header, colorforseverity(cat['severity']), cat['anchor'])
         for i in cat['members']:
-            tablerow(i)
+            tablerow(warningwithurl(i))
         endtable()
 
 
@@ -918,7 +939,7 @@
         for pat in i['patterns']:
             i['compiledpatterns'].append(re.compile(pat))
 
-infile = open(sys.argv[1], 'r')
+infile = open(args.buildlog, 'r')
 warnings = []
 
 platformversion = 'unknown'
