diff --git a/install/installcommand.cpp b/install/installcommand.cpp
index f421056..5e28472 100755
--- a/install/installcommand.cpp
+++ b/install/installcommand.cpp
@@ -121,12 +121,30 @@
         }
     }
     char value[PROPERTY_VALUE_MAX];
+    char propmodel[PROPERTY_VALUE_MAX];
+    char propname[PROPERTY_VALUE_MAX];
 
     property_get("ro.product.device", value, "");
+    property_get("ro.product.model", propmodel, "");
+    property_get("ro.product.name", propname, "");
     const std::string& pkg_device = metadata["pre-device"];
-    if (pkg_device != value || pkg_device.empty()) {
+
+    std::vector<std::string> assertResults = android::base::Split(pkg_device, ",");
+
+    bool deviceExists = false;
+
+    for(const std::string& deviceAssert : assertResults)
+    {
+        std::string assertName = android::base::Trim(deviceAssert);
+        if ((assertName == value || assertName == propmodel || assertName == propname ) && !assertName.empty()) {
+            deviceExists = true;
+            break;
+        }
+    }
+
+    if (!deviceExists) {
         printf("Package is for product %s but expected %s\n",
-             pkg_device.c_str(), value);
+            pkg_device.c_str(), value);
         return INSTALL_ERROR;
     }
 
diff --git a/installcommand.cpp b/installcommand.cpp
deleted file mode 100644
index 2a67e82..0000000
--- a/installcommand.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-#include <stdlib.h>
-#include <string>
-#include <vector>
-
-#ifdef AB_OTA_UPDATER
-#include <inttypes.h>
-#include <map>
-#include <android-base/parseint.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#endif
-#include <cutils/properties.h>
-
-#include "common.h"
-#include "installcommand.h"
-#include "zipwrap.hpp"
-#ifndef USE_MINZIP
-#include <ziparchive/zip_archive.h>
-#include <vintf/VintfObjectRecovery.h>
-#endif
-#ifdef USE_OLD_VERIFIER
-#include "verifier24/verifier.h"
-#else
-#include "verifier.h"
-#endif
-
-#ifdef AB_OTA_UPDATER
-
-static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt";
-static constexpr const char* AB_OTA_PAYLOAD = "payload.bin";
-static constexpr const char* METADATA_PATH = "META-INF/com/android/metadata";
-
-// This function parses and returns the build.version.incremental
-static int parse_build_number(std::string str) {
-    size_t pos = str.find("=");
-    if (pos != std::string::npos) {
-        std::string num_string = android::base::Trim(str.substr(pos+1));
-        int build_number;
-        if (android::base::ParseInt(num_string.c_str(), &build_number, 0)) {
-            return build_number;
-        }
-    }
-
-    printf("Failed to parse build number in %s.\n", str.c_str());
-    return -1;
-}
-
-bool read_metadata_from_package(ZipWrap* zip, std::string* meta_data) {
-    long size = zip->GetUncompressedSize(METADATA_PATH);
-    if (size <= 0)
-		return false;
-
-    meta_data->resize(size, '\0');
-    if (!zip->ExtractToBuffer(METADATA_PATH, reinterpret_cast<uint8_t*>(&(*meta_data)[0]))) {
-        printf("Failed to read metadata in update package.\n");
-        return false;
-    }
-    return true;
-}
-
-// Read the build.version.incremental of src/tgt from the metadata and log it to last_install.
-void read_source_target_build(ZipWrap* zip/*, std::vector<std::string>& log_buffer*/) {
-    std::string meta_data;
-    if (!read_metadata_from_package(zip, &meta_data)) {
-        return;
-    }
-    // Examples of the pre-build and post-build strings in metadata:
-    // pre-build-incremental=2943039
-    // post-build-incremental=2951741
-    std::vector<std::string> lines = android::base::Split(meta_data, "\n");
-    for (const std::string& line : lines) {
-        std::string str = android::base::Trim(line);
-        if (android::base::StartsWith(str, "pre-build-incremental")){
-            int source_build = parse_build_number(str);
-            if (source_build != -1) {
-                printf("source_build: %d\n", source_build);
-                /*log_buffer.push_back(android::base::StringPrintf("source_build: %d",
-                        source_build));*/
-            }
-        } else if (android::base::StartsWith(str, "post-build-incremental")) {
-            int target_build = parse_build_number(str);
-            if (target_build != -1) {
-                printf("target_build: %d\n", target_build);
-                /*log_buffer.push_back(android::base::StringPrintf("target_build: %d",
-                        target_build));*/
-            }
-        }
-    }
-}
-
-// Parses the metadata of the OTA package in |zip| and checks whether we are
-// allowed to accept this A/B package. Downgrading is not allowed unless
-// explicitly enabled in the package and only for incremental packages.
-static int check_newer_ab_build(ZipWrap* zip)
-{
-    std::string metadata_str;
-    if (!read_metadata_from_package(zip, &metadata_str)) {
-        return INSTALL_CORRUPT;
-    }
-    std::map<std::string, std::string> metadata;
-    for (const std::string& line : android::base::Split(metadata_str, "\n")) {
-        size_t eq = line.find('=');
-        if (eq != std::string::npos) {
-            metadata[line.substr(0, eq)] = line.substr(eq + 1);
-        }
-    }
-    char value[PROPERTY_VALUE_MAX];
-    char propmodel[PROPERTY_VALUE_MAX];
-    char propname[PROPERTY_VALUE_MAX];
-
-    property_get("ro.product.device", value, "");
-    property_get("ro.product.model", propmodel, "");
-    property_get("ro.product.name", propname, "");
-    const std::string& pkg_device = metadata["pre-device"];
-
-    std::vector<std::string> assertResults = android::base::Split(pkg_device, ",");
-
-    bool deviceExists = false;
-
-    for(const std::string& deviceAssert : assertResults)
-    {
-        std::string assertName = android::base::Trim(deviceAssert);
-        if ((assertName == value || assertName == propmodel || assertName == propname ) && !assertName.empty()) {
-            deviceExists = true;
-            break;
-        }
-    }
-
-    if (!deviceExists) {
-        printf("Package is for product %s but expected %s\n",
-            pkg_device.c_str(), value);
-        return INSTALL_ERROR;
-    }
-
-    // We allow the package to not have any serialno, but if it has a non-empty
-    // value it should match.
-    property_get("ro.serialno", value, "");
-    const std::string& pkg_serial_no = metadata["serialno"];
-    if (!pkg_serial_no.empty() && pkg_serial_no != value) {
-        printf("Package is for serial %s\n", pkg_serial_no.c_str());
-        return INSTALL_ERROR;
-    }
-
-    if (metadata["ota-type"] != "AB") {
-        printf("Package is not A/B\n");
-        return INSTALL_ERROR;
-    }
-
-    // Incremental updates should match the current build.
-    property_get("ro.build.version.incremental", value, "");
-    const std::string& pkg_pre_build = metadata["pre-build-incremental"];
-    if (!pkg_pre_build.empty() && pkg_pre_build != value) {
-        printf("Package is for source build %s but expected %s\n",
-             pkg_pre_build.c_str(), value);
-        return INSTALL_ERROR;
-    }
-    property_get("ro.build.fingerprint", value, "");
-    const std::string& pkg_pre_build_fingerprint = metadata["pre-build"];
-    if (!pkg_pre_build_fingerprint.empty() &&
-        pkg_pre_build_fingerprint != value) {
-        printf("Package is for source build %s but expected %s\n",
-             pkg_pre_build_fingerprint.c_str(), value);
-        return INSTALL_ERROR;
-    }
-
-    return 0;
-}
-
-int
-abupdate_binary_command(const char* path, ZipWrap* zip, int retry_count __unused,
-                      int status_fd, std::vector<std::string>* cmd)
-{
-    read_source_target_build(zip);
-    int ret = check_newer_ab_build(zip);
-    if (ret) {
-        return ret;
-    }
-
-    // For A/B updates we extract the payload properties to a buffer and obtain
-    // the RAW payload offset in the zip file.
-    if (!zip->EntryExists(AB_OTA_PAYLOAD_PROPERTIES)) {
-        printf("Can't find %s\n", AB_OTA_PAYLOAD_PROPERTIES);
-        return INSTALL_CORRUPT;
-    }
-    std::vector<unsigned char> payload_properties(
-            zip->GetUncompressedSize(AB_OTA_PAYLOAD_PROPERTIES));
-    if (!zip->ExtractToBuffer(AB_OTA_PAYLOAD_PROPERTIES, payload_properties.data())) {
-        printf("Can't extract %s\n", AB_OTA_PAYLOAD_PROPERTIES);
-        return INSTALL_CORRUPT;
-    }
-
-    if (!zip->EntryExists(AB_OTA_PAYLOAD)) {
-        printf("Can't find %s\n", AB_OTA_PAYLOAD);
-        return INSTALL_CORRUPT;
-    }
-    long payload_offset = zip->GetEntryOffset(AB_OTA_PAYLOAD);
-    *cmd = {
-        "/sbin/update_engine_sideload",
-        android::base::StringPrintf("--payload=file://%s", path),
-        android::base::StringPrintf("--offset=%ld", payload_offset),
-        "--headers=" + std::string(payload_properties.begin(),
-                                   payload_properties.end()),
-        android::base::StringPrintf("--status_fd=%d", status_fd),
-    };
-    return INSTALL_SUCCESS;
-}
-
-#else
-
-void read_source_target_build(ZipWrap* zip __unused /*, std::vector<std::string>& log_buffer*/) {return;}
-
-int
-abupdate_binary_command(__unused const char* path, __unused ZipWrap* zip, __unused int retry_count,
-                      __unused int status_fd, __unused std::vector<std::string>* cmd)
-{
-    printf("No support for AB OTA zips included\n");
-    return INSTALL_CORRUPT;
-}
-
-#endif
-
-int
-update_binary_command(const char* path, int retry_count,
-                      int status_fd, std::vector<std::string>* cmd)
-{
-    char charfd[16];
-    sprintf(charfd, "%i", status_fd);
-    cmd->push_back(TMP_UPDATER_BINARY_PATH);
-    cmd->push_back(EXPAND(RECOVERY_API_VERSION));
-    cmd->push_back(charfd);
-    cmd->push_back(path);
-    /**cmd = {
-        TMP_UPDATER_BINARY_PATH,
-        EXPAND(RECOVERY_API_VERSION),   // defined in Android.mk
-        charfd,
-        path,
-    };*/
-    if (retry_count > 0)
-        cmd->push_back("retry");
-    return 0;
-}
-
-#ifdef USE_MINZIP
-bool verify_package_compatibility(ZipWrap *package_zip) {
-  if (package_zip->EntryExists("compatibility.zip"))
-    printf("Cannot verify treble package compatibility, must build TWRP in Oreo tree or higher.\n");
-  return true;
-}
-#else
-// Verifes the compatibility info in a Treble-compatible package. Returns true directly if the
-// entry doesn't exist. Note that the compatibility info is packed in a zip file inside the OTA
-// package.
-bool verify_package_compatibility(ZipWrap *zw) {
-  ZipArchiveHandle package_zip = zw->GetZipArchiveHandle();
-  printf("Verifying package compatibility...\n");
-
-  static constexpr const char* COMPATIBILITY_ZIP_ENTRY = "compatibility.zip";
-  ZipString compatibility_entry_name(COMPATIBILITY_ZIP_ENTRY);
-  ZipEntry compatibility_entry;
-  if (FindEntry(package_zip, compatibility_entry_name, &compatibility_entry) != 0) {
-    printf("Package doesn't contain %s entry\n", COMPATIBILITY_ZIP_ENTRY);
-    return true;
-  }
-
-  std::string zip_content(compatibility_entry.uncompressed_length, '\0');
-  int32_t ret;
-  if ((ret = ExtractToMemory(package_zip, &compatibility_entry,
-                             reinterpret_cast<uint8_t*>(&zip_content[0]),
-                             compatibility_entry.uncompressed_length)) != 0) {
-    printf("Failed to read %s: %s\n", COMPATIBILITY_ZIP_ENTRY, ErrorCodeString(ret));
-    return false;
-  }
-
-  ZipArchiveHandle zip_handle;
-  ret = OpenArchiveFromMemory(static_cast<void*>(const_cast<char*>(zip_content.data())),
-                              zip_content.size(), COMPATIBILITY_ZIP_ENTRY, &zip_handle);
-  if (ret != 0) {
-    printf("Failed to OpenArchiveFromMemory: %s\n", ErrorCodeString(ret));
-    return false;
-  }
-
-  // Iterate all the entries inside COMPATIBILITY_ZIP_ENTRY and read the contents.
-  void* cookie;
-  ret = StartIteration(zip_handle, &cookie, nullptr, nullptr);
-  if (ret != 0) {
-    printf("Failed to start iterating zip entries: %s\n", ErrorCodeString(ret));
-    CloseArchive(zip_handle);
-    return false;
-  }
-  std::unique_ptr<void, decltype(&EndIteration)> guard(cookie, EndIteration);
-
-  std::vector<std::string> compatibility_info;
-  ZipEntry info_entry;
-  ZipString info_name;
-  while (Next(cookie, &info_entry, &info_name) == 0) {
-    std::string content(info_entry.uncompressed_length, '\0');
-    int32_t ret = ExtractToMemory(zip_handle, &info_entry, reinterpret_cast<uint8_t*>(&content[0]),
-                                  info_entry.uncompressed_length);
-    if (ret != 0) {
-      printf("Failed to read %s: %s\n", info_name.name, ErrorCodeString(ret));
-      CloseArchive(zip_handle);
-      return false;
-    }
-    compatibility_info.emplace_back(std::move(content));
-  }
-  CloseArchive(zip_handle);
-
-  // VintfObjectRecovery::CheckCompatibility returns zero on success. TODO THIS CAUSES A WEIRD COMPILE ERROR
-  std::string err;
-  int result = android::vintf::VintfObjectRecovery::CheckCompatibility(compatibility_info, &err);
-  if (result == 0) {
-    return true;
-  }
-
-  printf("Failed to verify package compatibility (result %i): %s\n", result, err.c_str());
-  return false;
-}
-#endif
->>>>>>> CHANGE (1913bf Make the twrp verify the pre-device among several props)
