diff --git a/payload_consumer/bzip_extent_writer.cc b/payload_consumer/bzip_extent_writer.cc
new file mode 100644
index 0000000..0fcc8ba
--- /dev/null
+++ b/payload_consumer/bzip_extent_writer.cc
@@ -0,0 +1,91 @@
+//
+// Copyright (C) 2009 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 "update_engine/payload_consumer/bzip_extent_writer.h"
+
+using std::vector;
+
+namespace chromeos_update_engine {
+
+namespace {
+const brillo::Blob::size_type kOutputBufferLength = 16 * 1024;
+}
+
+bool BzipExtentWriter::Init(FileDescriptorPtr fd,
+                            const vector<Extent>& extents,
+                            uint32_t block_size) {
+  // Init bzip2 stream
+  int rc = BZ2_bzDecompressInit(&stream_,
+                                0,   // verbosity. (0 == silent)
+                                0);  // 0 = faster algo, more memory
+
+  TEST_AND_RETURN_FALSE(rc == BZ_OK);
+
+  return next_->Init(fd, extents, block_size);
+}
+
+bool BzipExtentWriter::Write(const void* bytes, size_t count) {
+  brillo::Blob output_buffer(kOutputBufferLength);
+
+  // Copy the input data into |input_buffer_| only if |input_buffer_| already
+  // contains unconsumed data. Otherwise, process the data directly from the
+  // source.
+  const uint8_t* input = reinterpret_cast<const uint8_t*>(bytes);
+  const uint8_t* input_end = input + count;
+  if (!input_buffer_.empty()) {
+    input_buffer_.insert(input_buffer_.end(), input, input_end);
+    input = input_buffer_.data();
+    input_end = input + input_buffer_.size();
+  }
+  stream_.next_in = reinterpret_cast<char*>(const_cast<uint8_t*>(input));
+  stream_.avail_in = input_end - input;
+
+  for (;;) {
+    stream_.next_out = reinterpret_cast<char*>(output_buffer.data());
+    stream_.avail_out = output_buffer.size();
+
+    int rc = BZ2_bzDecompress(&stream_);
+    TEST_AND_RETURN_FALSE(rc == BZ_OK || rc == BZ_STREAM_END);
+
+    if (stream_.avail_out == output_buffer.size())
+      break;  // got no new bytes
+
+    TEST_AND_RETURN_FALSE(
+        next_->Write(output_buffer.data(),
+                     output_buffer.size() - stream_.avail_out));
+
+    if (rc == BZ_STREAM_END)
+      CHECK_EQ(stream_.avail_in, 0u);
+    if (stream_.avail_in == 0)
+      break;  // no more input to process
+  }
+
+  // Store unconsumed data (if any) in |input_buffer_|.
+  if (stream_.avail_in || !input_buffer_.empty()) {
+    brillo::Blob new_input_buffer(input_end - stream_.avail_in, input_end);
+    new_input_buffer.swap(input_buffer_);
+  }
+
+  return true;
+}
+
+bool BzipExtentWriter::EndImpl() {
+  TEST_AND_RETURN_FALSE(input_buffer_.empty());
+  TEST_AND_RETURN_FALSE(BZ2_bzDecompressEnd(&stream_) == BZ_OK);
+  return next_->End();
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/bzip_extent_writer.h b/payload_consumer/bzip_extent_writer.h
new file mode 100644
index 0000000..0ad542e
--- /dev/null
+++ b/payload_consumer/bzip_extent_writer.h
@@ -0,0 +1,57 @@
+//
+// Copyright (C) 2009 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.
+//
+
+#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_BZIP_EXTENT_WRITER_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_BZIP_EXTENT_WRITER_H_
+
+#include <bzlib.h>
+#include <memory>
+#include <vector>
+
+#include <brillo/secure_blob.h>
+
+#include "update_engine/common/utils.h"
+#include "update_engine/payload_consumer/extent_writer.h"
+
+// BzipExtentWriter is a concrete ExtentWriter subclass that bzip-decompresses
+// what it's given in Write. It passes the decompressed data to an underlying
+// ExtentWriter.
+
+namespace chromeos_update_engine {
+
+class BzipExtentWriter : public ExtentWriter {
+ public:
+  explicit BzipExtentWriter(std::unique_ptr<ExtentWriter> next)
+      : next_(std::move(next)) {
+    memset(&stream_, 0, sizeof(stream_));
+  }
+  ~BzipExtentWriter() override = default;
+
+  bool Init(FileDescriptorPtr fd,
+            const std::vector<Extent>& extents,
+            uint32_t block_size) override;
+  bool Write(const void* bytes, size_t count) override;
+  bool EndImpl() override;
+
+ private:
+  std::unique_ptr<ExtentWriter> next_;  // The underlying ExtentWriter.
+  bz_stream stream_;  // the libbz2 stream
+  brillo::Blob input_buffer_;
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_BZIP_EXTENT_WRITER_H_
diff --git a/payload_consumer/bzip_extent_writer_unittest.cc b/payload_consumer/bzip_extent_writer_unittest.cc
new file mode 100644
index 0000000..a52a286
--- /dev/null
+++ b/payload_consumer/bzip_extent_writer_unittest.cc
@@ -0,0 +1,145 @@
+//
+// Copyright (C) 2009 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 "update_engine/payload_consumer/bzip_extent_writer.h"
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include <brillo/make_unique_ptr.h>
+#include <gtest/gtest.h>
+
+#include "update_engine/common/test_utils.h"
+#include "update_engine/common/utils.h"
+
+using std::min;
+using std::string;
+using std::vector;
+
+namespace chromeos_update_engine {
+
+namespace {
+const char kPathTemplate[] = "./BzipExtentWriterTest-file.XXXXXX";
+const uint32_t kBlockSize = 4096;
+}
+
+class BzipExtentWriterTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    memcpy(path_, kPathTemplate, sizeof(kPathTemplate));
+    fd_.reset(new EintrSafeFileDescriptor);
+    int fd = mkstemp(path_);
+    ASSERT_TRUE(fd_->Open(path_, O_RDWR, 0600));
+    close(fd);
+  }
+  void TearDown() override {
+    fd_->Close();
+    unlink(path_);
+  }
+  void WriteAlignedExtents(size_t chunk_size, size_t first_chunk_size);
+  void TestZeroPad(bool aligned_size);
+
+  FileDescriptorPtr fd_;
+  char path_[sizeof(kPathTemplate)];
+};
+
+TEST_F(BzipExtentWriterTest, SimpleTest) {
+  vector<Extent> extents;
+  Extent extent;
+  extent.set_start_block(0);
+  extent.set_num_blocks(1);
+  extents.push_back(extent);
+
+  // 'echo test | bzip2 | hexdump' yields:
+  static const char test_uncompressed[] = "test\n";
+  static const uint8_t test[] = {
+    0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xcc, 0xc3,
+    0x71, 0xd4, 0x00, 0x00, 0x02, 0x41, 0x80, 0x00, 0x10, 0x02, 0x00, 0x0c,
+    0x00, 0x20, 0x00, 0x21, 0x9a, 0x68, 0x33, 0x4d, 0x19, 0x97, 0x8b, 0xb9,
+    0x22, 0x9c, 0x28, 0x48, 0x66, 0x61, 0xb8, 0xea, 0x00,
+  };
+
+  BzipExtentWriter bzip_writer(
+      brillo::make_unique_ptr(new DirectExtentWriter()));
+  EXPECT_TRUE(bzip_writer.Init(fd_, extents, kBlockSize));
+  EXPECT_TRUE(bzip_writer.Write(test, sizeof(test)));
+  EXPECT_TRUE(bzip_writer.End());
+
+  brillo::Blob buf;
+  EXPECT_TRUE(utils::ReadFile(path_, &buf));
+  EXPECT_EQ(strlen(test_uncompressed), buf.size());
+  EXPECT_EQ(string(buf.begin(), buf.end()), string(test_uncompressed));
+}
+
+TEST_F(BzipExtentWriterTest, ChunkedTest) {
+  const brillo::Blob::size_type kDecompressedLength = 2048 * 1024;  // 2 MiB
+  string decompressed_path;
+  ASSERT_TRUE(utils::MakeTempFile("BzipExtentWriterTest-decompressed-XXXXXX",
+                                  &decompressed_path, nullptr));
+  string compressed_path;
+  ASSERT_TRUE(utils::MakeTempFile("BzipExtentWriterTest-compressed-XXXXXX",
+                                  &compressed_path, nullptr));
+  const size_t kChunkSize = 3;
+
+  vector<Extent> extents;
+  Extent extent;
+  extent.set_start_block(0);
+  extent.set_num_blocks(kDecompressedLength / kBlockSize + 1);
+  extents.push_back(extent);
+
+  brillo::Blob decompressed_data(kDecompressedLength);
+  test_utils::FillWithData(&decompressed_data);
+
+  EXPECT_TRUE(test_utils::WriteFileVector(
+      decompressed_path, decompressed_data));
+
+  EXPECT_EQ(0, test_utils::System(
+      string("cat ") + decompressed_path + "|bzip2>" + compressed_path));
+
+  brillo::Blob compressed_data;
+  EXPECT_TRUE(utils::ReadFile(compressed_path, &compressed_data));
+
+  BzipExtentWriter bzip_writer(
+      brillo::make_unique_ptr(new DirectExtentWriter()));
+  EXPECT_TRUE(bzip_writer.Init(fd_, extents, kBlockSize));
+
+  brillo::Blob original_compressed_data = compressed_data;
+  for (brillo::Blob::size_type i = 0; i < compressed_data.size();
+       i += kChunkSize) {
+    size_t this_chunk_size = min(kChunkSize, compressed_data.size() - i);
+    EXPECT_TRUE(bzip_writer.Write(&compressed_data[i], this_chunk_size));
+  }
+  EXPECT_TRUE(bzip_writer.End());
+
+  // Check that the const input has not been clobbered.
+  test_utils::ExpectVectorsEq(original_compressed_data, compressed_data);
+
+  brillo::Blob output;
+  EXPECT_TRUE(utils::ReadFile(path_, &output));
+  EXPECT_EQ(kDecompressedLength, output.size());
+  test_utils::ExpectVectorsEq(decompressed_data, output);
+
+  unlink(decompressed_path.c_str());
+  unlink(compressed_path.c_str());
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
new file mode 100644
index 0000000..1df5214
--- /dev/null
+++ b/payload_consumer/delta_performer.cc
@@ -0,0 +1,1744 @@
+//
+// Copyright (C) 2012 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 "update_engine/payload_consumer/delta_performer.h"
+
+#include <endian.h>
+#include <errno.h>
+#include <linux/fs.h>
+
+#include <algorithm>
+#include <cstring>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <base/files/file_util.h>
+#include <base/format_macros.h>
+#include <base/strings/string_util.h>
+#include <base/strings/stringprintf.h>
+#include <brillo/data_encoding.h>
+#include <brillo/make_unique_ptr.h>
+#include <google/protobuf/repeated_field.h>
+
+#include "update_engine/common/constants.h"
+#include "update_engine/common/hardware_interface.h"
+#include "update_engine/payload_consumer/bzip_extent_writer.h"
+#include "update_engine/payload_consumer/extent_writer.h"
+#if USE_MTD
+#include "update_engine/payload_consumer/mtd_file_descriptor.h"
+#endif
+#include "update_engine/common/prefs_interface.h"
+#include "update_engine/common/subprocess.h"
+#include "update_engine/common/terminator.h"
+#include "update_engine/payload_consumer/payload_constants.h"
+#include "update_engine/payload_consumer/payload_verifier.h"
+#include "update_engine/payload_consumer/xz_extent_writer.h"
+#include "update_engine/payload_state_interface.h"
+#include "update_engine/update_attempter.h"
+
+using google::protobuf::RepeatedPtrField;
+using std::min;
+using std::string;
+using std::vector;
+
+namespace chromeos_update_engine {
+
+const uint64_t DeltaPerformer::kDeltaVersionOffset = sizeof(kDeltaMagic);
+const uint64_t DeltaPerformer::kDeltaVersionSize = 8;
+const uint64_t DeltaPerformer::kDeltaManifestSizeOffset =
+    kDeltaVersionOffset + kDeltaVersionSize;
+const uint64_t DeltaPerformer::kDeltaManifestSizeSize = 8;
+const uint64_t DeltaPerformer::kDeltaMetadataSignatureSizeSize = 4;
+const uint64_t DeltaPerformer::kMaxPayloadHeaderSize = 24;
+const uint64_t DeltaPerformer::kSupportedMajorPayloadVersion = 2;
+const uint32_t DeltaPerformer::kSupportedMinorPayloadVersion = 2;
+
+const unsigned DeltaPerformer::kProgressLogMaxChunks = 10;
+const unsigned DeltaPerformer::kProgressLogTimeoutSeconds = 30;
+const unsigned DeltaPerformer::kProgressDownloadWeight = 50;
+const unsigned DeltaPerformer::kProgressOperationsWeight = 50;
+
+namespace {
+const int kUpdateStateOperationInvalid = -1;
+const int kMaxResumedUpdateFailures = 10;
+#if USE_MTD
+const int kUbiVolumeAttachTimeout = 5 * 60;
+#endif
+
+FileDescriptorPtr CreateFileDescriptor(const char* path) {
+  FileDescriptorPtr ret;
+#if USE_MTD
+  if (strstr(path, "/dev/ubi") == path) {
+    if (!UbiFileDescriptor::IsUbi(path)) {
+      // The volume might not have been attached at boot time.
+      int volume_no;
+      if (utils::SplitPartitionName(path, nullptr, &volume_no)) {
+        utils::TryAttachingUbiVolume(volume_no, kUbiVolumeAttachTimeout);
+      }
+    }
+    if (UbiFileDescriptor::IsUbi(path)) {
+      LOG(INFO) << path << " is a UBI device.";
+      ret.reset(new UbiFileDescriptor);
+    }
+  } else if (MtdFileDescriptor::IsMtd(path)) {
+    LOG(INFO) << path << " is an MTD device.";
+    ret.reset(new MtdFileDescriptor);
+  } else {
+    LOG(INFO) << path << " is not an MTD nor a UBI device.";
+#endif
+    ret.reset(new EintrSafeFileDescriptor);
+#if USE_MTD
+  }
+#endif
+  return ret;
+}
+
+// Opens path for read/write. On success returns an open FileDescriptor
+// and sets *err to 0. On failure, sets *err to errno and returns nullptr.
+FileDescriptorPtr OpenFile(const char* path, int mode, int* err) {
+  FileDescriptorPtr fd = CreateFileDescriptor(path);
+#if USE_MTD
+  // On NAND devices, we can either read, or write, but not both. So here we
+  // use O_WRONLY.
+  if (UbiFileDescriptor::IsUbi(path) || MtdFileDescriptor::IsMtd(path)) {
+    mode = O_WRONLY;
+  }
+#endif
+  if (!fd->Open(path, mode, 000)) {
+    *err = errno;
+    PLOG(ERROR) << "Unable to open file " << path;
+    return nullptr;
+  }
+  *err = 0;
+  return fd;
+}
+}  // namespace
+
+
+// Computes the ratio of |part| and |total|, scaled to |norm|, using integer
+// arithmetic.
+static uint64_t IntRatio(uint64_t part, uint64_t total, uint64_t norm) {
+  return part * norm / total;
+}
+
+void DeltaPerformer::LogProgress(const char* message_prefix) {
+  // Format operations total count and percentage.
+  string total_operations_str("?");
+  string completed_percentage_str("");
+  if (num_total_operations_) {
+    total_operations_str = std::to_string(num_total_operations_);
+    // Upcasting to 64-bit to avoid overflow, back to size_t for formatting.
+    completed_percentage_str =
+        base::StringPrintf(" (%" PRIu64 "%%)",
+                           IntRatio(next_operation_num_, num_total_operations_,
+                                    100));
+  }
+
+  // Format download total count and percentage.
+  size_t payload_size = install_plan_->payload_size;
+  string payload_size_str("?");
+  string downloaded_percentage_str("");
+  if (payload_size) {
+    payload_size_str = std::to_string(payload_size);
+    // Upcasting to 64-bit to avoid overflow, back to size_t for formatting.
+    downloaded_percentage_str =
+        base::StringPrintf(" (%" PRIu64 "%%)",
+                           IntRatio(total_bytes_received_, payload_size, 100));
+  }
+
+  LOG(INFO) << (message_prefix ? message_prefix : "") << next_operation_num_
+            << "/" << total_operations_str << " operations"
+            << completed_percentage_str << ", " << total_bytes_received_
+            << "/" << payload_size_str << " bytes downloaded"
+            << downloaded_percentage_str << ", overall progress "
+            << overall_progress_ << "%";
+}
+
+void DeltaPerformer::UpdateOverallProgress(bool force_log,
+                                           const char* message_prefix) {
+  // Compute our download and overall progress.
+  unsigned new_overall_progress = 0;
+  COMPILE_ASSERT(kProgressDownloadWeight + kProgressOperationsWeight == 100,
+                 progress_weight_dont_add_up);
+  // Only consider download progress if its total size is known; otherwise
+  // adjust the operations weight to compensate for the absence of download
+  // progress. Also, make sure to cap the download portion at
+  // kProgressDownloadWeight, in case we end up downloading more than we
+  // initially expected (this indicates a problem, but could generally happen).
+  // TODO(garnold) the correction of operations weight when we do not have the
+  // total payload size, as well as the conditional guard below, should both be
+  // eliminated once we ensure that the payload_size in the install plan is
+  // always given and is non-zero. This currently isn't the case during unit
+  // tests (see chromium-os:37969).
+  size_t payload_size = install_plan_->payload_size;
+  unsigned actual_operations_weight = kProgressOperationsWeight;
+  if (payload_size)
+    new_overall_progress += min(
+        static_cast<unsigned>(IntRatio(total_bytes_received_, payload_size,
+                                       kProgressDownloadWeight)),
+        kProgressDownloadWeight);
+  else
+    actual_operations_weight += kProgressDownloadWeight;
+
+  // Only add completed operations if their total number is known; we definitely
+  // expect an update to have at least one operation, so the expectation is that
+  // this will eventually reach |actual_operations_weight|.
+  if (num_total_operations_)
+    new_overall_progress += IntRatio(next_operation_num_, num_total_operations_,
+                                     actual_operations_weight);
+
+  // Progress ratio cannot recede, unless our assumptions about the total
+  // payload size, total number of operations, or the monotonicity of progress
+  // is breached.
+  if (new_overall_progress < overall_progress_) {
+    LOG(WARNING) << "progress counter receded from " << overall_progress_
+                 << "% down to " << new_overall_progress << "%; this is a bug";
+    force_log = true;
+  }
+  overall_progress_ = new_overall_progress;
+
+  // Update chunk index, log as needed: if forced by called, or we completed a
+  // progress chunk, or a timeout has expired.
+  base::Time curr_time = base::Time::Now();
+  unsigned curr_progress_chunk =
+      overall_progress_ * kProgressLogMaxChunks / 100;
+  if (force_log || curr_progress_chunk > last_progress_chunk_ ||
+      curr_time > forced_progress_log_time_) {
+    forced_progress_log_time_ = curr_time + forced_progress_log_wait_;
+    LogProgress(message_prefix);
+  }
+  last_progress_chunk_ = curr_progress_chunk;
+}
+
+
+size_t DeltaPerformer::CopyDataToBuffer(const char** bytes_p, size_t* count_p,
+                                        size_t max) {
+  const size_t count = *count_p;
+  if (!count)
+    return 0;  // Special case shortcut.
+  size_t read_len = min(count, max - buffer_.size());
+  const char* bytes_start = *bytes_p;
+  const char* bytes_end = bytes_start + read_len;
+  buffer_.insert(buffer_.end(), bytes_start, bytes_end);
+  *bytes_p = bytes_end;
+  *count_p = count - read_len;
+  return read_len;
+}
+
+
+bool DeltaPerformer::HandleOpResult(bool op_result, const char* op_type_name,
+                                    ErrorCode* error) {
+  if (op_result)
+    return true;
+
+  LOG(ERROR) << "Failed to perform " << op_type_name << " operation "
+             << next_operation_num_;
+  *error = ErrorCode::kDownloadOperationExecutionError;
+  return false;
+}
+
+int DeltaPerformer::Close() {
+  int err = -CloseCurrentPartition();
+  LOG_IF(ERROR, !payload_hash_calculator_.Finalize() ||
+                !signed_hash_calculator_.Finalize())
+      << "Unable to finalize the hash.";
+  if (!buffer_.empty()) {
+    LOG(INFO) << "Discarding " << buffer_.size() << " unused downloaded bytes";
+    if (err >= 0)
+      err = 1;
+  }
+  return -err;
+}
+
+int DeltaPerformer::CloseCurrentPartition() {
+  int err = 0;
+  if (source_fd_ && !source_fd_->Close()) {
+    err = errno;
+    PLOG(ERROR) << "Error closing source partition";
+    if (!err)
+      err = 1;
+  }
+  source_fd_.reset();
+  source_path_.clear();
+
+  if (target_fd_ && !target_fd_->Close()) {
+    err = errno;
+    PLOG(ERROR) << "Error closing target partition";
+    if (!err)
+      err = 1;
+  }
+  target_fd_.reset();
+  target_path_.clear();
+  return -err;
+}
+
+bool DeltaPerformer::OpenCurrentPartition() {
+  if (current_partition_ >= partitions_.size())
+    return false;
+
+  const PartitionUpdate& partition = partitions_[current_partition_];
+  // Open source fds if we have a delta payload with minor version 2.
+  if (!install_plan_->is_full_update &&
+      GetMinorVersion() == kSourceMinorPayloadVersion) {
+    source_path_ = install_plan_->partitions[current_partition_].source_path;
+    int err;
+    source_fd_ = OpenFile(source_path_.c_str(), O_RDONLY, &err);
+    if (!source_fd_) {
+      LOG(ERROR) << "Unable to open source partition "
+                 << partition.partition_name() << " on slot "
+                 << BootControlInterface::SlotName(install_plan_->source_slot)
+                 << ", file " << source_path_;
+      return false;
+    }
+  }
+
+  target_path_ = install_plan_->partitions[current_partition_].target_path;
+  int err;
+  target_fd_ = OpenFile(target_path_.c_str(), O_RDWR, &err);
+  if (!target_fd_) {
+    LOG(ERROR) << "Unable to open target partition "
+               << partition.partition_name() << " on slot "
+               << BootControlInterface::SlotName(install_plan_->target_slot)
+               << ", file " << target_path_;
+    return false;
+  }
+  return true;
+}
+
+namespace {
+
+void LogPartitionInfoHash(const PartitionInfo& info, const string& tag) {
+  string sha256 = brillo::data_encoding::Base64Encode(info.hash());
+  LOG(INFO) << "PartitionInfo " << tag << " sha256: " << sha256
+            << " size: " << info.size();
+}
+
+void LogPartitionInfo(const vector<PartitionUpdate>& partitions) {
+  for (const PartitionUpdate& partition : partitions) {
+    LogPartitionInfoHash(partition.old_partition_info(),
+                         "old " + partition.partition_name());
+    LogPartitionInfoHash(partition.new_partition_info(),
+                         "new " + partition.partition_name());
+  }
+}
+
+}  // namespace
+
+bool DeltaPerformer::GetMetadataSignatureSizeOffset(
+    uint64_t* out_offset) const {
+  if (GetMajorVersion() == kBrilloMajorPayloadVersion) {
+    *out_offset = kDeltaManifestSizeOffset + kDeltaManifestSizeSize;
+    return true;
+  }
+  return false;
+}
+
+bool DeltaPerformer::GetManifestOffset(uint64_t* out_offset) const {
+  // Actual manifest begins right after the manifest size field or
+  // metadata signature size field if major version >= 2.
+  if (major_payload_version_ == kChromeOSMajorPayloadVersion) {
+    *out_offset = kDeltaManifestSizeOffset + kDeltaManifestSizeSize;
+    return true;
+  }
+  if (major_payload_version_ == kBrilloMajorPayloadVersion) {
+    *out_offset = kDeltaManifestSizeOffset + kDeltaManifestSizeSize +
+                  kDeltaMetadataSignatureSizeSize;
+    return true;
+  }
+  LOG(ERROR) << "Unknown major payload version: " << major_payload_version_;
+  return false;
+}
+
+uint64_t DeltaPerformer::GetMetadataSize() const {
+  return metadata_size_;
+}
+
+uint64_t DeltaPerformer::GetMajorVersion() const {
+  return major_payload_version_;
+}
+
+uint32_t DeltaPerformer::GetMinorVersion() const {
+  if (manifest_.has_minor_version()) {
+    return manifest_.minor_version();
+  } else {
+    return (install_plan_->is_full_update ?
+            kFullPayloadMinorVersion :
+            kSupportedMinorPayloadVersion);
+  }
+}
+
+bool DeltaPerformer::GetManifest(DeltaArchiveManifest* out_manifest_p) const {
+  if (!manifest_parsed_)
+    return false;
+  *out_manifest_p = manifest_;
+  return true;
+}
+
+bool DeltaPerformer::IsHeaderParsed() const {
+  return metadata_size_ != 0;
+}
+
+DeltaPerformer::MetadataParseResult DeltaPerformer::ParsePayloadMetadata(
+    const brillo::Blob& payload, ErrorCode* error) {
+  *error = ErrorCode::kSuccess;
+  uint64_t manifest_offset;
+
+  if (!IsHeaderParsed()) {
+    // Ensure we have data to cover the major payload version.
+    if (payload.size() < kDeltaManifestSizeOffset)
+      return kMetadataParseInsufficientData;
+
+    // Validate the magic string.
+    if (memcmp(payload.data(), kDeltaMagic, sizeof(kDeltaMagic)) != 0) {
+      LOG(ERROR) << "Bad payload format -- invalid delta magic.";
+      *error = ErrorCode::kDownloadInvalidMetadataMagicString;
+      return kMetadataParseError;
+    }
+
+    // Extract the payload version from the metadata.
+    COMPILE_ASSERT(sizeof(major_payload_version_) == kDeltaVersionSize,
+                   major_payload_version_size_mismatch);
+    memcpy(&major_payload_version_,
+           &payload[kDeltaVersionOffset],
+           kDeltaVersionSize);
+    // switch big endian to host
+    major_payload_version_ = be64toh(major_payload_version_);
+
+    if (major_payload_version_ != supported_major_version_ &&
+        major_payload_version_ != kChromeOSMajorPayloadVersion) {
+      LOG(ERROR) << "Bad payload format -- unsupported payload version: "
+          << major_payload_version_;
+      *error = ErrorCode::kUnsupportedMajorPayloadVersion;
+      return kMetadataParseError;
+    }
+
+    // Get the manifest offset now that we have payload version.
+    if (!GetManifestOffset(&manifest_offset)) {
+      *error = ErrorCode::kUnsupportedMajorPayloadVersion;
+      return kMetadataParseError;
+    }
+    // Check again with the manifest offset.
+    if (payload.size() < manifest_offset)
+      return kMetadataParseInsufficientData;
+
+    // Next, parse the manifest size.
+    COMPILE_ASSERT(sizeof(manifest_size_) == kDeltaManifestSizeSize,
+                   manifest_size_size_mismatch);
+    memcpy(&manifest_size_,
+           &payload[kDeltaManifestSizeOffset],
+           kDeltaManifestSizeSize);
+    manifest_size_ = be64toh(manifest_size_);  // switch big endian to host
+
+    if (GetMajorVersion() == kBrilloMajorPayloadVersion) {
+      // Parse the metadata signature size.
+      COMPILE_ASSERT(sizeof(metadata_signature_size_) ==
+                     kDeltaMetadataSignatureSizeSize,
+                     metadata_signature_size_size_mismatch);
+      uint64_t metadata_signature_size_offset;
+      if (!GetMetadataSignatureSizeOffset(&metadata_signature_size_offset)) {
+        *error = ErrorCode::kError;
+        return kMetadataParseError;
+      }
+      memcpy(&metadata_signature_size_,
+             &payload[metadata_signature_size_offset],
+             kDeltaMetadataSignatureSizeSize);
+      metadata_signature_size_ = be32toh(metadata_signature_size_);
+    }
+
+    // If the metadata size is present in install plan, check for it immediately
+    // even before waiting for that many number of bytes to be downloaded in the
+    // payload. This will prevent any attack which relies on us downloading data
+    // beyond the expected metadata size.
+    metadata_size_ = manifest_offset + manifest_size_;
+    if (install_plan_->hash_checks_mandatory) {
+      if (install_plan_->metadata_size != metadata_size_) {
+        LOG(ERROR) << "Mandatory metadata size in Omaha response ("
+                   << install_plan_->metadata_size
+                   << ") is missing/incorrect, actual = " << metadata_size_;
+        *error = ErrorCode::kDownloadInvalidMetadataSize;
+        return kMetadataParseError;
+      }
+    }
+  }
+
+  // Now that we have validated the metadata size, we should wait for the full
+  // metadata and its signature (if exist) to be read in before we can parse it.
+  if (payload.size() < metadata_size_ + metadata_signature_size_)
+    return kMetadataParseInsufficientData;
+
+  // Log whether we validated the size or simply trusting what's in the payload
+  // here. This is logged here (after we received the full metadata data) so
+  // that we just log once (instead of logging n times) if it takes n
+  // DeltaPerformer::Write calls to download the full manifest.
+  if (install_plan_->metadata_size == metadata_size_) {
+    LOG(INFO) << "Manifest size in payload matches expected value from Omaha";
+  } else {
+    // For mandatory-cases, we'd have already returned a kMetadataParseError
+    // above. We'll be here only for non-mandatory cases. Just send a UMA stat.
+    LOG(WARNING) << "Ignoring missing/incorrect metadata size ("
+                 << install_plan_->metadata_size
+                 << ") in Omaha response as validation is not mandatory. "
+                 << "Trusting metadata size in payload = " << metadata_size_;
+  }
+
+  // We have the full metadata in |payload|. Verify its integrity
+  // and authenticity based on the information we have in Omaha response.
+  *error = ValidateMetadataSignature(payload);
+  if (*error != ErrorCode::kSuccess) {
+    if (install_plan_->hash_checks_mandatory) {
+      // The autoupdate_CatchBadSignatures test checks for this string
+      // in log-files. Keep in sync.
+      LOG(ERROR) << "Mandatory metadata signature validation failed";
+      return kMetadataParseError;
+    }
+
+    // For non-mandatory cases, just send a UMA stat.
+    LOG(WARNING) << "Ignoring metadata signature validation failures";
+    *error = ErrorCode::kSuccess;
+  }
+
+  if (!GetManifestOffset(&manifest_offset)) {
+    *error = ErrorCode::kUnsupportedMajorPayloadVersion;
+    return kMetadataParseError;
+  }
+  // The payload metadata is deemed valid, it's safe to parse the protobuf.
+  if (!manifest_.ParseFromArray(&payload[manifest_offset], manifest_size_)) {
+    LOG(ERROR) << "Unable to parse manifest in update file.";
+    *error = ErrorCode::kDownloadManifestParseError;
+    return kMetadataParseError;
+  }
+
+  manifest_parsed_ = true;
+  return kMetadataParseSuccess;
+}
+
+// Wrapper around write. Returns true if all requested bytes
+// were written, or false on any error, regardless of progress
+// and stores an action exit code in |error|.
+bool DeltaPerformer::Write(const void* bytes, size_t count, ErrorCode *error) {
+  *error = ErrorCode::kSuccess;
+
+  const char* c_bytes = reinterpret_cast<const char*>(bytes);
+  system_state_->payload_state()->DownloadProgress(count);
+
+  // Update the total byte downloaded count and the progress logs.
+  total_bytes_received_ += count;
+  UpdateOverallProgress(false, "Completed ");
+
+  while (!manifest_valid_) {
+    // Read data up to the needed limit; this is either maximium payload header
+    // size, or the full metadata size (once it becomes known).
+    const bool do_read_header = !IsHeaderParsed();
+    CopyDataToBuffer(&c_bytes, &count,
+                     (do_read_header ? kMaxPayloadHeaderSize :
+                      metadata_size_ + metadata_signature_size_));
+
+    MetadataParseResult result = ParsePayloadMetadata(buffer_, error);
+    if (result == kMetadataParseError)
+      return false;
+    if (result == kMetadataParseInsufficientData) {
+      // If we just processed the header, make an attempt on the manifest.
+      if (do_read_header && IsHeaderParsed())
+        continue;
+
+      return true;
+    }
+
+    // Checks the integrity of the payload manifest.
+    if ((*error = ValidateManifest()) != ErrorCode::kSuccess)
+      return false;
+    manifest_valid_ = true;
+
+    // Clear the download buffer.
+    DiscardBuffer(false, metadata_size_);
+
+    // This populates |partitions_| and the |install_plan.partitions| with the
+    // list of partitions from the manifest.
+    if (!ParseManifestPartitions(error))
+      return false;
+
+    num_total_operations_ = 0;
+    for (const auto& partition : partitions_) {
+      num_total_operations_ += partition.operations_size();
+      acc_num_operations_.push_back(num_total_operations_);
+    }
+
+    LOG_IF(WARNING, !prefs_->SetInt64(kPrefsManifestMetadataSize,
+                                      metadata_size_))
+        << "Unable to save the manifest metadata size.";
+
+    if (!PrimeUpdateState()) {
+      *error = ErrorCode::kDownloadStateInitializationError;
+      LOG(ERROR) << "Unable to prime the update state.";
+      return false;
+    }
+
+    if (!OpenCurrentPartition()) {
+      *error = ErrorCode::kInstallDeviceOpenError;
+      return false;
+    }
+
+    if (next_operation_num_ > 0)
+      UpdateOverallProgress(true, "Resuming after ");
+    LOG(INFO) << "Starting to apply update payload operations";
+  }
+
+  while (next_operation_num_ < num_total_operations_) {
+    // Check if we should cancel the current attempt for any reason.
+    // In this case, *error will have already been populated with the reason
+    // why we're canceling.
+    if (system_state_->update_attempter()->ShouldCancel(error))
+      return false;
+
+    // We know there are more operations to perform because we didn't reach the
+    // |num_total_operations_| limit yet.
+    while (next_operation_num_ >= acc_num_operations_[current_partition_]) {
+      CloseCurrentPartition();
+      current_partition_++;
+      if (!OpenCurrentPartition()) {
+        *error = ErrorCode::kInstallDeviceOpenError;
+        return false;
+      }
+    }
+    const size_t partition_operation_num = next_operation_num_ - (
+        current_partition_ ? acc_num_operations_[current_partition_ - 1] : 0);
+
+    const InstallOperation& op =
+        partitions_[current_partition_].operations(partition_operation_num);
+
+    CopyDataToBuffer(&c_bytes, &count, op.data_length());
+
+    // Check whether we received all of the next operation's data payload.
+    if (!CanPerformInstallOperation(op))
+      return true;
+
+    // Validate the operation only if the metadata signature is present.
+    // Otherwise, keep the old behavior. This serves as a knob to disable
+    // the validation logic in case we find some regression after rollout.
+    // NOTE: If hash checks are mandatory and if metadata_signature is empty,
+    // we would have already failed in ParsePayloadMetadata method and thus not
+    // even be here. So no need to handle that case again here.
+    if (!install_plan_->metadata_signature.empty()) {
+      // Note: Validate must be called only if CanPerformInstallOperation is
+      // called. Otherwise, we might be failing operations before even if there
+      // isn't sufficient data to compute the proper hash.
+      *error = ValidateOperationHash(op);
+      if (*error != ErrorCode::kSuccess) {
+        if (install_plan_->hash_checks_mandatory) {
+          LOG(ERROR) << "Mandatory operation hash check failed";
+          return false;
+        }
+
+        // For non-mandatory cases, just send a UMA stat.
+        LOG(WARNING) << "Ignoring operation validation errors";
+        *error = ErrorCode::kSuccess;
+      }
+    }
+
+    // Makes sure we unblock exit when this operation completes.
+    ScopedTerminatorExitUnblocker exit_unblocker =
+        ScopedTerminatorExitUnblocker();  // Avoids a compiler unused var bug.
+
+    bool op_result;
+    switch (op.type()) {
+      case InstallOperation::REPLACE:
+      case InstallOperation::REPLACE_BZ:
+      case InstallOperation::REPLACE_XZ:
+        op_result = PerformReplaceOperation(op);
+        break;
+      case InstallOperation::ZERO:
+      case InstallOperation::DISCARD:
+        op_result = PerformZeroOrDiscardOperation(op);
+        break;
+      case InstallOperation::MOVE:
+        op_result = PerformMoveOperation(op);
+        break;
+      case InstallOperation::BSDIFF:
+        op_result = PerformBsdiffOperation(op);
+        break;
+      case InstallOperation::SOURCE_COPY:
+        op_result = PerformSourceCopyOperation(op);
+        break;
+      case InstallOperation::SOURCE_BSDIFF:
+        op_result = PerformSourceBsdiffOperation(op);
+        break;
+      default:
+       op_result = false;
+    }
+    if (!HandleOpResult(op_result, InstallOperationTypeName(op.type()), error))
+      return false;
+
+    next_operation_num_++;
+    UpdateOverallProgress(false, "Completed ");
+    CheckpointUpdateProgress();
+  }
+
+  // In major version 2, we don't add dummy operation to the payload.
+  if (major_payload_version_ == kBrilloMajorPayloadVersion &&
+      manifest_.has_signatures_offset() && manifest_.has_signatures_size()) {
+    if (manifest_.signatures_offset() != buffer_offset_) {
+      LOG(ERROR) << "Payload signatures offset points to blob offset "
+                 << manifest_.signatures_offset()
+                 << " but signatures are expected at offset "
+                 << buffer_offset_;
+      *error = ErrorCode::kDownloadPayloadVerificationError;
+      return false;
+    }
+    CopyDataToBuffer(&c_bytes, &count, manifest_.signatures_size());
+    // Needs more data to cover entire signature.
+    if (buffer_.size() < manifest_.signatures_size())
+      return true;
+    if (!ExtractSignatureMessage()) {
+      LOG(ERROR) << "Extract payload signature failed.";
+      *error = ErrorCode::kDownloadPayloadVerificationError;
+      return false;
+    }
+    DiscardBuffer(true, 0);
+  }
+
+  return true;
+}
+
+bool DeltaPerformer::IsManifestValid() {
+  return manifest_valid_;
+}
+
+bool DeltaPerformer::ParseManifestPartitions(ErrorCode* error) {
+  if (major_payload_version_ == kBrilloMajorPayloadVersion) {
+    partitions_.clear();
+    for (const PartitionUpdate& partition : manifest_.partitions()) {
+      partitions_.push_back(partition);
+    }
+    manifest_.clear_partitions();
+  } else if (major_payload_version_ == kChromeOSMajorPayloadVersion) {
+    LOG(INFO) << "Converting update information from old format.";
+    PartitionUpdate root_part;
+    root_part.set_partition_name(kLegacyPartitionNameRoot);
+#ifdef __ANDROID__
+    LOG(WARNING) << "Legacy payload major version provided to an Android "
+                    "build. Assuming no post-install. Please use major version "
+                    "2 or newer.";
+    root_part.set_run_postinstall(false);
+#else
+    root_part.set_run_postinstall(true);
+#endif  // __ANDROID__
+    if (manifest_.has_old_rootfs_info()) {
+      *root_part.mutable_old_partition_info() = manifest_.old_rootfs_info();
+      manifest_.clear_old_rootfs_info();
+    }
+    if (manifest_.has_new_rootfs_info()) {
+      *root_part.mutable_new_partition_info() = manifest_.new_rootfs_info();
+      manifest_.clear_new_rootfs_info();
+    }
+    *root_part.mutable_operations() = manifest_.install_operations();
+    manifest_.clear_install_operations();
+    partitions_.push_back(std::move(root_part));
+
+    PartitionUpdate kern_part;
+    kern_part.set_partition_name(kLegacyPartitionNameKernel);
+    kern_part.set_run_postinstall(false);
+    if (manifest_.has_old_kernel_info()) {
+      *kern_part.mutable_old_partition_info() = manifest_.old_kernel_info();
+      manifest_.clear_old_kernel_info();
+    }
+    if (manifest_.has_new_kernel_info()) {
+      *kern_part.mutable_new_partition_info() = manifest_.new_kernel_info();
+      manifest_.clear_new_kernel_info();
+    }
+    *kern_part.mutable_operations() = manifest_.kernel_install_operations();
+    manifest_.clear_kernel_install_operations();
+    partitions_.push_back(std::move(kern_part));
+  }
+
+  // TODO(deymo): Remove this block of code once we switched to optional
+  // source partition verification. This list of partitions in the InstallPlan
+  // is initialized with the expected hashes in the payload major version 1,
+  // so we need to check those now if already set. See b/23182225.
+  if (!install_plan_->partitions.empty()) {
+    if (!VerifySourcePartitions()) {
+      *error = ErrorCode::kDownloadStateInitializationError;
+      return false;
+    }
+  }
+
+  // Fill in the InstallPlan::partitions based on the partitions from the
+  // payload.
+  install_plan_->partitions.clear();
+  for (const auto& partition : partitions_) {
+    InstallPlan::Partition install_part;
+    install_part.name = partition.partition_name();
+    install_part.run_postinstall =
+        partition.has_run_postinstall() && partition.run_postinstall();
+
+    if (partition.has_old_partition_info()) {
+      const PartitionInfo& info = partition.old_partition_info();
+      install_part.source_size = info.size();
+      install_part.source_hash.assign(info.hash().begin(), info.hash().end());
+    }
+
+    if (!partition.has_new_partition_info()) {
+      LOG(ERROR) << "Unable to get new partition hash info on partition "
+                 << install_part.name << ".";
+      *error = ErrorCode::kDownloadNewPartitionInfoError;
+      return false;
+    }
+    const PartitionInfo& info = partition.new_partition_info();
+    install_part.target_size = info.size();
+    install_part.target_hash.assign(info.hash().begin(), info.hash().end());
+
+    install_plan_->partitions.push_back(install_part);
+  }
+
+  if (!install_plan_->LoadPartitionsFromSlots(system_state_)) {
+    LOG(ERROR) << "Unable to determine all the partition devices.";
+    *error = ErrorCode::kInstallDeviceOpenError;
+    return false;
+  }
+  LogPartitionInfo(partitions_);
+  return true;
+}
+
+bool DeltaPerformer::CanPerformInstallOperation(
+    const chromeos_update_engine::InstallOperation& operation) {
+  // Move and source_copy operations don't require any data blob, so they can
+  // always be performed.
+  if (operation.type() == InstallOperation::MOVE ||
+      operation.type() == InstallOperation::SOURCE_COPY)
+    return true;
+
+  // See if we have the entire data blob in the buffer
+  if (operation.data_offset() < buffer_offset_) {
+    LOG(ERROR) << "we threw away data it seems?";
+    return false;
+  }
+
+  return (operation.data_offset() + operation.data_length() <=
+          buffer_offset_ + buffer_.size());
+}
+
+bool DeltaPerformer::PerformReplaceOperation(
+    const InstallOperation& operation) {
+  CHECK(operation.type() == InstallOperation::REPLACE ||
+        operation.type() == InstallOperation::REPLACE_BZ ||
+        operation.type() == InstallOperation::REPLACE_XZ);
+
+  // Since we delete data off the beginning of the buffer as we use it,
+  // the data we need should be exactly at the beginning of the buffer.
+  TEST_AND_RETURN_FALSE(buffer_offset_ == operation.data_offset());
+  TEST_AND_RETURN_FALSE(buffer_.size() >= operation.data_length());
+
+  // Extract the signature message if it's in this operation.
+  if (ExtractSignatureMessageFromOperation(operation)) {
+    // If this is dummy replace operation, we ignore it after extracting the
+    // signature.
+    DiscardBuffer(true, 0);
+    return true;
+  }
+
+  // Setup the ExtentWriter stack based on the operation type.
+  std::unique_ptr<ExtentWriter> writer =
+    brillo::make_unique_ptr(new ZeroPadExtentWriter(
+      brillo::make_unique_ptr(new DirectExtentWriter())));
+
+  if (operation.type() == InstallOperation::REPLACE_BZ) {
+    writer.reset(new BzipExtentWriter(std::move(writer)));
+  } else if (operation.type() == InstallOperation::REPLACE_XZ) {
+    writer.reset(new XzExtentWriter(std::move(writer)));
+  }
+
+  // Create a vector of extents to pass to the ExtentWriter.
+  vector<Extent> extents;
+  for (int i = 0; i < operation.dst_extents_size(); i++) {
+    extents.push_back(operation.dst_extents(i));
+  }
+
+  TEST_AND_RETURN_FALSE(writer->Init(target_fd_, extents, block_size_));
+  TEST_AND_RETURN_FALSE(writer->Write(buffer_.data(), operation.data_length()));
+  TEST_AND_RETURN_FALSE(writer->End());
+
+  // Update buffer
+  DiscardBuffer(true, buffer_.size());
+  return true;
+}
+
+bool DeltaPerformer::PerformZeroOrDiscardOperation(
+    const InstallOperation& operation) {
+  CHECK(operation.type() == InstallOperation::DISCARD ||
+        operation.type() == InstallOperation::ZERO);
+
+  // These operations have no blob.
+  TEST_AND_RETURN_FALSE(!operation.has_data_offset());
+  TEST_AND_RETURN_FALSE(!operation.has_data_length());
+
+  int request =
+      (operation.type() == InstallOperation::ZERO ? BLKZEROOUT : BLKDISCARD);
+
+  bool attempt_ioctl = true;
+  brillo::Blob zeros;
+  for (int i = 0; i < operation.dst_extents_size(); i++) {
+    Extent extent = operation.dst_extents(i);
+    const uint64_t start = extent.start_block() * block_size_;
+    const uint64_t length = extent.num_blocks() * block_size_;
+    if (attempt_ioctl) {
+      int result = 0;
+      if (target_fd_->BlkIoctl(request, start, length, &result) && result == 0)
+        continue;
+      attempt_ioctl = false;
+      zeros.resize(16 * block_size_);
+    }
+    // In case of failure, we fall back to writing 0 to the selected region.
+    for (uint64_t offset = 0; offset < length; offset += zeros.size()) {
+      uint64_t chunk_length = min(length - offset,
+                                  static_cast<uint64_t>(zeros.size()));
+      TEST_AND_RETURN_FALSE(
+          utils::PWriteAll(target_fd_, zeros.data(), chunk_length, start + offset));
+    }
+  }
+  return true;
+}
+
+bool DeltaPerformer::PerformMoveOperation(const InstallOperation& operation) {
+  // Calculate buffer size. Note, this function doesn't do a sliding
+  // window to copy in case the source and destination blocks overlap.
+  // If we wanted to do a sliding window, we could program the server
+  // to generate deltas that effectively did a sliding window.
+
+  uint64_t blocks_to_read = 0;
+  for (int i = 0; i < operation.src_extents_size(); i++)
+    blocks_to_read += operation.src_extents(i).num_blocks();
+
+  uint64_t blocks_to_write = 0;
+  for (int i = 0; i < operation.dst_extents_size(); i++)
+    blocks_to_write += operation.dst_extents(i).num_blocks();
+
+  DCHECK_EQ(blocks_to_write, blocks_to_read);
+  brillo::Blob buf(blocks_to_write * block_size_);
+
+  // Read in bytes.
+  ssize_t bytes_read = 0;
+  for (int i = 0; i < operation.src_extents_size(); i++) {
+    ssize_t bytes_read_this_iteration = 0;
+    const Extent& extent = operation.src_extents(i);
+    const size_t bytes = extent.num_blocks() * block_size_;
+    TEST_AND_RETURN_FALSE(extent.start_block() != kSparseHole);
+    TEST_AND_RETURN_FALSE(utils::PReadAll(target_fd_,
+                                          &buf[bytes_read],
+                                          bytes,
+                                          extent.start_block() * block_size_,
+                                          &bytes_read_this_iteration));
+    TEST_AND_RETURN_FALSE(
+        bytes_read_this_iteration == static_cast<ssize_t>(bytes));
+    bytes_read += bytes_read_this_iteration;
+  }
+
+  // Write bytes out.
+  ssize_t bytes_written = 0;
+  for (int i = 0; i < operation.dst_extents_size(); i++) {
+    const Extent& extent = operation.dst_extents(i);
+    const size_t bytes = extent.num_blocks() * block_size_;
+    TEST_AND_RETURN_FALSE(extent.start_block() != kSparseHole);
+    TEST_AND_RETURN_FALSE(utils::PWriteAll(target_fd_,
+                                           &buf[bytes_written],
+                                           bytes,
+                                           extent.start_block() * block_size_));
+    bytes_written += bytes;
+  }
+  DCHECK_EQ(bytes_written, bytes_read);
+  DCHECK_EQ(bytes_written, static_cast<ssize_t>(buf.size()));
+  return true;
+}
+
+namespace {
+
+// Takes |extents| and fills an empty vector |blocks| with a block index for
+// each block in |extents|. For example, [(3, 2), (8, 1)] would give [3, 4, 8].
+void ExtentsToBlocks(const RepeatedPtrField<Extent>& extents,
+                     vector<uint64_t>* blocks) {
+  for (Extent ext : extents) {
+    for (uint64_t j = 0; j < ext.num_blocks(); j++)
+      blocks->push_back(ext.start_block() + j);
+  }
+}
+
+// Takes |extents| and returns the number of blocks in those extents.
+uint64_t GetBlockCount(const RepeatedPtrField<Extent>& extents) {
+  uint64_t sum = 0;
+  for (Extent ext : extents) {
+    sum += ext.num_blocks();
+  }
+  return sum;
+}
+
+}  // namespace
+
+bool DeltaPerformer::PerformSourceCopyOperation(
+    const InstallOperation& operation) {
+  if (operation.has_src_length())
+    TEST_AND_RETURN_FALSE(operation.src_length() % block_size_ == 0);
+  if (operation.has_dst_length())
+    TEST_AND_RETURN_FALSE(operation.dst_length() % block_size_ == 0);
+
+  uint64_t blocks_to_read = GetBlockCount(operation.src_extents());
+  uint64_t blocks_to_write = GetBlockCount(operation.dst_extents());
+  TEST_AND_RETURN_FALSE(blocks_to_write ==  blocks_to_read);
+
+  // Create vectors of all the individual src/dst blocks.
+  vector<uint64_t> src_blocks;
+  vector<uint64_t> dst_blocks;
+  ExtentsToBlocks(operation.src_extents(), &src_blocks);
+  ExtentsToBlocks(operation.dst_extents(), &dst_blocks);
+  DCHECK_EQ(src_blocks.size(), blocks_to_read);
+  DCHECK_EQ(src_blocks.size(), dst_blocks.size());
+
+  brillo::Blob buf(block_size_);
+  ssize_t bytes_read = 0;
+  // Read/write one block at a time.
+  for (uint64_t i = 0; i < blocks_to_read; i++) {
+    ssize_t bytes_read_this_iteration = 0;
+    uint64_t src_block = src_blocks[i];
+    uint64_t dst_block = dst_blocks[i];
+
+    // Read in bytes.
+    TEST_AND_RETURN_FALSE(
+        utils::PReadAll(source_fd_,
+                        buf.data(),
+                        block_size_,
+                        src_block * block_size_,
+                        &bytes_read_this_iteration));
+
+    // Write bytes out.
+    TEST_AND_RETURN_FALSE(
+        utils::PWriteAll(target_fd_,
+                         buf.data(),
+                         block_size_,
+                         dst_block * block_size_));
+
+    bytes_read += bytes_read_this_iteration;
+    TEST_AND_RETURN_FALSE(bytes_read_this_iteration ==
+                          static_cast<ssize_t>(block_size_));
+  }
+  DCHECK_EQ(bytes_read, static_cast<ssize_t>(blocks_to_read * block_size_));
+  return true;
+}
+
+bool DeltaPerformer::ExtentsToBsdiffPositionsString(
+    const RepeatedPtrField<Extent>& extents,
+    uint64_t block_size,
+    uint64_t full_length,
+    string* positions_string) {
+  string ret;
+  uint64_t length = 0;
+  for (int i = 0; i < extents.size(); i++) {
+    Extent extent = extents.Get(i);
+    int64_t start = extent.start_block() * block_size;
+    uint64_t this_length = min(full_length - length,
+                               extent.num_blocks() * block_size);
+    ret += base::StringPrintf("%" PRIi64 ":%" PRIu64 ",", start, this_length);
+    length += this_length;
+  }
+  TEST_AND_RETURN_FALSE(length == full_length);
+  if (!ret.empty())
+    ret.resize(ret.size() - 1);  // Strip trailing comma off
+  *positions_string = ret;
+  return true;
+}
+
+bool DeltaPerformer::PerformBsdiffOperation(const InstallOperation& operation) {
+  // Since we delete data off the beginning of the buffer as we use it,
+  // the data we need should be exactly at the beginning of the buffer.
+  TEST_AND_RETURN_FALSE(buffer_offset_ == operation.data_offset());
+  TEST_AND_RETURN_FALSE(buffer_.size() >= operation.data_length());
+
+  string input_positions;
+  TEST_AND_RETURN_FALSE(ExtentsToBsdiffPositionsString(operation.src_extents(),
+                                                       block_size_,
+                                                       operation.src_length(),
+                                                       &input_positions));
+  string output_positions;
+  TEST_AND_RETURN_FALSE(ExtentsToBsdiffPositionsString(operation.dst_extents(),
+                                                       block_size_,
+                                                       operation.dst_length(),
+                                                       &output_positions));
+
+  string temp_filename;
+  TEST_AND_RETURN_FALSE(utils::MakeTempFile("au_patch.XXXXXX",
+                                            &temp_filename,
+                                            nullptr));
+  ScopedPathUnlinker path_unlinker(temp_filename);
+  {
+    int fd = open(temp_filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644);
+    ScopedFdCloser fd_closer(&fd);
+    TEST_AND_RETURN_FALSE(
+        utils::WriteAll(fd, buffer_.data(), operation.data_length()));
+  }
+
+  // Update the buffer to release the patch data memory as soon as the patch
+  // file is written out.
+  DiscardBuffer(true, buffer_.size());
+
+  vector<string> cmd{kBspatchPath, target_path_, target_path_, temp_filename,
+                     input_positions, output_positions};
+
+  int return_code = 0;
+  TEST_AND_RETURN_FALSE(
+      Subprocess::SynchronousExecFlags(cmd, Subprocess::kSearchPath,
+                                       &return_code, nullptr));
+  TEST_AND_RETURN_FALSE(return_code == 0);
+
+  if (operation.dst_length() % block_size_) {
+    // Zero out rest of final block.
+    // TODO(adlr): build this into bspatch; it's more efficient that way.
+    const Extent& last_extent =
+        operation.dst_extents(operation.dst_extents_size() - 1);
+    const uint64_t end_byte =
+        (last_extent.start_block() + last_extent.num_blocks()) * block_size_;
+    const uint64_t begin_byte =
+        end_byte - (block_size_ - operation.dst_length() % block_size_);
+    brillo::Blob zeros(end_byte - begin_byte);
+    TEST_AND_RETURN_FALSE(
+        utils::PWriteAll(target_fd_, zeros.data(), end_byte - begin_byte, begin_byte));
+  }
+  return true;
+}
+
+bool DeltaPerformer::PerformSourceBsdiffOperation(
+    const InstallOperation& operation) {
+  // Since we delete data off the beginning of the buffer as we use it,
+  // the data we need should be exactly at the beginning of the buffer.
+  TEST_AND_RETURN_FALSE(buffer_offset_ == operation.data_offset());
+  TEST_AND_RETURN_FALSE(buffer_.size() >= operation.data_length());
+  if (operation.has_src_length())
+    TEST_AND_RETURN_FALSE(operation.src_length() % block_size_ == 0);
+  if (operation.has_dst_length())
+    TEST_AND_RETURN_FALSE(operation.dst_length() % block_size_ == 0);
+
+  string input_positions;
+  TEST_AND_RETURN_FALSE(ExtentsToBsdiffPositionsString(operation.src_extents(),
+                                                       block_size_,
+                                                       operation.src_length(),
+                                                       &input_positions));
+  string output_positions;
+  TEST_AND_RETURN_FALSE(ExtentsToBsdiffPositionsString(operation.dst_extents(),
+                                                       block_size_,
+                                                       operation.dst_length(),
+                                                       &output_positions));
+
+  string temp_filename;
+  TEST_AND_RETURN_FALSE(utils::MakeTempFile("au_patch.XXXXXX",
+                                            &temp_filename,
+                                            nullptr));
+  ScopedPathUnlinker path_unlinker(temp_filename);
+  {
+    int fd = open(temp_filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644);
+    ScopedFdCloser fd_closer(&fd);
+    TEST_AND_RETURN_FALSE(
+        utils::WriteAll(fd, buffer_.data(), operation.data_length()));
+  }
+
+  // Update the buffer to release the patch data memory as soon as the patch
+  // file is written out.
+  DiscardBuffer(true, buffer_.size());
+
+  vector<string> cmd{kBspatchPath, source_path_, target_path_, temp_filename,
+                     input_positions, output_positions};
+
+  int return_code = 0;
+  TEST_AND_RETURN_FALSE(
+      Subprocess::SynchronousExecFlags(cmd, Subprocess::kSearchPath,
+                                       &return_code, nullptr));
+  TEST_AND_RETURN_FALSE(return_code == 0);
+  return true;
+}
+
+bool DeltaPerformer::ExtractSignatureMessageFromOperation(
+    const InstallOperation& operation) {
+  if (operation.type() != InstallOperation::REPLACE ||
+      !manifest_.has_signatures_offset() ||
+      manifest_.signatures_offset() != operation.data_offset()) {
+    return false;
+  }
+  TEST_AND_RETURN_FALSE(manifest_.has_signatures_size() &&
+                        manifest_.signatures_size() == operation.data_length());
+  TEST_AND_RETURN_FALSE(ExtractSignatureMessage());
+  return true;
+}
+
+bool DeltaPerformer::ExtractSignatureMessage() {
+  TEST_AND_RETURN_FALSE(signatures_message_data_.empty());
+  TEST_AND_RETURN_FALSE(buffer_offset_ == manifest_.signatures_offset());
+  TEST_AND_RETURN_FALSE(buffer_.size() >= manifest_.signatures_size());
+  signatures_message_data_.assign(
+      buffer_.begin(),
+      buffer_.begin() + manifest_.signatures_size());
+
+  // Save the signature blob because if the update is interrupted after the
+  // download phase we don't go through this path anymore. Some alternatives to
+  // consider:
+  //
+  // 1. On resume, re-download the signature blob from the server and re-verify
+  // it.
+  //
+  // 2. Verify the signature as soon as it's received and don't checkpoint the
+  // blob and the signed sha-256 context.
+  LOG_IF(WARNING, !prefs_->SetString(kPrefsUpdateStateSignatureBlob,
+                                     string(signatures_message_data_.begin(),
+                                            signatures_message_data_.end())))
+      << "Unable to store the signature blob.";
+
+  LOG(INFO) << "Extracted signature data of size "
+            << manifest_.signatures_size() << " at "
+            << manifest_.signatures_offset();
+  return true;
+}
+
+bool DeltaPerformer::GetPublicKeyFromResponse(base::FilePath *out_tmp_key) {
+  if (system_state_->hardware()->IsOfficialBuild() ||
+      utils::FileExists(public_key_path_.c_str()) ||
+      install_plan_->public_key_rsa.empty())
+    return false;
+
+  if (!utils::DecodeAndStoreBase64String(install_plan_->public_key_rsa,
+                                         out_tmp_key))
+    return false;
+
+  return true;
+}
+
+ErrorCode DeltaPerformer::ValidateMetadataSignature(
+    const brillo::Blob& payload) {
+  if (payload.size() < metadata_size_ + metadata_signature_size_)
+    return ErrorCode::kDownloadMetadataSignatureError;
+
+  brillo::Blob metadata_signature_blob, metadata_signature_protobuf_blob;
+  if (!install_plan_->metadata_signature.empty()) {
+    // Convert base64-encoded signature to raw bytes.
+    if (!brillo::data_encoding::Base64Decode(
+        install_plan_->metadata_signature, &metadata_signature_blob)) {
+      LOG(ERROR) << "Unable to decode base64 metadata signature: "
+                 << install_plan_->metadata_signature;
+      return ErrorCode::kDownloadMetadataSignatureError;
+    }
+  } else if (major_payload_version_ == kBrilloMajorPayloadVersion) {
+    metadata_signature_protobuf_blob.assign(payload.begin() + metadata_size_,
+                                            payload.begin() + metadata_size_ +
+                                            metadata_signature_size_);
+  }
+
+  if (metadata_signature_blob.empty() &&
+      metadata_signature_protobuf_blob.empty()) {
+    if (install_plan_->hash_checks_mandatory) {
+      LOG(ERROR) << "Missing mandatory metadata signature in both Omaha "
+                 << "response and payload.";
+      return ErrorCode::kDownloadMetadataSignatureMissingError;
+    }
+
+    LOG(WARNING) << "Cannot validate metadata as the signature is empty";
+    return ErrorCode::kSuccess;
+  }
+
+  // See if we should use the public RSA key in the Omaha response.
+  base::FilePath path_to_public_key(public_key_path_);
+  base::FilePath tmp_key;
+  if (GetPublicKeyFromResponse(&tmp_key))
+    path_to_public_key = tmp_key;
+  ScopedPathUnlinker tmp_key_remover(tmp_key.value());
+  if (tmp_key.empty())
+    tmp_key_remover.set_should_remove(false);
+
+  LOG(INFO) << "Verifying metadata hash signature using public key: "
+            << path_to_public_key.value();
+
+  HashCalculator metadata_hasher;
+  metadata_hasher.Update(payload.data(), metadata_size_);
+  if (!metadata_hasher.Finalize()) {
+    LOG(ERROR) << "Unable to compute actual hash of manifest";
+    return ErrorCode::kDownloadMetadataSignatureVerificationError;
+  }
+
+  brillo::Blob calculated_metadata_hash = metadata_hasher.raw_hash();
+  PayloadVerifier::PadRSA2048SHA256Hash(&calculated_metadata_hash);
+  if (calculated_metadata_hash.empty()) {
+    LOG(ERROR) << "Computed actual hash of metadata is empty.";
+    return ErrorCode::kDownloadMetadataSignatureVerificationError;
+  }
+
+  if (!metadata_signature_blob.empty()) {
+    brillo::Blob expected_metadata_hash;
+    if (!PayloadVerifier::GetRawHashFromSignature(metadata_signature_blob,
+                                                  path_to_public_key.value(),
+                                                  &expected_metadata_hash)) {
+      LOG(ERROR) << "Unable to compute expected hash from metadata signature";
+      return ErrorCode::kDownloadMetadataSignatureError;
+    }
+    if (calculated_metadata_hash != expected_metadata_hash) {
+      LOG(ERROR) << "Manifest hash verification failed. Expected hash = ";
+      utils::HexDumpVector(expected_metadata_hash);
+      LOG(ERROR) << "Calculated hash = ";
+      utils::HexDumpVector(calculated_metadata_hash);
+      return ErrorCode::kDownloadMetadataSignatureMismatch;
+    }
+  } else {
+    if (!PayloadVerifier::VerifySignature(metadata_signature_protobuf_blob,
+                                          path_to_public_key.value(),
+                                          calculated_metadata_hash)) {
+      LOG(ERROR) << "Manifest hash verification failed.";
+      return ErrorCode::kDownloadMetadataSignatureMismatch;
+    }
+  }
+
+  // The autoupdate_CatchBadSignatures test checks for this string in
+  // log-files. Keep in sync.
+  LOG(INFO) << "Metadata hash signature matches value in Omaha response.";
+  return ErrorCode::kSuccess;
+}
+
+ErrorCode DeltaPerformer::ValidateManifest() {
+  // Perform assorted checks to sanity check the manifest, make sure it
+  // matches data from other sources, and that it is a supported version.
+  //
+  // TODO(garnold) in general, the presence of an old partition hash should be
+  // the sole indicator for a delta update, as we would generally like update
+  // payloads to be self contained and not assume an Omaha response to tell us
+  // that. However, since this requires some massive reengineering of the update
+  // flow (making filesystem copying happen conditionally only *after*
+  // downloading and parsing of the update manifest) we'll put it off for now.
+  // See chromium-os:7597 for further discussion.
+  if (install_plan_->is_full_update) {
+    if (manifest_.has_old_kernel_info() || manifest_.has_old_rootfs_info()) {
+      LOG(ERROR) << "Purported full payload contains old partition "
+                    "hash(es), aborting update";
+      return ErrorCode::kPayloadMismatchedType;
+    }
+
+    for (const PartitionUpdate& partition : manifest_.partitions()) {
+      if (partition.has_old_partition_info()) {
+        LOG(ERROR) << "Purported full payload contains old partition "
+                      "hash(es), aborting update";
+        return ErrorCode::kPayloadMismatchedType;
+      }
+    }
+
+    if (manifest_.minor_version() != kFullPayloadMinorVersion) {
+      LOG(ERROR) << "Manifest contains minor version "
+                 << manifest_.minor_version()
+                 << ", but all full payloads should have version "
+                 << kFullPayloadMinorVersion << ".";
+      return ErrorCode::kUnsupportedMinorPayloadVersion;
+    }
+  } else {
+    if (manifest_.minor_version() != supported_minor_version_) {
+      LOG(ERROR) << "Manifest contains minor version "
+                 << manifest_.minor_version()
+                 << " not the supported "
+                 << supported_minor_version_;
+      return ErrorCode::kUnsupportedMinorPayloadVersion;
+    }
+  }
+
+  if (major_payload_version_ != kChromeOSMajorPayloadVersion) {
+    if (manifest_.has_old_rootfs_info() ||
+        manifest_.has_new_rootfs_info() ||
+        manifest_.has_old_kernel_info() ||
+        manifest_.has_new_kernel_info() ||
+        manifest_.install_operations_size() != 0 ||
+        manifest_.kernel_install_operations_size() != 0) {
+      LOG(ERROR) << "Manifest contains deprecated field only supported in "
+                 << "major payload version 1, but the payload major version is "
+                 << major_payload_version_;
+      return ErrorCode::kPayloadMismatchedType;
+    }
+  }
+
+  // TODO(garnold) we should be adding more and more manifest checks, such as
+  // partition boundaries etc (see chromium-os:37661).
+
+  return ErrorCode::kSuccess;
+}
+
+ErrorCode DeltaPerformer::ValidateOperationHash(
+    const InstallOperation& operation) {
+  if (!operation.data_sha256_hash().size()) {
+    if (!operation.data_length()) {
+      // Operations that do not have any data blob won't have any operation hash
+      // either. So, these operations are always considered validated since the
+      // metadata that contains all the non-data-blob portions of the operation
+      // has already been validated. This is true for both HTTP and HTTPS cases.
+      return ErrorCode::kSuccess;
+    }
+
+    // No hash is present for an operation that has data blobs. This shouldn't
+    // happen normally for any client that has this code, because the
+    // corresponding update should have been produced with the operation
+    // hashes. So if it happens it means either we've turned operation hash
+    // generation off in DeltaDiffGenerator or it's a regression of some sort.
+    // One caveat though: The last operation is a dummy signature operation
+    // that doesn't have a hash at the time the manifest is created. So we
+    // should not complaint about that operation. This operation can be
+    // recognized by the fact that it's offset is mentioned in the manifest.
+    if (manifest_.signatures_offset() &&
+        manifest_.signatures_offset() == operation.data_offset()) {
+      LOG(INFO) << "Skipping hash verification for signature operation "
+                << next_operation_num_ + 1;
+    } else {
+      if (install_plan_->hash_checks_mandatory) {
+        LOG(ERROR) << "Missing mandatory operation hash for operation "
+                   << next_operation_num_ + 1;
+        return ErrorCode::kDownloadOperationHashMissingError;
+      }
+
+      LOG(WARNING) << "Cannot validate operation " << next_operation_num_ + 1
+                   << " as there's no operation hash in manifest";
+    }
+    return ErrorCode::kSuccess;
+  }
+
+  brillo::Blob expected_op_hash;
+  expected_op_hash.assign(operation.data_sha256_hash().data(),
+                          (operation.data_sha256_hash().data() +
+                           operation.data_sha256_hash().size()));
+
+  HashCalculator operation_hasher;
+  operation_hasher.Update(buffer_.data(), operation.data_length());
+  if (!operation_hasher.Finalize()) {
+    LOG(ERROR) << "Unable to compute actual hash of operation "
+               << next_operation_num_;
+    return ErrorCode::kDownloadOperationHashVerificationError;
+  }
+
+  brillo::Blob calculated_op_hash = operation_hasher.raw_hash();
+  if (calculated_op_hash != expected_op_hash) {
+    LOG(ERROR) << "Hash verification failed for operation "
+               << next_operation_num_ << ". Expected hash = ";
+    utils::HexDumpVector(expected_op_hash);
+    LOG(ERROR) << "Calculated hash over " << operation.data_length()
+               << " bytes at offset: " << operation.data_offset() << " = ";
+    utils::HexDumpVector(calculated_op_hash);
+    return ErrorCode::kDownloadOperationHashMismatch;
+  }
+
+  return ErrorCode::kSuccess;
+}
+
+#define TEST_AND_RETURN_VAL(_retval, _condition)                \
+  do {                                                          \
+    if (!(_condition)) {                                        \
+      LOG(ERROR) << "VerifyPayload failure: " << #_condition;   \
+      return _retval;                                           \
+    }                                                           \
+  } while (0);
+
+ErrorCode DeltaPerformer::VerifyPayload(
+    const string& update_check_response_hash,
+    const uint64_t update_check_response_size) {
+
+  // See if we should use the public RSA key in the Omaha response.
+  base::FilePath path_to_public_key(public_key_path_);
+  base::FilePath tmp_key;
+  if (GetPublicKeyFromResponse(&tmp_key))
+    path_to_public_key = tmp_key;
+  ScopedPathUnlinker tmp_key_remover(tmp_key.value());
+  if (tmp_key.empty())
+    tmp_key_remover.set_should_remove(false);
+
+  LOG(INFO) << "Verifying payload using public key: "
+            << path_to_public_key.value();
+
+  // Verifies the download size.
+  TEST_AND_RETURN_VAL(ErrorCode::kPayloadSizeMismatchError,
+                      update_check_response_size ==
+                      metadata_size_ + metadata_signature_size_ +
+                      buffer_offset_);
+
+  // Verifies the payload hash.
+  const string& payload_hash_data = payload_hash_calculator_.hash();
+  TEST_AND_RETURN_VAL(ErrorCode::kDownloadPayloadVerificationError,
+                      !payload_hash_data.empty());
+  TEST_AND_RETURN_VAL(ErrorCode::kPayloadHashMismatchError,
+                      payload_hash_data == update_check_response_hash);
+
+  // Verifies the signed payload hash.
+  if (!utils::FileExists(path_to_public_key.value().c_str())) {
+    LOG(WARNING) << "Not verifying signed delta payload -- missing public key.";
+    return ErrorCode::kSuccess;
+  }
+  TEST_AND_RETURN_VAL(ErrorCode::kSignedDeltaPayloadExpectedError,
+                      !signatures_message_data_.empty());
+  brillo::Blob hash_data = signed_hash_calculator_.raw_hash();
+  TEST_AND_RETURN_VAL(ErrorCode::kDownloadPayloadPubKeyVerificationError,
+                      PayloadVerifier::PadRSA2048SHA256Hash(&hash_data));
+  TEST_AND_RETURN_VAL(ErrorCode::kDownloadPayloadPubKeyVerificationError,
+                      !hash_data.empty());
+
+  if (!PayloadVerifier::VerifySignature(
+      signatures_message_data_, path_to_public_key.value(), hash_data)) {
+    // The autoupdate_CatchBadSignatures test checks for this string
+    // in log-files. Keep in sync.
+    LOG(ERROR) << "Public key verification failed, thus update failed.";
+    return ErrorCode::kDownloadPayloadPubKeyVerificationError;
+  }
+
+  LOG(INFO) << "Payload hash matches value in payload.";
+
+  // At this point, we are guaranteed to have downloaded a full payload, i.e
+  // the one whose size matches the size mentioned in Omaha response. If any
+  // errors happen after this, it's likely a problem with the payload itself or
+  // the state of the system and not a problem with the URL or network.  So,
+  // indicate that to the payload state so that AU can backoff appropriately.
+  system_state_->payload_state()->DownloadComplete();
+
+  return ErrorCode::kSuccess;
+}
+
+namespace {
+void LogVerifyError(const string& type,
+                    const string& device,
+                    uint64_t size,
+                    const string& local_hash,
+                    const string& expected_hash) {
+  LOG(ERROR) << "This is a server-side error due to "
+             << "mismatched delta update image!";
+  LOG(ERROR) << "The delta I've been given contains a " << type << " delta "
+             << "update that must be applied over a " << type << " with "
+             << "a specific checksum, but the " << type << " we're starting "
+             << "with doesn't have that checksum! This means that "
+             << "the delta I've been given doesn't match my existing "
+             << "system. The " << type << " partition I have has hash: "
+             << local_hash << " but the update expected me to have "
+             << expected_hash << " .";
+  LOG(INFO) << "To get the checksum of the " << type << " partition run this"
+               "command: dd if=" << device << " bs=1M count=" << size
+            << " iflag=count_bytes 2>/dev/null | openssl dgst -sha256 -binary "
+               "| openssl base64";
+  LOG(INFO) << "To get the checksum of partitions in a bin file, "
+            << "run: .../src/scripts/sha256_partitions.sh .../file.bin";
+}
+
+string StringForHashBytes(const void* bytes, size_t size) {
+  return brillo::data_encoding::Base64Encode(bytes, size);
+}
+}  // namespace
+
+bool DeltaPerformer::VerifySourcePartitions() {
+  LOG(INFO) << "Verifying source partitions.";
+  CHECK(manifest_valid_);
+  CHECK(install_plan_);
+  if (install_plan_->partitions.size() != partitions_.size()) {
+    DLOG(ERROR) << "The list of partitions in the InstallPlan doesn't match the "
+                   "list received in the payload. The InstallPlan has "
+                << install_plan_->partitions.size()
+                << " partitions while the payload has " << partitions_.size()
+                << " partitions.";
+    return false;
+  }
+  for (size_t i = 0; i < partitions_.size(); ++i) {
+    if (partitions_[i].partition_name() != install_plan_->partitions[i].name) {
+      DLOG(ERROR) << "The InstallPlan's partition " << i << " is \""
+                  << install_plan_->partitions[i].name
+                  << "\" but the payload expects it to be \""
+                  << partitions_[i].partition_name()
+                  << "\". This is an error in the DeltaPerformer setup.";
+      return false;
+    }
+    if (!partitions_[i].has_old_partition_info())
+      continue;
+    const PartitionInfo& info = partitions_[i].old_partition_info();
+    const InstallPlan::Partition& plan_part = install_plan_->partitions[i];
+    bool valid =
+        !plan_part.source_hash.empty() &&
+        plan_part.source_hash.size() == info.hash().size() &&
+        memcmp(plan_part.source_hash.data(),
+               info.hash().data(),
+               plan_part.source_hash.size()) == 0;
+    if (!valid) {
+      LogVerifyError(partitions_[i].partition_name(),
+                     plan_part.source_path,
+                     info.hash().size(),
+                     StringForHashBytes(plan_part.source_hash.data(),
+                                        plan_part.source_hash.size()),
+                     StringForHashBytes(info.hash().data(),
+                                        info.hash().size()));
+      return false;
+    }
+  }
+  return true;
+}
+
+void DeltaPerformer::DiscardBuffer(bool do_advance_offset,
+                                   size_t signed_hash_buffer_size) {
+  // Update the buffer offset.
+  if (do_advance_offset)
+    buffer_offset_ += buffer_.size();
+
+  // Hash the content.
+  payload_hash_calculator_.Update(buffer_.data(), buffer_.size());
+  signed_hash_calculator_.Update(buffer_.data(), signed_hash_buffer_size);
+
+  // Swap content with an empty vector to ensure that all memory is released.
+  brillo::Blob().swap(buffer_);
+}
+
+bool DeltaPerformer::CanResumeUpdate(PrefsInterface* prefs,
+                                     string update_check_response_hash) {
+  int64_t next_operation = kUpdateStateOperationInvalid;
+  if (!(prefs->GetInt64(kPrefsUpdateStateNextOperation, &next_operation) &&
+        next_operation != kUpdateStateOperationInvalid &&
+        next_operation > 0))
+    return false;
+
+  string interrupted_hash;
+  if (!(prefs->GetString(kPrefsUpdateCheckResponseHash, &interrupted_hash) &&
+        !interrupted_hash.empty() &&
+        interrupted_hash == update_check_response_hash))
+    return false;
+
+  int64_t resumed_update_failures;
+  if (!(prefs->GetInt64(kPrefsResumedUpdateFailures, &resumed_update_failures)
+        && resumed_update_failures > kMaxResumedUpdateFailures))
+    return false;
+
+  // Sanity check the rest.
+  int64_t next_data_offset = -1;
+  if (!(prefs->GetInt64(kPrefsUpdateStateNextDataOffset, &next_data_offset) &&
+        next_data_offset >= 0))
+    return false;
+
+  string sha256_context;
+  if (!(prefs->GetString(kPrefsUpdateStateSHA256Context, &sha256_context) &&
+        !sha256_context.empty()))
+    return false;
+
+  int64_t manifest_metadata_size = 0;
+  if (!(prefs->GetInt64(kPrefsManifestMetadataSize, &manifest_metadata_size) &&
+        manifest_metadata_size > 0))
+    return false;
+
+  return true;
+}
+
+bool DeltaPerformer::ResetUpdateProgress(PrefsInterface* prefs, bool quick) {
+  TEST_AND_RETURN_FALSE(prefs->SetInt64(kPrefsUpdateStateNextOperation,
+                                        kUpdateStateOperationInvalid));
+  if (!quick) {
+    prefs->SetString(kPrefsUpdateCheckResponseHash, "");
+    prefs->SetInt64(kPrefsUpdateStateNextDataOffset, -1);
+    prefs->SetInt64(kPrefsUpdateStateNextDataLength, 0);
+    prefs->SetString(kPrefsUpdateStateSHA256Context, "");
+    prefs->SetString(kPrefsUpdateStateSignedSHA256Context, "");
+    prefs->SetString(kPrefsUpdateStateSignatureBlob, "");
+    prefs->SetInt64(kPrefsManifestMetadataSize, -1);
+    prefs->SetInt64(kPrefsResumedUpdateFailures, 0);
+  }
+  return true;
+}
+
+bool DeltaPerformer::CheckpointUpdateProgress() {
+  Terminator::set_exit_blocked(true);
+  if (last_updated_buffer_offset_ != buffer_offset_) {
+    // Resets the progress in case we die in the middle of the state update.
+    ResetUpdateProgress(prefs_, true);
+    TEST_AND_RETURN_FALSE(
+        prefs_->SetString(kPrefsUpdateStateSHA256Context,
+                          payload_hash_calculator_.GetContext()));
+    TEST_AND_RETURN_FALSE(
+        prefs_->SetString(kPrefsUpdateStateSignedSHA256Context,
+                          signed_hash_calculator_.GetContext()));
+    TEST_AND_RETURN_FALSE(prefs_->SetInt64(kPrefsUpdateStateNextDataOffset,
+                                           buffer_offset_));
+    last_updated_buffer_offset_ = buffer_offset_;
+
+    if (next_operation_num_ < num_total_operations_) {
+      size_t partition_index = current_partition_;
+      while (next_operation_num_ >= acc_num_operations_[partition_index])
+        partition_index++;
+      const size_t partition_operation_num = next_operation_num_ - (
+          partition_index ? acc_num_operations_[partition_index - 1] : 0);
+      const InstallOperation& op =
+          partitions_[partition_index].operations(partition_operation_num);
+      TEST_AND_RETURN_FALSE(prefs_->SetInt64(kPrefsUpdateStateNextDataLength,
+                                             op.data_length()));
+    } else {
+      TEST_AND_RETURN_FALSE(prefs_->SetInt64(kPrefsUpdateStateNextDataLength,
+                                             0));
+    }
+  }
+  TEST_AND_RETURN_FALSE(prefs_->SetInt64(kPrefsUpdateStateNextOperation,
+                                         next_operation_num_));
+  return true;
+}
+
+bool DeltaPerformer::PrimeUpdateState() {
+  CHECK(manifest_valid_);
+  block_size_ = manifest_.block_size();
+
+  int64_t next_operation = kUpdateStateOperationInvalid;
+  if (!prefs_->GetInt64(kPrefsUpdateStateNextOperation, &next_operation) ||
+      next_operation == kUpdateStateOperationInvalid ||
+      next_operation <= 0) {
+    // Initiating a new update, no more state needs to be initialized.
+    return true;
+  }
+  next_operation_num_ = next_operation;
+
+  // Resuming an update -- load the rest of the update state.
+  int64_t next_data_offset = -1;
+  TEST_AND_RETURN_FALSE(prefs_->GetInt64(kPrefsUpdateStateNextDataOffset,
+                                         &next_data_offset) &&
+                        next_data_offset >= 0);
+  buffer_offset_ = next_data_offset;
+
+  // The signed hash context and the signature blob may be empty if the
+  // interrupted update didn't reach the signature.
+  string signed_hash_context;
+  if (prefs_->GetString(kPrefsUpdateStateSignedSHA256Context,
+                        &signed_hash_context)) {
+    TEST_AND_RETURN_FALSE(
+        signed_hash_calculator_.SetContext(signed_hash_context));
+  }
+
+  string signature_blob;
+  if (prefs_->GetString(kPrefsUpdateStateSignatureBlob, &signature_blob)) {
+    signatures_message_data_.assign(signature_blob.begin(),
+                                    signature_blob.end());
+  }
+
+  string hash_context;
+  TEST_AND_RETURN_FALSE(prefs_->GetString(kPrefsUpdateStateSHA256Context,
+                                          &hash_context) &&
+                        payload_hash_calculator_.SetContext(hash_context));
+
+  int64_t manifest_metadata_size = 0;
+  TEST_AND_RETURN_FALSE(prefs_->GetInt64(kPrefsManifestMetadataSize,
+                                         &manifest_metadata_size) &&
+                        manifest_metadata_size > 0);
+  metadata_size_ = manifest_metadata_size;
+
+  // Advance the download progress to reflect what doesn't need to be
+  // re-downloaded.
+  total_bytes_received_ += buffer_offset_;
+
+  // Speculatively count the resume as a failure.
+  int64_t resumed_update_failures;
+  if (prefs_->GetInt64(kPrefsResumedUpdateFailures, &resumed_update_failures)) {
+    resumed_update_failures++;
+  } else {
+    resumed_update_failures = 1;
+  }
+  prefs_->SetInt64(kPrefsResumedUpdateFailures, resumed_update_failures);
+  return true;
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/delta_performer.h b/payload_consumer/delta_performer.h
new file mode 100644
index 0000000..db938c1
--- /dev/null
+++ b/payload_consumer/delta_performer.h
@@ -0,0 +1,396 @@
+//
+// Copyright (C) 2010 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.
+//
+
+#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_DELTA_PERFORMER_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_DELTA_PERFORMER_H_
+
+#include <inttypes.h>
+
+#include <string>
+#include <vector>
+
+#include <base/time/time.h>
+#include <brillo/secure_blob.h>
+#include <google/protobuf/repeated_field.h>
+#include <gtest/gtest_prod.h>  // for FRIEND_TEST
+
+#include "update_engine/common/hash_calculator.h"
+#include "update_engine/common/platform_constants.h"
+#include "update_engine/payload_consumer/file_descriptor.h"
+#include "update_engine/payload_consumer/file_writer.h"
+#include "update_engine/payload_consumer/install_plan.h"
+#include "update_engine/system_state.h"
+#include "update_engine/update_metadata.pb.h"
+
+namespace chromeos_update_engine {
+
+class PrefsInterface;
+
+// This class performs the actions in a delta update synchronously. The delta
+// update itself should be passed in in chunks as it is received.
+
+class DeltaPerformer : public FileWriter {
+ public:
+  enum MetadataParseResult {
+    kMetadataParseSuccess,
+    kMetadataParseError,
+    kMetadataParseInsufficientData,
+  };
+
+  static const uint64_t kDeltaVersionOffset;
+  static const uint64_t kDeltaVersionSize;
+  static const uint64_t kDeltaManifestSizeOffset;
+  static const uint64_t kDeltaManifestSizeSize;
+  static const uint64_t kDeltaMetadataSignatureSizeSize;
+  static const uint64_t kMaxPayloadHeaderSize;
+  static const uint64_t kSupportedMajorPayloadVersion;
+  static const uint32_t kSupportedMinorPayloadVersion;
+
+  // Defines the granularity of progress logging in terms of how many "completed
+  // chunks" we want to report at the most.
+  static const unsigned kProgressLogMaxChunks;
+  // Defines a timeout since the last progress was logged after which we want to
+  // force another log message (even if the current chunk was not completed).
+  static const unsigned kProgressLogTimeoutSeconds;
+  // These define the relative weights (0-100) we give to the different work
+  // components associated with an update when computing an overall progress.
+  // Currently they include the download progress and the number of completed
+  // operations. They must add up to one hundred (100).
+  static const unsigned kProgressDownloadWeight;
+  static const unsigned kProgressOperationsWeight;
+
+  DeltaPerformer(PrefsInterface* prefs,
+                 SystemState* system_state,
+                 InstallPlan* install_plan)
+      : prefs_(prefs),
+        system_state_(system_state),
+        install_plan_(install_plan) {}
+
+  // FileWriter's Write implementation where caller doesn't care about
+  // error codes.
+  bool Write(const void* bytes, size_t count) override {
+    ErrorCode error;
+    return Write(bytes, count, &error);
+  }
+
+  // FileWriter's Write implementation that returns a more specific |error| code
+  // in case of failures in Write operation.
+  bool Write(const void* bytes, size_t count, ErrorCode *error) override;
+
+  // Wrapper around close. Returns 0 on success or -errno on error.
+  // Closes both 'path' given to Open() and the kernel path.
+  int Close() override;
+
+  // Open the target and source (if delta payload) file descriptors for the
+  // |current_partition_|. The manifest needs to be already parsed for this to
+  // work. Returns whether the required file descriptors were successfully open.
+  bool OpenCurrentPartition();
+
+  // Closes the current partition file descriptors if open. Returns 0 on success
+  // or -errno on error.
+  int CloseCurrentPartition();
+
+  // Returns |true| only if the manifest has been processed and it's valid.
+  bool IsManifestValid();
+
+  // Verifies the downloaded payload against the signed hash included in the
+  // payload, against the update check hash (which is in base64 format)  and
+  // size using the public key and returns ErrorCode::kSuccess on success, an
+  // error code on failure.  This method should be called after closing the
+  // stream. Note this method skips the signed hash check if the public key is
+  // unavailable; it returns ErrorCode::kSignedDeltaPayloadExpectedError if the
+  // public key is available but the delta payload doesn't include a signature.
+  ErrorCode VerifyPayload(const std::string& update_check_response_hash,
+                          const uint64_t update_check_response_size);
+
+  // Converts an ordered collection of Extent objects which contain data of
+  // length full_length to a comma-separated string. For each Extent, the
+  // string will have the start offset and then the length in bytes.
+  // The length value of the last extent in the string may be short, since
+  // the full length of all extents in the string is capped to full_length.
+  // Also, an extent starting at kSparseHole, appears as -1 in the string.
+  // For example, if the Extents are {1, 1}, {4, 2}, {kSparseHole, 1},
+  // {0, 1}, block_size is 4096, and full_length is 5 * block_size - 13,
+  // the resulting string will be: "4096:4096,16384:8192,-1:4096,0:4083"
+  static bool ExtentsToBsdiffPositionsString(
+      const google::protobuf::RepeatedPtrField<Extent>& extents,
+      uint64_t block_size,
+      uint64_t full_length,
+      std::string* positions_string);
+
+  // Returns true if a previous update attempt can be continued based on the
+  // persistent preferences and the new update check response hash.
+  static bool CanResumeUpdate(PrefsInterface* prefs,
+                              std::string update_check_response_hash);
+
+  // Resets the persistent update progress state to indicate that an update
+  // can't be resumed. Performs a quick update-in-progress reset if |quick| is
+  // true, otherwise resets all progress-related update state. Returns true on
+  // success, false otherwise.
+  static bool ResetUpdateProgress(PrefsInterface* prefs, bool quick);
+
+  // Attempts to parse the update metadata starting from the beginning of
+  // |payload|. On success, returns kMetadataParseSuccess. Returns
+  // kMetadataParseInsufficientData if more data is needed to parse the complete
+  // metadata. Returns kMetadataParseError if the metadata can't be parsed given
+  // the payload.
+  MetadataParseResult ParsePayloadMetadata(const brillo::Blob& payload,
+                                           ErrorCode* error);
+
+  void set_public_key_path(const std::string& public_key_path) {
+    public_key_path_ = public_key_path;
+  }
+
+  // Set |*out_offset| to the byte offset where the size of the metadata signature
+  // is stored in a payload. Return true on success, if this field is not
+  // present in the payload, return false.
+  bool GetMetadataSignatureSizeOffset(uint64_t* out_offset) const;
+
+  // Set |*out_offset| to the byte offset at which the manifest protobuf begins
+  // in a payload. Return true on success, false if the offset is unknown.
+  bool GetManifestOffset(uint64_t* out_offset) const;
+
+  // Returns the size of the payload metadata, which includes the payload header
+  // and the manifest. If the header was not yet parsed, returns zero.
+  uint64_t GetMetadataSize() const;
+
+  // If the manifest was successfully parsed, copies it to |*out_manifest_p|.
+  // Returns true on success.
+  bool GetManifest(DeltaArchiveManifest* out_manifest_p) const;
+
+  // Return true if header parsing is finished and no errors occurred.
+  bool IsHeaderParsed() const;
+
+  // Returns the major payload version. If the version was not yet parsed,
+  // returns zero.
+  uint64_t GetMajorVersion() const;
+
+  // Returns the delta minor version. If this value is defined in the manifest,
+  // it returns that value, otherwise it returns the default value.
+  uint32_t GetMinorVersion() const;
+
+ private:
+  friend class DeltaPerformerTest;
+  friend class DeltaPerformerIntegrationTest;
+  FRIEND_TEST(DeltaPerformerTest, BrilloMetadataSignatureSizeTest);
+  FRIEND_TEST(DeltaPerformerTest, BrilloVerifyMetadataSignatureTest);
+  FRIEND_TEST(DeltaPerformerTest, UsePublicKeyFromResponse);
+
+  // Parse and move the update instructions of all partitions into our local
+  // |partitions_| variable based on the version of the payload. Requires the
+  // manifest to be parsed and valid.
+  bool ParseManifestPartitions(ErrorCode* error);
+
+  // Appends up to |*count_p| bytes from |*bytes_p| to |buffer_|, but only to
+  // the extent that the size of |buffer_| does not exceed |max|. Advances
+  // |*cbytes_p| and decreases |*count_p| by the actual number of bytes copied,
+  // and returns this number.
+  size_t CopyDataToBuffer(const char** bytes_p, size_t* count_p, size_t max);
+
+  // If |op_result| is false, emits an error message using |op_type_name| and
+  // sets |*error| accordingly. Otherwise does nothing. Returns |op_result|.
+  bool HandleOpResult(bool op_result, const char* op_type_name,
+                      ErrorCode* error);
+
+  // Logs the progress of downloading/applying an update.
+  void LogProgress(const char* message_prefix);
+
+  // Update overall progress metrics, log as necessary.
+  void UpdateOverallProgress(bool force_log, const char* message_prefix);
+
+  // Verifies that the expected source partition hashes (if present) match the
+  // hashes for the current partitions. Returns true if there are no expected
+  // hashes in the payload (e.g., if it's a new-style full update) or if the
+  // hashes match; returns false otherwise.
+  bool VerifySourcePartitions();
+
+  // Returns true if enough of the delta file has been passed via Write()
+  // to be able to perform a given install operation.
+  bool CanPerformInstallOperation(const InstallOperation& operation);
+
+  // Checks the integrity of the payload manifest. Returns true upon success,
+  // false otherwise.
+  ErrorCode ValidateManifest();
+
+  // Validates that the hash of the blobs corresponding to the given |operation|
+  // matches what's specified in the manifest in the payload.
+  // Returns ErrorCode::kSuccess on match or a suitable error code otherwise.
+  ErrorCode ValidateOperationHash(const InstallOperation& operation);
+
+  // Given the |payload|, verifies that the signed hash of its metadata matches
+  // what's specified in the install plan from Omaha (if present) or the
+  // metadata signature in payload itself (if present). Returns
+  // ErrorCode::kSuccess on match or a suitable error code otherwise. This
+  // method must be called before any part of the metadata is parsed so that a
+  // man-in-the-middle attack on the SSL connection to the payload server
+  // doesn't exploit any vulnerability in the code that parses the protocol
+  // buffer.
+  ErrorCode ValidateMetadataSignature(const brillo::Blob& payload);
+
+  // Returns true on success.
+  bool PerformInstallOperation(const InstallOperation& operation);
+
+  // These perform a specific type of operation and return true on success.
+  bool PerformReplaceOperation(const InstallOperation& operation);
+  bool PerformZeroOrDiscardOperation(const InstallOperation& operation);
+  bool PerformMoveOperation(const InstallOperation& operation);
+  bool PerformBsdiffOperation(const InstallOperation& operation);
+  bool PerformSourceCopyOperation(const InstallOperation& operation);
+  bool PerformSourceBsdiffOperation(const InstallOperation& operation);
+
+  // Extracts the payload signature message from the blob on the |operation| if
+  // the offset matches the one specified by the manifest. Returns whether the
+  // signature was extracted.
+  bool ExtractSignatureMessageFromOperation(const InstallOperation& operation);
+
+  // Extracts the payload signature message from the current |buffer_| if the
+  // offset matches the one specified by the manifest. Returns whether the
+  // signature was extracted.
+  bool ExtractSignatureMessage();
+
+  // Updates the payload hash calculator with the bytes in |buffer_|, also
+  // updates the signed hash calculator with the first |signed_hash_buffer_size|
+  // bytes in |buffer_|. Then discard the content, ensuring that memory is being
+  // deallocated. If |do_advance_offset|, advances the internal offset counter
+  // accordingly.
+  void DiscardBuffer(bool do_advance_offset, size_t signed_hash_buffer_size);
+
+  // Checkpoints the update progress into persistent storage to allow this
+  // update attempt to be resumed after reboot.
+  bool CheckpointUpdateProgress();
+
+  // Primes the required update state. Returns true if the update state was
+  // successfully initialized to a saved resume state or if the update is a new
+  // update. Returns false otherwise.
+  bool PrimeUpdateState();
+
+  // If the Omaha response contains a public RSA key and we're allowed
+  // to use it (e.g. if we're in developer mode), extract the key from
+  // the response and store it in a temporary file and return true. In
+  // the affirmative the path to the temporary file is stored in
+  // |out_tmp_key| and it is the responsibility of the caller to clean
+  // it up.
+  bool GetPublicKeyFromResponse(base::FilePath *out_tmp_key);
+
+  // Update Engine preference store.
+  PrefsInterface* prefs_;
+
+  // Global context of the system.
+  SystemState* system_state_;
+
+  // Install Plan based on Omaha Response.
+  InstallPlan* install_plan_;
+
+  // File descriptor of the source partition. Only set while updating a
+  // partition when using a delta payload.
+  FileDescriptorPtr source_fd_{nullptr};
+
+  // File descriptor of the target partition. Only set while performing the
+  // operations of a given partition.
+  FileDescriptorPtr target_fd_{nullptr};
+
+  // Paths the |source_fd_| and |target_fd_| refer to.
+  std::string source_path_;
+  std::string target_path_;
+
+  // Parsed manifest. Set after enough bytes to parse the manifest were
+  // downloaded.
+  DeltaArchiveManifest manifest_;
+  bool manifest_parsed_{false};
+  bool manifest_valid_{false};
+  uint64_t metadata_size_{0};
+  uint64_t manifest_size_{0};
+  uint32_t metadata_signature_size_{0};
+  uint64_t major_payload_version_{0};
+
+  // Accumulated number of operations per partition. The i-th element is the
+  // sum of the number of operations for all the partitions from 0 to i
+  // inclusive. Valid when |manifest_valid_| is true.
+  std::vector<size_t> acc_num_operations_;
+
+  // The total operations in a payload. Valid when |manifest_valid_| is true,
+  // otherwise 0.
+  size_t num_total_operations_{0};
+
+  // The list of partitions to update as found in the manifest major version 2.
+  // When parsing an older manifest format, the information is converted over to
+  // this format instead.
+  std::vector<PartitionUpdate> partitions_;
+
+  // Index in the list of partitions (|partitions_| member) of the current
+  // partition being processed.
+  size_t current_partition_{0};
+
+  // Index of the next operation to perform in the manifest. The index is linear
+  // on the total number of operation on the manifest.
+  size_t next_operation_num_{0};
+
+  // A buffer used for accumulating downloaded data. Initially, it stores the
+  // payload metadata; once that's downloaded and parsed, it stores data for the
+  // next update operation.
+  brillo::Blob buffer_;
+  // Offset of buffer_ in the binary blobs section of the update.
+  uint64_t buffer_offset_{0};
+
+  // Last |buffer_offset_| value updated as part of the progress update.
+  uint64_t last_updated_buffer_offset_{kuint64max};
+
+  // The block size (parsed from the manifest).
+  uint32_t block_size_{0};
+
+  // Calculates the whole payload file hash, including headers and signatures.
+  HashCalculator payload_hash_calculator_;
+
+  // Calculates the hash of the portion of the payload signed by the payload
+  // signature. This hash skips the metadata signature portion, located after
+  // the metadata and doesn't include the payload signature itself.
+  HashCalculator signed_hash_calculator_;
+
+  // Signatures message blob extracted directly from the payload.
+  brillo::Blob signatures_message_data_;
+
+  // The public key to be used. Provided as a member so that tests can
+  // override with test keys.
+  std::string public_key_path_{constants::kUpdatePayloadPublicKeyPath};
+
+  // The number of bytes received so far, used for progress tracking.
+  size_t total_bytes_received_{0};
+
+  // An overall progress counter, which should reflect both download progress
+  // and the ratio of applied operations. Range is 0-100.
+  unsigned overall_progress_{0};
+
+  // The last progress chunk recorded.
+  unsigned last_progress_chunk_{0};
+
+  // The timeout after which we should force emitting a progress log (constant),
+  // and the actual point in time for the next forced log to be emitted.
+  const base::TimeDelta forced_progress_log_wait_{
+      base::TimeDelta::FromSeconds(kProgressLogTimeoutSeconds)};
+  base::Time forced_progress_log_time_;
+
+  // The payload major payload version supported by DeltaPerformer.
+  uint64_t supported_major_version_{kSupportedMajorPayloadVersion};
+
+  // The delta minor payload version supported by DeltaPerformer.
+  uint32_t supported_minor_version_{kSupportedMinorPayloadVersion};
+
+  DISALLOW_COPY_AND_ASSIGN(DeltaPerformer);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_DELTA_PERFORMER_H_
diff --git a/payload_consumer/delta_performer_integration_test.cc b/payload_consumer/delta_performer_integration_test.cc
new file mode 100644
index 0000000..728e12e
--- /dev/null
+++ b/payload_consumer/delta_performer_integration_test.cc
@@ -0,0 +1,1031 @@
+//
+// Copyright (C) 2012 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 "update_engine/payload_consumer/delta_performer.h"
+
+#include <inttypes.h>
+#include <sys/mount.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include <base/files/file_path.h>
+#include <base/files/file_util.h>
+#include <base/strings/string_util.h>
+#include <base/strings/stringprintf.h>
+#include <google/protobuf/repeated_field.h>
+#include <gtest/gtest.h>
+
+#include "update_engine/common/constants.h"
+#include "update_engine/common/fake_hardware.h"
+#include "update_engine/common/mock_prefs.h"
+#include "update_engine/common/test_utils.h"
+#include "update_engine/common/utils.h"
+#include "update_engine/fake_system_state.h"
+#include "update_engine/payload_consumer/payload_constants.h"
+#include "update_engine/payload_consumer/payload_verifier.h"
+#include "update_engine/payload_generator/delta_diff_generator.h"
+#include "update_engine/payload_generator/payload_signer.h"
+#include "update_engine/update_metadata.pb.h"
+
+namespace chromeos_update_engine {
+
+using std::string;
+using std::vector;
+using test_utils::ScopedLoopMounter;
+using test_utils::System;
+using test_utils::kRandomString;
+using testing::Return;
+using testing::_;
+
+extern const char* kUnittestPrivateKeyPath;
+extern const char* kUnittestPublicKeyPath;
+extern const char* kUnittestPrivateKey2Path;
+extern const char* kUnittestPublicKey2Path;
+
+static const int kDefaultKernelSize = 4096;  // Something small for a test
+static const uint8_t kNewData[] = {'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
+                                   'n', 'e', 'w', ' ', 'd', 'a', 't', 'a', '.'};
+
+namespace {
+struct DeltaState {
+  string a_img;
+  string b_img;
+  string result_img;
+  size_t image_size;
+
+  string delta_path;
+  uint64_t metadata_size;
+
+  string old_kernel;
+  brillo::Blob old_kernel_data;
+
+  string new_kernel;
+  brillo::Blob new_kernel_data;
+
+  string result_kernel;
+  brillo::Blob result_kernel_data;
+  size_t kernel_size;
+
+  // The InstallPlan referenced by the DeltaPerformer. This needs to outlive
+  // the DeltaPerformer.
+  InstallPlan install_plan;
+
+  // The in-memory copy of delta file.
+  brillo::Blob delta;
+
+  // The mock system state object with which we initialize the
+  // delta performer.
+  FakeSystemState fake_system_state;
+};
+
+enum SignatureTest {
+  kSignatureNone,  // No payload signing.
+  kSignatureGenerator,  // Sign the payload at generation time.
+  kSignatureGenerated,  // Sign the payload after it's generated.
+  kSignatureGeneratedPlaceholder,  // Insert placeholder signatures, then real.
+  kSignatureGeneratedPlaceholderMismatch,  // Insert a wrong sized placeholder.
+  kSignatureGeneratedShell,  // Sign the generated payload through shell cmds.
+  kSignatureGeneratedShellBadKey,  // Sign with a bad key through shell cmds.
+  kSignatureGeneratedShellRotateCl1,  // Rotate key, test client v1
+  kSignatureGeneratedShellRotateCl2,  // Rotate key, test client v2
+};
+
+enum OperationHashTest {
+  kInvalidOperationData,
+  kValidOperationData,
+};
+
+}  // namespace
+
+class DeltaPerformerIntegrationTest : public ::testing::Test {
+ public:
+  static void SetSupportedVersion(DeltaPerformer* performer,
+                                  uint64_t minor_version) {
+    performer->supported_minor_version_ = minor_version;
+  }
+};
+
+static void CompareFilesByBlock(const string& a_file, const string& b_file,
+                                size_t image_size) {
+  EXPECT_EQ(0, image_size % kBlockSize);
+
+  brillo::Blob a_data, b_data;
+  EXPECT_TRUE(utils::ReadFile(a_file, &a_data)) << "file failed: " << a_file;
+  EXPECT_TRUE(utils::ReadFile(b_file, &b_data)) << "file failed: " << b_file;
+
+  EXPECT_GE(a_data.size(), image_size);
+  EXPECT_GE(b_data.size(), image_size);
+  for (size_t i = 0; i < image_size; i += kBlockSize) {
+    EXPECT_EQ(0, i % kBlockSize);
+    brillo::Blob a_sub(&a_data[i], &a_data[i + kBlockSize]);
+    brillo::Blob b_sub(&b_data[i], &b_data[i + kBlockSize]);
+    EXPECT_TRUE(a_sub == b_sub) << "Block " << (i/kBlockSize) << " differs";
+  }
+  if (::testing::Test::HasNonfatalFailure()) {
+    LOG(INFO) << "Compared filesystems with size " << image_size
+              << ", partition A " << a_file << " size: " << a_data.size()
+              << ", partition B " << b_file << " size: " << b_data.size();
+  }
+}
+
+static bool WriteSparseFile(const string& path, off_t size) {
+  int fd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644);
+  TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
+  ScopedFdCloser fd_closer(&fd);
+  off_t rc = lseek(fd, size + 1, SEEK_SET);
+  TEST_AND_RETURN_FALSE_ERRNO(rc != static_cast<off_t>(-1));
+  int return_code = ftruncate(fd, size);
+  TEST_AND_RETURN_FALSE_ERRNO(return_code == 0);
+  return true;
+}
+
+static size_t GetSignatureSize(const string& private_key_path) {
+  const brillo::Blob data(1, 'x');
+  brillo::Blob hash;
+  EXPECT_TRUE(HashCalculator::RawHashOfData(data, &hash));
+  brillo::Blob signature;
+  EXPECT_TRUE(PayloadSigner::SignHash(hash,
+                                      private_key_path,
+                                      &signature));
+  return signature.size();
+}
+
+static bool InsertSignaturePlaceholder(int signature_size,
+                                       const string& payload_path,
+                                       uint64_t* out_metadata_size) {
+  vector<brillo::Blob> signatures;
+  signatures.push_back(brillo::Blob(signature_size, 0));
+
+  return PayloadSigner::AddSignatureToPayload(
+      payload_path,
+      signatures,
+      {},
+      payload_path,
+      out_metadata_size);
+}
+
+static void SignGeneratedPayload(const string& payload_path,
+                                 uint64_t* out_metadata_size) {
+  int signature_size = GetSignatureSize(kUnittestPrivateKeyPath);
+  brillo::Blob hash;
+  ASSERT_TRUE(PayloadSigner::HashPayloadForSigning(
+      payload_path,
+      vector<int>(1, signature_size),
+      &hash,
+      nullptr));
+  brillo::Blob signature;
+  ASSERT_TRUE(PayloadSigner::SignHash(hash,
+                                      kUnittestPrivateKeyPath,
+                                      &signature));
+  ASSERT_TRUE(PayloadSigner::AddSignatureToPayload(
+      payload_path,
+      vector<brillo::Blob>(1, signature),
+      {},
+      payload_path,
+      out_metadata_size));
+  EXPECT_TRUE(PayloadSigner::VerifySignedPayload(
+      payload_path,
+      kUnittestPublicKeyPath));
+}
+
+static void SignGeneratedShellPayload(SignatureTest signature_test,
+                                      const string& payload_path) {
+  string private_key_path = kUnittestPrivateKeyPath;
+  if (signature_test == kSignatureGeneratedShellBadKey) {
+    ASSERT_TRUE(utils::MakeTempFile("key.XXXXXX",
+                                    &private_key_path,
+                                    nullptr));
+  } else {
+    ASSERT_TRUE(signature_test == kSignatureGeneratedShell ||
+                signature_test == kSignatureGeneratedShellRotateCl1 ||
+                signature_test == kSignatureGeneratedShellRotateCl2);
+  }
+  ScopedPathUnlinker key_unlinker(private_key_path);
+  key_unlinker.set_should_remove(signature_test ==
+                                 kSignatureGeneratedShellBadKey);
+  // Generates a new private key that will not match the public key.
+  if (signature_test == kSignatureGeneratedShellBadKey) {
+    LOG(INFO) << "Generating a mismatched private key.";
+    ASSERT_EQ(0, System(base::StringPrintf(
+        "openssl genrsa -out %s 2048", private_key_path.c_str())));
+  }
+  int signature_size = GetSignatureSize(private_key_path);
+  string hash_file;
+  ASSERT_TRUE(utils::MakeTempFile("hash.XXXXXX", &hash_file, nullptr));
+  ScopedPathUnlinker hash_unlinker(hash_file);
+  string signature_size_string;
+  if (signature_test == kSignatureGeneratedShellRotateCl1 ||
+      signature_test == kSignatureGeneratedShellRotateCl2)
+    signature_size_string = base::StringPrintf("%d:%d",
+                                               signature_size, signature_size);
+  else
+    signature_size_string = base::StringPrintf("%d", signature_size);
+  ASSERT_EQ(0,
+            System(base::StringPrintf(
+                "./delta_generator -in_file=%s -signature_size=%s "
+                "-out_hash_file=%s",
+                payload_path.c_str(),
+                signature_size_string.c_str(),
+                hash_file.c_str())));
+
+  // Pad the hash
+  brillo::Blob hash;
+  ASSERT_TRUE(utils::ReadFile(hash_file, &hash));
+  ASSERT_TRUE(PayloadVerifier::PadRSA2048SHA256Hash(&hash));
+  ASSERT_TRUE(test_utils::WriteFileVector(hash_file, hash));
+
+  string sig_file;
+  ASSERT_TRUE(utils::MakeTempFile("signature.XXXXXX", &sig_file, nullptr));
+  ScopedPathUnlinker sig_unlinker(sig_file);
+  ASSERT_EQ(0,
+            System(base::StringPrintf(
+                "openssl rsautl -raw -sign -inkey %s -in %s -out %s",
+                private_key_path.c_str(),
+                hash_file.c_str(),
+                sig_file.c_str())));
+  string sig_file2;
+  ASSERT_TRUE(utils::MakeTempFile("signature.XXXXXX", &sig_file2, nullptr));
+  ScopedPathUnlinker sig2_unlinker(sig_file2);
+  if (signature_test == kSignatureGeneratedShellRotateCl1 ||
+      signature_test == kSignatureGeneratedShellRotateCl2) {
+    ASSERT_EQ(0,
+              System(base::StringPrintf(
+                  "openssl rsautl -raw -sign -inkey %s -in %s -out %s",
+                  kUnittestPrivateKey2Path,
+                  hash_file.c_str(),
+                  sig_file2.c_str())));
+    // Append second sig file to first path
+    sig_file += ":" + sig_file2;
+  }
+
+  ASSERT_EQ(0,
+            System(base::StringPrintf(
+                "./delta_generator -in_file=%s -signature_file=%s "
+                "-out_file=%s",
+                payload_path.c_str(),
+                sig_file.c_str(),
+                payload_path.c_str())));
+  int verify_result =
+      System(base::StringPrintf(
+          "./delta_generator -in_file=%s -public_key=%s -public_key_version=%d",
+          payload_path.c_str(),
+          signature_test == kSignatureGeneratedShellRotateCl2 ?
+          kUnittestPublicKey2Path : kUnittestPublicKeyPath,
+          signature_test == kSignatureGeneratedShellRotateCl2 ? 2 : 1));
+  if (signature_test == kSignatureGeneratedShellBadKey) {
+    ASSERT_NE(0, verify_result);
+  } else {
+    ASSERT_EQ(0, verify_result);
+  }
+}
+
+static void GenerateDeltaFile(bool full_kernel,
+                              bool full_rootfs,
+                              bool noop,
+                              ssize_t chunk_size,
+                              SignatureTest signature_test,
+                              DeltaState *state,
+                              uint32_t minor_version) {
+  EXPECT_TRUE(utils::MakeTempFile("a_img.XXXXXX", &state->a_img, nullptr));
+  EXPECT_TRUE(utils::MakeTempFile("b_img.XXXXXX", &state->b_img, nullptr));
+
+  // result_img is used in minor version 2. Instead of applying the update
+  // in-place on A, we apply it to a new image, result_img.
+  EXPECT_TRUE(
+      utils::MakeTempFile("result_img.XXXXXX", &state->result_img, nullptr));
+  test_utils::CreateExtImageAtPath(state->a_img, nullptr);
+
+  state->image_size = utils::FileSize(state->a_img);
+
+  // Create ImageInfo A & B
+  ImageInfo old_image_info;
+  ImageInfo new_image_info;
+
+  if (!full_rootfs) {
+    old_image_info.set_channel("src-channel");
+    old_image_info.set_board("src-board");
+    old_image_info.set_version("src-version");
+    old_image_info.set_key("src-key");
+    old_image_info.set_build_channel("src-build-channel");
+    old_image_info.set_build_version("src-build-version");
+  }
+
+  new_image_info.set_channel("test-channel");
+  new_image_info.set_board("test-board");
+  new_image_info.set_version("test-version");
+  new_image_info.set_key("test-key");
+  new_image_info.set_build_channel("test-build-channel");
+  new_image_info.set_build_version("test-build-version");
+
+  // Make some changes to the A image.
+  {
+    string a_mnt;
+    ScopedLoopMounter b_mounter(state->a_img, &a_mnt, 0);
+
+    brillo::Blob hardtocompress;
+    while (hardtocompress.size() < 3 * kBlockSize) {
+      hardtocompress.insert(hardtocompress.end(),
+                            std::begin(kRandomString), std::end(kRandomString));
+    }
+    EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/hardtocompress",
+                                                    a_mnt.c_str()).c_str(),
+                                 hardtocompress.data(),
+                                 hardtocompress.size()));
+
+    brillo::Blob zeros(16 * 1024, 0);
+    EXPECT_EQ(zeros.size(),
+              base::WriteFile(base::FilePath(base::StringPrintf(
+                                  "%s/move-to-sparse", a_mnt.c_str())),
+                              reinterpret_cast<const char*>(zeros.data()),
+                              zeros.size()));
+
+    EXPECT_TRUE(
+        WriteSparseFile(base::StringPrintf("%s/move-from-sparse",
+                                           a_mnt.c_str()), 16 * 1024));
+
+    EXPECT_EQ(0,
+              System(base::StringPrintf("dd if=/dev/zero of=%s/move-semi-sparse"
+                                        " bs=1 seek=4096 count=1 status=none",
+                                        a_mnt.c_str()).c_str()));
+
+    // Write 1 MiB of 0xff to try to catch the case where writing a bsdiff
+    // patch fails to zero out the final block.
+    brillo::Blob ones(1024 * 1024, 0xff);
+    EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/ones",
+                                                    a_mnt.c_str()).c_str(),
+                                 ones.data(),
+                                 ones.size()));
+  }
+
+  if (noop) {
+    EXPECT_TRUE(base::CopyFile(base::FilePath(state->a_img),
+                               base::FilePath(state->b_img)));
+    old_image_info = new_image_info;
+  } else {
+    if (minor_version == kSourceMinorPayloadVersion) {
+      // Create a result image with image_size bytes of garbage.
+      brillo::Blob ones(state->image_size, 0xff);
+      EXPECT_TRUE(utils::WriteFile(state->result_img.c_str(),
+                                   ones.data(),
+                                   ones.size()));
+      EXPECT_EQ(utils::FileSize(state->a_img),
+                utils::FileSize(state->result_img));
+    }
+
+    test_utils::CreateExtImageAtPath(state->b_img, nullptr);
+
+    // Make some changes to the B image.
+    string b_mnt;
+    ScopedLoopMounter b_mounter(state->b_img, &b_mnt, 0);
+
+    EXPECT_EQ(0, System(base::StringPrintf("cp %s/hello %s/hello2",
+                                           b_mnt.c_str(),
+                                           b_mnt.c_str()).c_str()));
+    EXPECT_EQ(0, System(base::StringPrintf("rm %s/hello",
+                                           b_mnt.c_str()).c_str()));
+    EXPECT_EQ(0, System(base::StringPrintf("mv %s/hello2 %s/hello",
+                                           b_mnt.c_str(),
+                                           b_mnt.c_str()).c_str()));
+    EXPECT_EQ(0, System(base::StringPrintf("echo foo > %s/foo",
+                                           b_mnt.c_str()).c_str()));
+    EXPECT_EQ(0, System(base::StringPrintf("touch %s/emptyfile",
+                                           b_mnt.c_str()).c_str()));
+    EXPECT_TRUE(WriteSparseFile(base::StringPrintf("%s/fullsparse",
+                                                   b_mnt.c_str()),
+                                                   1024 * 1024));
+
+    EXPECT_TRUE(
+        WriteSparseFile(base::StringPrintf("%s/move-to-sparse", b_mnt.c_str()),
+                        16 * 1024));
+
+    brillo::Blob zeros(16 * 1024, 0);
+    EXPECT_EQ(zeros.size(),
+              base::WriteFile(base::FilePath(base::StringPrintf(
+                                  "%s/move-from-sparse", b_mnt.c_str())),
+                              reinterpret_cast<const char*>(zeros.data()),
+                              zeros.size()));
+
+    EXPECT_EQ(0, System(base::StringPrintf("dd if=/dev/zero "
+                                           "of=%s/move-semi-sparse "
+                                           "bs=1 seek=4096 count=1 status=none",
+                                           b_mnt.c_str()).c_str()));
+
+    EXPECT_EQ(0, System(base::StringPrintf("dd if=/dev/zero "
+                                           "of=%s/partsparse bs=1 "
+                                           "seek=4096 count=1 status=none",
+                                           b_mnt.c_str()).c_str()));
+    EXPECT_EQ(0, System(base::StringPrintf("cp %s/srchardlink0 %s/tmp && "
+                                           "mv %s/tmp %s/srchardlink1",
+                                           b_mnt.c_str(),
+                                           b_mnt.c_str(),
+                                           b_mnt.c_str(),
+                                           b_mnt.c_str()).c_str()));
+    EXPECT_EQ(0, System(
+        base::StringPrintf("rm %s/boguslink && echo foobar > %s/boguslink",
+                           b_mnt.c_str(), b_mnt.c_str()).c_str()));
+
+    brillo::Blob hardtocompress;
+    while (hardtocompress.size() < 3 * kBlockSize) {
+      hardtocompress.insert(hardtocompress.end(),
+                            std::begin(kRandomString), std::end(kRandomString));
+    }
+    EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/hardtocompress",
+                                              b_mnt.c_str()).c_str(),
+                                 hardtocompress.data(),
+                                 hardtocompress.size()));
+  }
+
+  string old_kernel;
+  EXPECT_TRUE(utils::MakeTempFile("old_kernel.XXXXXX",
+                                  &state->old_kernel,
+                                  nullptr));
+
+  string new_kernel;
+  EXPECT_TRUE(utils::MakeTempFile("new_kernel.XXXXXX",
+                                  &state->new_kernel,
+                                  nullptr));
+
+  string result_kernel;
+  EXPECT_TRUE(utils::MakeTempFile("result_kernel.XXXXXX",
+                                  &state->result_kernel,
+                                  nullptr));
+
+  state->kernel_size = kDefaultKernelSize;
+  state->old_kernel_data.resize(kDefaultKernelSize);
+  state->new_kernel_data.resize(state->old_kernel_data.size());
+  state->result_kernel_data.resize(state->old_kernel_data.size());
+  test_utils::FillWithData(&state->old_kernel_data);
+  test_utils::FillWithData(&state->new_kernel_data);
+  test_utils::FillWithData(&state->result_kernel_data);
+
+  // change the new kernel data
+  std::copy(std::begin(kNewData), std::end(kNewData),
+            state->new_kernel_data.begin());
+
+  if (noop) {
+    state->old_kernel_data = state->new_kernel_data;
+  }
+
+  // Write kernels to disk
+  EXPECT_TRUE(utils::WriteFile(state->old_kernel.c_str(),
+                               state->old_kernel_data.data(),
+                               state->old_kernel_data.size()));
+  EXPECT_TRUE(utils::WriteFile(state->new_kernel.c_str(),
+                               state->new_kernel_data.data(),
+                               state->new_kernel_data.size()));
+  EXPECT_TRUE(utils::WriteFile(state->result_kernel.c_str(),
+                               state->result_kernel_data.data(),
+                               state->result_kernel_data.size()));
+
+  EXPECT_TRUE(utils::MakeTempFile("delta.XXXXXX",
+                                  &state->delta_path,
+                                  nullptr));
+  LOG(INFO) << "delta path: " << state->delta_path;
+  {
+    const string private_key =
+        signature_test == kSignatureGenerator ? kUnittestPrivateKeyPath : "";
+
+    PayloadGenerationConfig payload_config;
+    payload_config.is_delta = !full_rootfs;
+    payload_config.hard_chunk_size = chunk_size;
+    payload_config.rootfs_partition_size = kRootFSPartitionSize;
+    payload_config.major_version = kChromeOSMajorPayloadVersion;
+    payload_config.minor_version = minor_version;
+    if (!full_rootfs) {
+      payload_config.source.partitions.emplace_back(kLegacyPartitionNameRoot);
+      payload_config.source.partitions.emplace_back(kLegacyPartitionNameKernel);
+      payload_config.source.partitions.front().path = state->a_img;
+      if (!full_kernel)
+        payload_config.source.partitions.back().path = state->old_kernel;
+      payload_config.source.image_info = old_image_info;
+      EXPECT_TRUE(payload_config.source.LoadImageSize());
+      for (PartitionConfig& part : payload_config.source.partitions)
+        EXPECT_TRUE(part.OpenFilesystem());
+    } else {
+      if (payload_config.hard_chunk_size == -1)
+        // Use 1 MiB chunk size for the full unittests.
+        payload_config.hard_chunk_size = 1024 * 1024;
+    }
+    payload_config.target.partitions.emplace_back(kLegacyPartitionNameRoot);
+    payload_config.target.partitions.back().path = state->b_img;
+    payload_config.target.partitions.emplace_back(kLegacyPartitionNameKernel);
+    payload_config.target.partitions.back().path = state->new_kernel;
+    payload_config.target.image_info = new_image_info;
+    EXPECT_TRUE(payload_config.target.LoadImageSize());
+    for (PartitionConfig& part : payload_config.target.partitions)
+      EXPECT_TRUE(part.OpenFilesystem());
+
+    EXPECT_TRUE(payload_config.Validate());
+    EXPECT_TRUE(
+        GenerateUpdatePayloadFile(
+            payload_config,
+            state->delta_path,
+            private_key,
+            &state->metadata_size));
+  }
+  // Extend the "partitions" holding the file system a bit.
+  EXPECT_EQ(0, HANDLE_EINTR(truncate(state->a_img.c_str(),
+                                     state->image_size + 1024 * 1024)));
+  EXPECT_EQ(state->image_size + 1024 * 1024, utils::FileSize(state->a_img));
+  EXPECT_EQ(0, HANDLE_EINTR(truncate(state->b_img.c_str(),
+                                     state->image_size + 1024 * 1024)));
+  EXPECT_EQ(state->image_size + 1024 * 1024, utils::FileSize(state->b_img));
+
+  if (signature_test == kSignatureGeneratedPlaceholder ||
+      signature_test == kSignatureGeneratedPlaceholderMismatch) {
+    int signature_size = GetSignatureSize(kUnittestPrivateKeyPath);
+    LOG(INFO) << "Inserting placeholder signature.";
+    ASSERT_TRUE(InsertSignaturePlaceholder(signature_size, state->delta_path,
+                                           &state->metadata_size));
+
+    if (signature_test == kSignatureGeneratedPlaceholderMismatch) {
+      signature_size -= 1;
+      LOG(INFO) << "Inserting mismatched placeholder signature.";
+      ASSERT_FALSE(InsertSignaturePlaceholder(signature_size, state->delta_path,
+                                              &state->metadata_size));
+      return;
+    }
+  }
+
+  if (signature_test == kSignatureGenerated ||
+      signature_test == kSignatureGeneratedPlaceholder ||
+      signature_test == kSignatureGeneratedPlaceholderMismatch) {
+    // Generate the signed payload and update the metadata size in state to
+    // reflect the new size after adding the signature operation to the
+    // manifest.
+    LOG(INFO) << "Signing payload.";
+    SignGeneratedPayload(state->delta_path, &state->metadata_size);
+  } else if (signature_test == kSignatureGeneratedShell ||
+             signature_test == kSignatureGeneratedShellBadKey ||
+             signature_test == kSignatureGeneratedShellRotateCl1 ||
+             signature_test == kSignatureGeneratedShellRotateCl2) {
+    SignGeneratedShellPayload(signature_test, state->delta_path);
+  }
+}
+
+static void ApplyDeltaFile(bool full_kernel, bool full_rootfs, bool noop,
+                           SignatureTest signature_test, DeltaState* state,
+                           bool hash_checks_mandatory,
+                           OperationHashTest op_hash_test,
+                           DeltaPerformer** performer,
+                           uint32_t minor_version) {
+  // Check the metadata.
+  {
+    DeltaArchiveManifest manifest;
+    EXPECT_TRUE(PayloadSigner::LoadPayload(state->delta_path,
+                                           &state->delta,
+                                           &manifest,
+                                           nullptr,
+                                           &state->metadata_size,
+                                           nullptr));
+    LOG(INFO) << "Metadata size: " << state->metadata_size;
+
+
+
+    if (signature_test == kSignatureNone) {
+      EXPECT_FALSE(manifest.has_signatures_offset());
+      EXPECT_FALSE(manifest.has_signatures_size());
+    } else {
+      EXPECT_TRUE(manifest.has_signatures_offset());
+      EXPECT_TRUE(manifest.has_signatures_size());
+      Signatures sigs_message;
+      EXPECT_TRUE(sigs_message.ParseFromArray(
+          &state->delta[state->metadata_size + manifest.signatures_offset()],
+          manifest.signatures_size()));
+      if (signature_test == kSignatureGeneratedShellRotateCl1 ||
+          signature_test == kSignatureGeneratedShellRotateCl2)
+        EXPECT_EQ(2, sigs_message.signatures_size());
+      else
+        EXPECT_EQ(1, sigs_message.signatures_size());
+      const Signatures_Signature& signature = sigs_message.signatures(0);
+      EXPECT_EQ(1, signature.version());
+
+      uint64_t expected_sig_data_length = 0;
+      vector<string> key_paths{kUnittestPrivateKeyPath};
+      if (signature_test == kSignatureGeneratedShellRotateCl1 ||
+          signature_test == kSignatureGeneratedShellRotateCl2) {
+        key_paths.push_back(kUnittestPrivateKey2Path);
+      }
+      EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
+          key_paths,
+          &expected_sig_data_length));
+      EXPECT_EQ(expected_sig_data_length, manifest.signatures_size());
+      EXPECT_FALSE(signature.data().empty());
+    }
+
+    if (noop) {
+      EXPECT_EQ(0, manifest.install_operations_size());
+      EXPECT_EQ(1, manifest.kernel_install_operations_size());
+    }
+
+    if (full_kernel) {
+      EXPECT_FALSE(manifest.has_old_kernel_info());
+    } else {
+      EXPECT_EQ(state->old_kernel_data.size(),
+                manifest.old_kernel_info().size());
+      EXPECT_FALSE(manifest.old_kernel_info().hash().empty());
+    }
+
+    EXPECT_EQ(manifest.new_image_info().channel(), "test-channel");
+    EXPECT_EQ(manifest.new_image_info().board(), "test-board");
+    EXPECT_EQ(manifest.new_image_info().version(), "test-version");
+    EXPECT_EQ(manifest.new_image_info().key(), "test-key");
+    EXPECT_EQ(manifest.new_image_info().build_channel(), "test-build-channel");
+    EXPECT_EQ(manifest.new_image_info().build_version(), "test-build-version");
+
+    if (!full_rootfs) {
+      if (noop) {
+        EXPECT_EQ(manifest.old_image_info().channel(), "test-channel");
+        EXPECT_EQ(manifest.old_image_info().board(), "test-board");
+        EXPECT_EQ(manifest.old_image_info().version(), "test-version");
+        EXPECT_EQ(manifest.old_image_info().key(), "test-key");
+        EXPECT_EQ(manifest.old_image_info().build_channel(),
+                  "test-build-channel");
+        EXPECT_EQ(manifest.old_image_info().build_version(),
+                  "test-build-version");
+      } else {
+        EXPECT_EQ(manifest.old_image_info().channel(), "src-channel");
+        EXPECT_EQ(manifest.old_image_info().board(), "src-board");
+        EXPECT_EQ(manifest.old_image_info().version(), "src-version");
+        EXPECT_EQ(manifest.old_image_info().key(), "src-key");
+        EXPECT_EQ(manifest.old_image_info().build_channel(),
+                  "src-build-channel");
+        EXPECT_EQ(manifest.old_image_info().build_version(),
+                  "src-build-version");
+      }
+    }
+
+
+    if (full_rootfs) {
+      EXPECT_FALSE(manifest.has_old_rootfs_info());
+      EXPECT_FALSE(manifest.has_old_image_info());
+      EXPECT_TRUE(manifest.has_new_image_info());
+    } else {
+      EXPECT_EQ(state->image_size, manifest.old_rootfs_info().size());
+      EXPECT_FALSE(manifest.old_rootfs_info().hash().empty());
+    }
+
+    EXPECT_EQ(state->new_kernel_data.size(), manifest.new_kernel_info().size());
+    EXPECT_EQ(state->image_size, manifest.new_rootfs_info().size());
+
+    EXPECT_FALSE(manifest.new_kernel_info().hash().empty());
+    EXPECT_FALSE(manifest.new_rootfs_info().hash().empty());
+  }
+
+  MockPrefs prefs;
+  EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize,
+                              state->metadata_size)).WillOnce(Return(true));
+  EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _))
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _))
+      .WillOnce(Return(false));
+  EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataOffset, _))
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataLength, _))
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSHA256Context, _))
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignedSHA256Context, _))
+      .WillRepeatedly(Return(true));
+  if (op_hash_test == kValidOperationData && signature_test != kSignatureNone) {
+    EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignatureBlob, _))
+        .WillOnce(Return(true));
+  }
+
+  // Update the A image in place.
+  InstallPlan* install_plan = &state->install_plan;
+  install_plan->hash_checks_mandatory = hash_checks_mandatory;
+  install_plan->metadata_size = state->metadata_size;
+  install_plan->is_full_update = full_kernel && full_rootfs;
+  install_plan->source_slot = 0;
+  install_plan->target_slot = 1;
+
+  InstallPlan::Partition root_part;
+  root_part.name = kLegacyPartitionNameRoot;
+
+  InstallPlan::Partition kernel_part;
+  kernel_part.name = kLegacyPartitionNameKernel;
+
+  LOG(INFO) << "Setting payload metadata size in Omaha  = "
+            << state->metadata_size;
+  ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
+      state->delta.data(),
+      state->metadata_size,
+      kUnittestPrivateKeyPath,
+      &install_plan->metadata_signature));
+  EXPECT_FALSE(install_plan->metadata_signature.empty());
+
+  *performer = new DeltaPerformer(&prefs,
+                                  &state->fake_system_state,
+                                  install_plan);
+  EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
+  (*performer)->set_public_key_path(kUnittestPublicKeyPath);
+  DeltaPerformerIntegrationTest::SetSupportedVersion(*performer, minor_version);
+
+  EXPECT_EQ(state->image_size,
+            HashCalculator::RawHashOfFile(
+                state->a_img,
+                state->image_size,
+                &root_part.source_hash));
+  EXPECT_TRUE(HashCalculator::RawHashOfData(
+                  state->old_kernel_data,
+                  &kernel_part.source_hash));
+
+  // This partitions are normally filed by the FilesystemVerifierAction with
+  // the source hashes used for deltas.
+  install_plan->partitions = {root_part, kernel_part};
+
+  // With minor version 2, we want the target to be the new image, result_img,
+  // but with version 1, we want to update A in place.
+  string target_root, target_kernel;
+  if (minor_version == kSourceMinorPayloadVersion) {
+    target_root = state->result_img;
+    target_kernel = state->result_kernel;
+  } else {
+    target_root = state->a_img;
+    target_kernel = state->old_kernel;
+  }
+
+  state->fake_system_state.fake_boot_control()->SetPartitionDevice(
+      kLegacyPartitionNameRoot, install_plan->source_slot, state->a_img);
+  state->fake_system_state.fake_boot_control()->SetPartitionDevice(
+      kLegacyPartitionNameKernel, install_plan->source_slot, state->old_kernel);
+  state->fake_system_state.fake_boot_control()->SetPartitionDevice(
+      kLegacyPartitionNameRoot, install_plan->target_slot, target_root);
+  state->fake_system_state.fake_boot_control()->SetPartitionDevice(
+      kLegacyPartitionNameKernel, install_plan->target_slot, target_kernel);
+
+  ErrorCode expected_error, actual_error;
+  bool continue_writing;
+  switch (op_hash_test) {
+    case kInvalidOperationData: {
+      // Muck with some random offset post the metadata size so that
+      // some operation hash will result in a mismatch.
+      int some_offset = state->metadata_size + 300;
+      LOG(INFO) << "Tampered value at offset: " << some_offset;
+      state->delta[some_offset]++;
+      expected_error = ErrorCode::kDownloadOperationHashMismatch;
+      continue_writing = false;
+      break;
+    }
+
+    case kValidOperationData:
+    default:
+      // no change.
+      expected_error = ErrorCode::kSuccess;
+      continue_writing = true;
+      break;
+  }
+
+  // Write at some number of bytes per operation. Arbitrarily chose 5.
+  const size_t kBytesPerWrite = 5;
+  for (size_t i = 0; i < state->delta.size(); i += kBytesPerWrite) {
+    size_t count = std::min(state->delta.size() - i, kBytesPerWrite);
+    bool write_succeeded = ((*performer)->Write(&state->delta[i],
+                                                count,
+                                                &actual_error));
+    // Normally write_succeeded should be true every time and
+    // actual_error should be ErrorCode::kSuccess. If so, continue the loop.
+    // But if we seeded an operation hash error above, then write_succeeded
+    // will be false. The failure may happen at any operation n. So, all
+    // Writes until n-1 should succeed and the nth operation will fail with
+    // actual_error. In this case, we should bail out of the loop because
+    // we cannot proceed applying the delta.
+    if (!write_succeeded) {
+      LOG(INFO) << "Write failed. Checking if it failed with expected error";
+      EXPECT_EQ(expected_error, actual_error);
+      if (!continue_writing) {
+        LOG(INFO) << "Cannot continue writing. Bailing out.";
+        break;
+      }
+    }
+
+    EXPECT_EQ(ErrorCode::kSuccess, actual_error);
+  }
+
+  // If we had continued all the way through, Close should succeed.
+  // Otherwise, it should fail. Check appropriately.
+  bool close_result = (*performer)->Close();
+  if (continue_writing)
+    EXPECT_EQ(0, close_result);
+  else
+    EXPECT_LE(0, close_result);
+}
+
+void VerifyPayloadResult(DeltaPerformer* performer,
+                         DeltaState* state,
+                         ErrorCode expected_result,
+                         uint32_t minor_version) {
+  if (!performer) {
+    EXPECT_TRUE(!"Skipping payload verification since performer is null.");
+    return;
+  }
+
+  int expected_times = (expected_result == ErrorCode::kSuccess) ? 1 : 0;
+  EXPECT_CALL(*(state->fake_system_state.mock_payload_state()),
+              DownloadComplete()).Times(expected_times);
+
+  LOG(INFO) << "Verifying payload for expected result "
+            << expected_result;
+  EXPECT_EQ(expected_result, performer->VerifyPayload(
+      HashCalculator::HashOfData(state->delta),
+      state->delta.size()));
+  LOG(INFO) << "Verified payload.";
+
+  if (expected_result != ErrorCode::kSuccess) {
+    // no need to verify new partition if VerifyPayload failed.
+    return;
+  }
+
+  brillo::Blob updated_kernel_partition;
+  if (minor_version == kSourceMinorPayloadVersion) {
+    CompareFilesByBlock(state->result_kernel, state->new_kernel,
+                        state->kernel_size);
+    CompareFilesByBlock(state->result_img, state->b_img,
+                        state->image_size);
+    EXPECT_TRUE(utils::ReadFile(state->result_kernel,
+                                &updated_kernel_partition));
+  } else {
+    CompareFilesByBlock(state->old_kernel, state->new_kernel,
+                        state->kernel_size);
+    CompareFilesByBlock(state->a_img, state->b_img,
+                        state->image_size);
+    EXPECT_TRUE(utils::ReadFile(state->old_kernel, &updated_kernel_partition));
+  }
+
+  ASSERT_GE(updated_kernel_partition.size(), arraysize(kNewData));
+  EXPECT_TRUE(std::equal(std::begin(kNewData), std::end(kNewData),
+                         updated_kernel_partition.begin()));
+
+  const auto& partitions = state->install_plan.partitions;
+  EXPECT_EQ(2, partitions.size());
+  EXPECT_EQ(kLegacyPartitionNameRoot, partitions[0].name);
+  EXPECT_EQ(kLegacyPartitionNameKernel, partitions[1].name);
+
+  EXPECT_EQ(kDefaultKernelSize, partitions[1].target_size);
+  brillo::Blob expected_new_kernel_hash;
+  EXPECT_TRUE(HashCalculator::RawHashOfData(state->new_kernel_data,
+                                            &expected_new_kernel_hash));
+  EXPECT_EQ(expected_new_kernel_hash, partitions[1].target_hash);
+
+  EXPECT_EQ(state->image_size, partitions[0].target_size);
+  brillo::Blob expected_new_rootfs_hash;
+  EXPECT_EQ(state->image_size,
+            HashCalculator::RawHashOfFile(state->b_img,
+                                          state->image_size,
+                                          &expected_new_rootfs_hash));
+  EXPECT_EQ(expected_new_rootfs_hash, partitions[0].target_hash);
+}
+
+void VerifyPayload(DeltaPerformer* performer,
+                   DeltaState* state,
+                   SignatureTest signature_test,
+                   uint32_t minor_version) {
+  ErrorCode expected_result = ErrorCode::kSuccess;
+  switch (signature_test) {
+    case kSignatureNone:
+      expected_result = ErrorCode::kSignedDeltaPayloadExpectedError;
+      break;
+    case kSignatureGeneratedShellBadKey:
+      expected_result = ErrorCode::kDownloadPayloadPubKeyVerificationError;
+      break;
+    default: break;  // appease gcc
+  }
+
+  VerifyPayloadResult(performer, state, expected_result, minor_version);
+}
+
+void DoSmallImageTest(bool full_kernel, bool full_rootfs, bool noop,
+                      ssize_t chunk_size,
+                      SignatureTest signature_test,
+                      bool hash_checks_mandatory, uint32_t minor_version) {
+  DeltaState state;
+  DeltaPerformer *performer = nullptr;
+  GenerateDeltaFile(full_kernel, full_rootfs, noop, chunk_size,
+                    signature_test, &state, minor_version);
+
+  ScopedPathUnlinker a_img_unlinker(state.a_img);
+  ScopedPathUnlinker b_img_unlinker(state.b_img);
+  ScopedPathUnlinker new_img_unlinker(state.result_img);
+  ScopedPathUnlinker delta_unlinker(state.delta_path);
+  ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
+  ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
+  ScopedPathUnlinker result_kernel_unlinker(state.result_kernel);
+  ApplyDeltaFile(full_kernel, full_rootfs, noop, signature_test,
+                 &state, hash_checks_mandatory, kValidOperationData,
+                 &performer, minor_version);
+  VerifyPayload(performer, &state, signature_test, minor_version);
+  delete performer;
+}
+
+void DoOperationHashMismatchTest(OperationHashTest op_hash_test,
+                                 bool hash_checks_mandatory) {
+  DeltaState state;
+  uint64_t minor_version = kFullPayloadMinorVersion;
+  GenerateDeltaFile(true, true, false, -1, kSignatureGenerated, &state,
+                    minor_version);
+  ScopedPathUnlinker a_img_unlinker(state.a_img);
+  ScopedPathUnlinker b_img_unlinker(state.b_img);
+  ScopedPathUnlinker delta_unlinker(state.delta_path);
+  ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
+  ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
+  DeltaPerformer *performer = nullptr;
+  ApplyDeltaFile(true, true, false, kSignatureGenerated, &state,
+                 hash_checks_mandatory, op_hash_test, &performer,
+                 minor_version);
+  delete performer;
+}
+
+
+TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageTest) {
+  DoSmallImageTest(false, false, false, -1, kSignatureGenerator,
+                   false, kInPlaceMinorPayloadVersion);
+}
+
+TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignaturePlaceholderTest) {
+  DoSmallImageTest(false, false, false, -1, kSignatureGeneratedPlaceholder,
+                   false, kInPlaceMinorPayloadVersion);
+}
+
+TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignaturePlaceholderMismatchTest) {
+  DeltaState state;
+  GenerateDeltaFile(false, false, false, -1,
+                    kSignatureGeneratedPlaceholderMismatch, &state,
+                    kInPlaceMinorPayloadVersion);
+}
+
+TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageChunksTest) {
+  DoSmallImageTest(false, false, false, kBlockSize, kSignatureGenerator,
+                   false, kInPlaceMinorPayloadVersion);
+}
+
+TEST(DeltaPerformerIntegrationTest, RunAsRootFullKernelSmallImageTest) {
+  DoSmallImageTest(true, false, false, -1, kSignatureGenerator,
+                   false, kInPlaceMinorPayloadVersion);
+}
+
+TEST(DeltaPerformerIntegrationTest, RunAsRootFullSmallImageTest) {
+  DoSmallImageTest(true, true, false, -1, kSignatureGenerator,
+                   true, kFullPayloadMinorVersion);
+}
+
+TEST(DeltaPerformerIntegrationTest, RunAsRootNoopSmallImageTest) {
+  DoSmallImageTest(false, false, true, -1, kSignatureGenerator,
+                   false, kInPlaceMinorPayloadVersion);
+}
+
+TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignNoneTest) {
+  DoSmallImageTest(false, false, false, -1, kSignatureNone,
+                   false, kInPlaceMinorPayloadVersion);
+}
+
+TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedTest) {
+  DoSmallImageTest(false, false, false, -1, kSignatureGenerated,
+                   true, kInPlaceMinorPayloadVersion);
+}
+
+TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedShellTest) {
+  DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShell,
+                   false, kInPlaceMinorPayloadVersion);
+}
+
+TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedShellBadKeyTest) {
+  DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellBadKey,
+                   false, kInPlaceMinorPayloadVersion);
+}
+
+TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedShellRotateCl1Test) {
+  DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellRotateCl1,
+                   false, kInPlaceMinorPayloadVersion);
+}
+
+TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedShellRotateCl2Test) {
+  DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellRotateCl2,
+                   false, kInPlaceMinorPayloadVersion);
+}
+
+TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSourceOpsTest) {
+  DoSmallImageTest(false, false, false, -1, kSignatureGenerator,
+                   false, kSourceMinorPayloadVersion);
+}
+
+TEST(DeltaPerformerIntegrationTest, RunAsRootMandatoryOperationHashMismatchTest) {
+  DoOperationHashMismatchTest(kInvalidOperationData, true);
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/delta_performer_unittest.cc b/payload_consumer/delta_performer_unittest.cc
new file mode 100644
index 0000000..c0a1a57
--- /dev/null
+++ b/payload_consumer/delta_performer_unittest.cc
@@ -0,0 +1,736 @@
+//
+// Copyright (C) 2012 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 "update_engine/payload_consumer/delta_performer.h"
+
+#include <inttypes.h>
+
+#include <string>
+#include <vector>
+
+#include <base/files/file_path.h>
+#include <base/files/file_util.h>
+#include <base/strings/string_number_conversions.h>
+#include <base/strings/string_util.h>
+#include <base/strings/stringprintf.h>
+#include <google/protobuf/repeated_field.h>
+#include <gtest/gtest.h>
+
+#include "update_engine/common/constants.h"
+#include "update_engine/common/fake_hardware.h"
+#include "update_engine/common/fake_prefs.h"
+#include "update_engine/common/test_utils.h"
+#include "update_engine/common/utils.h"
+#include "update_engine/fake_system_state.h"
+#include "update_engine/payload_consumer/payload_constants.h"
+#include "update_engine/payload_generator/bzip.h"
+#include "update_engine/payload_generator/extent_ranges.h"
+#include "update_engine/payload_generator/payload_file.h"
+#include "update_engine/payload_generator/payload_signer.h"
+#include "update_engine/update_metadata.pb.h"
+
+namespace chromeos_update_engine {
+
+using std::string;
+using std::vector;
+using test_utils::System;
+using test_utils::kRandomString;
+
+extern const char* kUnittestPrivateKeyPath;
+extern const char* kUnittestPublicKeyPath;
+
+static const char* kBogusMetadataSignature1 =
+    "awSFIUdUZz2VWFiR+ku0Pj00V7bPQPQFYQSXjEXr3vaw3TE4xHV5CraY3/YrZpBv"
+    "J5z4dSBskoeuaO1TNC/S6E05t+yt36tE4Fh79tMnJ/z9fogBDXWgXLEUyG78IEQr"
+    "YH6/eBsQGT2RJtBgXIXbZ9W+5G9KmGDoPOoiaeNsDuqHiBc/58OFsrxskH8E6vMS"
+    "BmMGGk82mvgzic7ApcoURbCGey1b3Mwne/hPZ/bb9CIyky8Og9IfFMdL2uAweOIR"
+    "fjoTeLYZpt+WN65Vu7jJ0cQN8e1y+2yka5112wpRf/LLtPgiAjEZnsoYpLUd7CoV"
+    "pLRtClp97kN2+tXGNBQqkA==";
+
+namespace {
+// Different options that determine what we should fill into the
+// install_plan.metadata_signature to simulate the contents received in the
+// Omaha response.
+enum MetadataSignatureTest {
+  kEmptyMetadataSignature,
+  kInvalidMetadataSignature,
+  kValidMetadataSignature,
+};
+
+// Compressed data without checksum, generated with:
+// echo -n a | xz -9 --check=none | hexdump -v -e '"    " 12/1 "0x%02x, " "\n"'
+const uint8_t kXzCompressedData[] = {
+    0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x00, 0xff, 0x12, 0xd9, 0x41,
+    0x02, 0x00, 0x21, 0x01, 0x1c, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x58, 0xcc,
+    0x01, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x01,
+    0xad, 0xa6, 0x58, 0x04, 0x06, 0x72, 0x9e, 0x7a, 0x01, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x59, 0x5a,
+};
+
+}  // namespace
+
+class DeltaPerformerTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    install_plan_.source_slot = 0;
+    install_plan_.target_slot = 1;
+  }
+
+  // Test helper placed where it can easily be friended from DeltaPerformer.
+  void RunManifestValidation(const DeltaArchiveManifest& manifest,
+                             uint64_t major_version,
+                             bool full_payload,
+                             ErrorCode expected) {
+    // The install plan is for Full or Delta.
+    install_plan_.is_full_update = full_payload;
+
+    // The Manifest we are validating.
+    performer_.manifest_.CopyFrom(manifest);
+    performer_.major_payload_version_ = major_version;
+
+    EXPECT_EQ(expected, performer_.ValidateManifest());
+  }
+
+  brillo::Blob GeneratePayload(const brillo::Blob& blob_data,
+                               const vector<AnnotatedOperation>& aops,
+                               bool sign_payload,
+                               uint64_t major_version,
+                               uint32_t minor_version) {
+    string blob_path;
+    EXPECT_TRUE(utils::MakeTempFile("Blob-XXXXXX", &blob_path, nullptr));
+    ScopedPathUnlinker blob_unlinker(blob_path);
+    EXPECT_TRUE(utils::WriteFile(blob_path.c_str(),
+                                 blob_data.data(),
+                                 blob_data.size()));
+
+    PayloadGenerationConfig config;
+    config.major_version = major_version;
+    config.minor_version = minor_version;
+
+    PayloadFile payload;
+    EXPECT_TRUE(payload.Init(config));
+
+    PartitionConfig old_part(kLegacyPartitionNameRoot);
+    PartitionConfig new_part(kLegacyPartitionNameRoot);
+    new_part.path = "/dev/zero";
+    new_part.size = 1234;
+
+    payload.AddPartition(old_part, new_part, aops);
+
+    // We include a kernel partition without operations.
+    old_part.name = kLegacyPartitionNameKernel;
+    new_part.name = kLegacyPartitionNameKernel;
+    new_part.size = 0;
+    payload.AddPartition(old_part, new_part, {});
+
+    string payload_path;
+    EXPECT_TRUE(utils::MakeTempFile("Payload-XXXXXX", &payload_path, nullptr));
+    ScopedPathUnlinker payload_unlinker(payload_path);
+    EXPECT_TRUE(payload.WritePayload(payload_path, blob_path,
+        sign_payload ? kUnittestPrivateKeyPath : "",
+        &install_plan_.metadata_size));
+
+    brillo::Blob payload_data;
+    EXPECT_TRUE(utils::ReadFile(payload_path, &payload_data));
+    return payload_data;
+  }
+
+  // Apply |payload_data| on partition specified in |source_path|.
+  brillo::Blob ApplyPayload(const brillo::Blob& payload_data,
+                            const string& source_path) {
+    return ApplyPayloadToData(payload_data, source_path, brillo::Blob());
+  }
+
+  // Apply the payload provided in |payload_data| reading from the |source_path|
+  // file and writing the contents to a new partition. The existing data in the
+  // new target file are set to |target_data| before applying the payload.
+  // Returns the result of the payload application.
+  brillo::Blob ApplyPayloadToData(const brillo::Blob& payload_data,
+                                  const string& source_path,
+                                  const brillo::Blob& target_data) {
+    string new_part;
+    EXPECT_TRUE(utils::MakeTempFile("Partition-XXXXXX", &new_part, nullptr));
+    ScopedPathUnlinker partition_unlinker(new_part);
+    EXPECT_TRUE(utils::WriteFile(new_part.c_str(), target_data.data(),
+                                 target_data.size()));
+
+    // We installed the operations only in the rootfs partition, but the
+    // delta performer needs to access all the partitions.
+    fake_system_state_.fake_boot_control()->SetPartitionDevice(
+        kLegacyPartitionNameRoot, install_plan_.target_slot, new_part);
+    fake_system_state_.fake_boot_control()->SetPartitionDevice(
+        kLegacyPartitionNameRoot, install_plan_.source_slot, source_path);
+    fake_system_state_.fake_boot_control()->SetPartitionDevice(
+        kLegacyPartitionNameKernel, install_plan_.target_slot, "/dev/null");
+    fake_system_state_.fake_boot_control()->SetPartitionDevice(
+        kLegacyPartitionNameKernel, install_plan_.source_slot, "/dev/null");
+
+    EXPECT_TRUE(performer_.Write(payload_data.data(), payload_data.size()));
+    EXPECT_EQ(0, performer_.Close());
+
+    brillo::Blob partition_data;
+    EXPECT_TRUE(utils::ReadFile(new_part, &partition_data));
+    return partition_data;
+  }
+
+  // Calls delta performer's Write method by pretending to pass in bytes from a
+  // delta file whose metadata size is actual_metadata_size and tests if all
+  // checks are correctly performed if the install plan contains
+  // expected_metadata_size and that the result of the parsing are as per
+  // hash_checks_mandatory flag.
+  void DoMetadataSizeTest(uint64_t expected_metadata_size,
+                          uint64_t actual_metadata_size,
+                          bool hash_checks_mandatory) {
+    install_plan_.hash_checks_mandatory = hash_checks_mandatory;
+
+    // Set a valid magic string and version number 1.
+    EXPECT_TRUE(performer_.Write("CrAU", 4));
+    uint64_t version = htobe64(kChromeOSMajorPayloadVersion);
+    EXPECT_TRUE(performer_.Write(&version, 8));
+
+    install_plan_.metadata_size = expected_metadata_size;
+    ErrorCode error_code;
+    // When filling in size in manifest, exclude the size of the 20-byte header.
+    uint64_t size_in_manifest = htobe64(actual_metadata_size - 20);
+    bool result = performer_.Write(&size_in_manifest, 8, &error_code);
+    if (expected_metadata_size == actual_metadata_size ||
+        !hash_checks_mandatory) {
+      EXPECT_TRUE(result);
+    } else {
+      EXPECT_FALSE(result);
+      EXPECT_EQ(ErrorCode::kDownloadInvalidMetadataSize, error_code);
+    }
+
+    EXPECT_LT(performer_.Close(), 0);
+  }
+
+  // Generates a valid delta file but tests the delta performer by suppling
+  // different metadata signatures as per metadata_signature_test flag and
+  // sees if the result of the parsing are as per hash_checks_mandatory flag.
+  void DoMetadataSignatureTest(MetadataSignatureTest metadata_signature_test,
+                               bool sign_payload,
+                               bool hash_checks_mandatory) {
+
+    // Loads the payload and parses the manifest.
+    brillo::Blob payload = GeneratePayload(brillo::Blob(),
+        vector<AnnotatedOperation>(), sign_payload,
+        kChromeOSMajorPayloadVersion, kFullPayloadMinorVersion);
+
+    LOG(INFO) << "Payload size: " << payload.size();
+
+    install_plan_.hash_checks_mandatory = hash_checks_mandatory;
+
+    DeltaPerformer::MetadataParseResult expected_result, actual_result;
+    ErrorCode expected_error, actual_error;
+
+    // Fill up the metadata signature in install plan according to the test.
+    switch (metadata_signature_test) {
+      case kEmptyMetadataSignature:
+        install_plan_.metadata_signature.clear();
+        expected_result = DeltaPerformer::kMetadataParseError;
+        expected_error = ErrorCode::kDownloadMetadataSignatureMissingError;
+        break;
+
+      case kInvalidMetadataSignature:
+        install_plan_.metadata_signature = kBogusMetadataSignature1;
+        expected_result = DeltaPerformer::kMetadataParseError;
+        expected_error = ErrorCode::kDownloadMetadataSignatureMismatch;
+        break;
+
+      case kValidMetadataSignature:
+      default:
+        // Set the install plan's metadata size to be the same as the one
+        // in the manifest so that we pass the metadata size checks. Only
+        // then we can get to manifest signature checks.
+        ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
+            payload.data(),
+            install_plan_.metadata_size,
+            kUnittestPrivateKeyPath,
+            &install_plan_.metadata_signature));
+        EXPECT_FALSE(install_plan_.metadata_signature.empty());
+        expected_result = DeltaPerformer::kMetadataParseSuccess;
+        expected_error = ErrorCode::kSuccess;
+        break;
+    }
+
+    // Ignore the expected result/error if hash checks are not mandatory.
+    if (!hash_checks_mandatory) {
+      expected_result = DeltaPerformer::kMetadataParseSuccess;
+      expected_error = ErrorCode::kSuccess;
+    }
+
+    // Use the public key corresponding to the private key used above to
+    // sign the metadata.
+    EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
+    performer_.set_public_key_path(kUnittestPublicKeyPath);
+
+    // Init actual_error with an invalid value so that we make sure
+    // ParsePayloadMetadata properly populates it in all cases.
+    actual_error = ErrorCode::kUmaReportedMax;
+    actual_result = performer_.ParsePayloadMetadata(payload, &actual_error);
+
+    EXPECT_EQ(expected_result, actual_result);
+    EXPECT_EQ(expected_error, actual_error);
+
+    // Check that the parsed metadata size is what's expected. This test
+    // implicitly confirms that the metadata signature is valid, if required.
+    EXPECT_EQ(install_plan_.metadata_size, performer_.GetMetadataSize());
+  }
+
+  void SetSupportedMajorVersion(uint64_t major_version) {
+    performer_.supported_major_version_ = major_version;
+  }
+  FakePrefs prefs_;
+  InstallPlan install_plan_;
+  FakeSystemState fake_system_state_;
+  DeltaPerformer performer_{&prefs_, &fake_system_state_, &install_plan_};
+};
+
+TEST_F(DeltaPerformerTest, FullPayloadWriteTest) {
+  install_plan_.is_full_update = true;
+  brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
+                                            std::end(kRandomString));
+  expected_data.resize(4096);  // block size
+  vector<AnnotatedOperation> aops;
+  AnnotatedOperation aop;
+  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
+  aop.op.set_data_offset(0);
+  aop.op.set_data_length(expected_data.size());
+  aop.op.set_type(InstallOperation::REPLACE);
+  aops.push_back(aop);
+
+  brillo::Blob payload_data = GeneratePayload(expected_data, aops, false,
+      kChromeOSMajorPayloadVersion, kFullPayloadMinorVersion);
+
+  EXPECT_EQ(expected_data, ApplyPayload(payload_data, "/dev/null"));
+}
+
+TEST_F(DeltaPerformerTest, ReplaceOperationTest) {
+  brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
+                                            std::end(kRandomString));
+  expected_data.resize(4096);  // block size
+  vector<AnnotatedOperation> aops;
+  AnnotatedOperation aop;
+  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
+  aop.op.set_data_offset(0);
+  aop.op.set_data_length(expected_data.size());
+  aop.op.set_type(InstallOperation::REPLACE);
+  aops.push_back(aop);
+
+  brillo::Blob payload_data = GeneratePayload(expected_data, aops, false,
+                                              kChromeOSMajorPayloadVersion,
+                                              kSourceMinorPayloadVersion);
+
+  EXPECT_EQ(expected_data, ApplyPayload(payload_data, "/dev/null"));
+}
+
+TEST_F(DeltaPerformerTest, ReplaceBzOperationTest) {
+  brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
+                                            std::end(kRandomString));
+  expected_data.resize(4096);  // block size
+  brillo::Blob bz_data;
+  EXPECT_TRUE(BzipCompress(expected_data, &bz_data));
+
+  vector<AnnotatedOperation> aops;
+  AnnotatedOperation aop;
+  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
+  aop.op.set_data_offset(0);
+  aop.op.set_data_length(bz_data.size());
+  aop.op.set_type(InstallOperation::REPLACE_BZ);
+  aops.push_back(aop);
+
+  brillo::Blob payload_data = GeneratePayload(bz_data, aops, false,
+                                              kChromeOSMajorPayloadVersion,
+                                              kSourceMinorPayloadVersion);
+
+  EXPECT_EQ(expected_data, ApplyPayload(payload_data, "/dev/null"));
+}
+
+TEST_F(DeltaPerformerTest, ReplaceXzOperationTest) {
+  brillo::Blob xz_data(std::begin(kXzCompressedData),
+                         std::end(kXzCompressedData));
+  // The compressed xz data contains only a single "a", but the operation should
+  // pad the rest of the two blocks with zeros.
+  brillo::Blob expected_data = brillo::Blob(4096, 0);
+  expected_data[0] = 'a';
+
+  AnnotatedOperation aop;
+  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
+  aop.op.set_data_offset(0);
+  aop.op.set_data_length(xz_data.size());
+  aop.op.set_type(InstallOperation::REPLACE_XZ);
+  vector<AnnotatedOperation> aops = {aop};
+
+  brillo::Blob payload_data = GeneratePayload(xz_data, aops, false,
+                                              kChromeOSMajorPayloadVersion,
+                                              kSourceMinorPayloadVersion);
+
+  EXPECT_EQ(expected_data, ApplyPayload(payload_data, "/dev/null"));
+}
+
+TEST_F(DeltaPerformerTest, ZeroOperationTest) {
+  brillo::Blob existing_data = brillo::Blob(4096 * 10, 'a');
+  brillo::Blob expected_data = existing_data;
+  // Blocks 4, 5 and 7 should have zeros instead of 'a' after the operation is
+  // applied.
+  std::fill(expected_data.data() + 4096 * 4, expected_data.data() + 4096 * 6,
+            0);
+  std::fill(expected_data.data() + 4096 * 7, expected_data.data() + 4096 * 8,
+            0);
+
+  AnnotatedOperation aop;
+  *(aop.op.add_dst_extents()) = ExtentForRange(4, 2);
+  *(aop.op.add_dst_extents()) = ExtentForRange(7, 1);
+  aop.op.set_type(InstallOperation::ZERO);
+  vector<AnnotatedOperation> aops = {aop};
+
+  brillo::Blob payload_data = GeneratePayload(brillo::Blob(), aops, false,
+                                              kChromeOSMajorPayloadVersion,
+                                              kSourceMinorPayloadVersion);
+
+  EXPECT_EQ(expected_data,
+            ApplyPayloadToData(payload_data, "/dev/null", existing_data));
+}
+
+TEST_F(DeltaPerformerTest, SourceCopyOperationTest) {
+  brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
+                                            std::end(kRandomString));
+  expected_data.resize(4096);  // block size
+  vector<AnnotatedOperation> aops;
+  AnnotatedOperation aop;
+  *(aop.op.add_src_extents()) = ExtentForRange(0, 1);
+  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
+  aop.op.set_type(InstallOperation::SOURCE_COPY);
+  aops.push_back(aop);
+
+  brillo::Blob payload_data = GeneratePayload(brillo::Blob(), aops, false,
+                                              kChromeOSMajorPayloadVersion,
+                                              kSourceMinorPayloadVersion);
+  string source_path;
+  EXPECT_TRUE(utils::MakeTempFile("Source-XXXXXX",
+                                  &source_path, nullptr));
+  ScopedPathUnlinker path_unlinker(source_path);
+  EXPECT_TRUE(utils::WriteFile(source_path.c_str(),
+                               expected_data.data(),
+                               expected_data.size()));
+
+  EXPECT_EQ(expected_data, ApplyPayload(payload_data, source_path));
+}
+
+TEST_F(DeltaPerformerTest, ExtentsToByteStringTest) {
+  uint64_t test[] = {1, 1, 4, 2, 0, 1};
+  COMPILE_ASSERT(arraysize(test) % 2 == 0, array_size_uneven);
+  const uint64_t block_size = 4096;
+  const uint64_t file_length = 4 * block_size - 13;
+
+  google::protobuf::RepeatedPtrField<Extent> extents;
+  for (size_t i = 0; i < arraysize(test); i += 2) {
+    *(extents.Add()) = ExtentForRange(test[i], test[i + 1]);
+  }
+
+  string expected_output = "4096:4096,16384:8192,0:4083";
+  string actual_output;
+  EXPECT_TRUE(DeltaPerformer::ExtentsToBsdiffPositionsString(extents,
+                                                             block_size,
+                                                             file_length,
+                                                             &actual_output));
+  EXPECT_EQ(expected_output, actual_output);
+}
+
+TEST_F(DeltaPerformerTest, ValidateManifestFullGoodTest) {
+  // The Manifest we are validating.
+  DeltaArchiveManifest manifest;
+  manifest.mutable_new_kernel_info();
+  manifest.mutable_new_rootfs_info();
+  manifest.set_minor_version(kFullPayloadMinorVersion);
+
+  RunManifestValidation(manifest, kChromeOSMajorPayloadVersion, true,
+                        ErrorCode::kSuccess);
+}
+
+TEST_F(DeltaPerformerTest, ValidateManifestDeltaGoodTest) {
+  // The Manifest we are validating.
+  DeltaArchiveManifest manifest;
+  manifest.mutable_old_kernel_info();
+  manifest.mutable_old_rootfs_info();
+  manifest.mutable_new_kernel_info();
+  manifest.mutable_new_rootfs_info();
+  manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
+
+  RunManifestValidation(manifest, kChromeOSMajorPayloadVersion, false,
+                        ErrorCode::kSuccess);
+}
+
+TEST_F(DeltaPerformerTest, ValidateManifestFullUnsetMinorVersion) {
+  // The Manifest we are validating.
+  DeltaArchiveManifest manifest;
+
+  RunManifestValidation(manifest, DeltaPerformer::kSupportedMajorPayloadVersion,
+                        true, ErrorCode::kSuccess);
+}
+
+TEST_F(DeltaPerformerTest, ValidateManifestDeltaUnsetMinorVersion) {
+  // The Manifest we are validating.
+  DeltaArchiveManifest manifest;
+
+  RunManifestValidation(manifest, DeltaPerformer::kSupportedMajorPayloadVersion,
+                        false, ErrorCode::kUnsupportedMinorPayloadVersion);
+}
+
+TEST_F(DeltaPerformerTest, ValidateManifestFullOldKernelTest) {
+  // The Manifest we are validating.
+  DeltaArchiveManifest manifest;
+  manifest.mutable_old_kernel_info();
+  manifest.mutable_new_kernel_info();
+  manifest.mutable_new_rootfs_info();
+  manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
+
+  RunManifestValidation(manifest, kChromeOSMajorPayloadVersion, true,
+                        ErrorCode::kPayloadMismatchedType);
+}
+
+TEST_F(DeltaPerformerTest, ValidateManifestFullOldRootfsTest) {
+  // The Manifest we are validating.
+  DeltaArchiveManifest manifest;
+  manifest.mutable_old_rootfs_info();
+  manifest.mutable_new_kernel_info();
+  manifest.mutable_new_rootfs_info();
+  manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
+
+  RunManifestValidation(manifest, kChromeOSMajorPayloadVersion, true,
+                        ErrorCode::kPayloadMismatchedType);
+}
+
+TEST_F(DeltaPerformerTest, ValidateManifestFullPartitionUpdateTest) {
+  // The Manifest we are validating.
+  DeltaArchiveManifest manifest;
+  PartitionUpdate* partition = manifest.add_partitions();
+  partition->mutable_old_partition_info();
+  partition->mutable_new_partition_info();
+  manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
+
+  RunManifestValidation(manifest, kBrilloMajorPayloadVersion, true,
+                        ErrorCode::kPayloadMismatchedType);
+}
+
+TEST_F(DeltaPerformerTest, ValidateManifestBadMinorVersion) {
+  // The Manifest we are validating.
+  DeltaArchiveManifest manifest;
+
+  // Generate a bad version number.
+  manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion +
+                             10000);
+
+  RunManifestValidation(manifest, DeltaPerformer::kSupportedMajorPayloadVersion,
+                        false, ErrorCode::kUnsupportedMinorPayloadVersion);
+}
+
+TEST_F(DeltaPerformerTest, BrilloMetadataSignatureSizeTest) {
+  EXPECT_TRUE(performer_.Write(kDeltaMagic, sizeof(kDeltaMagic)));
+
+  uint64_t major_version = htobe64(kBrilloMajorPayloadVersion);
+  EXPECT_TRUE(performer_.Write(&major_version, 8));
+
+  uint64_t manifest_size = rand() % 256;
+  uint64_t manifest_size_be = htobe64(manifest_size);
+  EXPECT_TRUE(performer_.Write(&manifest_size_be, 8));
+
+  uint32_t metadata_signature_size = rand() % 256;
+  uint32_t metadata_signature_size_be = htobe32(metadata_signature_size);
+  EXPECT_TRUE(performer_.Write(&metadata_signature_size_be, 4));
+
+  EXPECT_LT(performer_.Close(), 0);
+
+  EXPECT_TRUE(performer_.IsHeaderParsed());
+  EXPECT_EQ(kBrilloMajorPayloadVersion, performer_.GetMajorVersion());
+  uint64_t manifest_offset;
+  EXPECT_TRUE(performer_.GetManifestOffset(&manifest_offset));
+  EXPECT_EQ(24, manifest_offset);  // 4 + 8 + 8 + 4
+  EXPECT_EQ(manifest_offset + manifest_size, performer_.GetMetadataSize());
+  EXPECT_EQ(metadata_signature_size, performer_.metadata_signature_size_);
+}
+
+TEST_F(DeltaPerformerTest, BrilloVerifyMetadataSignatureTest) {
+  brillo::Blob payload_data = GeneratePayload({}, {}, true,
+                                              kBrilloMajorPayloadVersion,
+                                              kSourceMinorPayloadVersion);
+  install_plan_.hash_checks_mandatory = true;
+  // Just set these value so that we can use ValidateMetadataSignature directly.
+  performer_.major_payload_version_ = kBrilloMajorPayloadVersion;
+  performer_.metadata_size_ = install_plan_.metadata_size;
+  uint64_t signature_length;
+  EXPECT_TRUE(PayloadSigner::SignatureBlobLength({kUnittestPrivateKeyPath},
+                                                 &signature_length));
+  performer_.metadata_signature_size_ = signature_length;
+  performer_.set_public_key_path(kUnittestPublicKeyPath);
+  EXPECT_EQ(ErrorCode::kSuccess,
+            performer_.ValidateMetadataSignature(payload_data));
+}
+
+TEST_F(DeltaPerformerTest, BadDeltaMagicTest) {
+  EXPECT_TRUE(performer_.Write("junk", 4));
+  EXPECT_FALSE(performer_.Write("morejunk", 8));
+  EXPECT_LT(performer_.Close(), 0);
+}
+
+TEST_F(DeltaPerformerTest, WriteUpdatesPayloadState) {
+  EXPECT_CALL(*(fake_system_state_.mock_payload_state()),
+              DownloadProgress(4)).Times(1);
+  EXPECT_CALL(*(fake_system_state_.mock_payload_state()),
+              DownloadProgress(8)).Times(1);
+
+  EXPECT_TRUE(performer_.Write("junk", 4));
+  EXPECT_FALSE(performer_.Write("morejunk", 8));
+  EXPECT_LT(performer_.Close(), 0);
+}
+
+TEST_F(DeltaPerformerTest, MissingMandatoryMetadataSizeTest) {
+  DoMetadataSizeTest(0, 75456, true);
+}
+
+TEST_F(DeltaPerformerTest, MissingNonMandatoryMetadataSizeTest) {
+  DoMetadataSizeTest(0, 123456, false);
+}
+
+TEST_F(DeltaPerformerTest, InvalidMandatoryMetadataSizeTest) {
+  DoMetadataSizeTest(13000, 140000, true);
+}
+
+TEST_F(DeltaPerformerTest, InvalidNonMandatoryMetadataSizeTest) {
+  DoMetadataSizeTest(40000, 50000, false);
+}
+
+TEST_F(DeltaPerformerTest, ValidMandatoryMetadataSizeTest) {
+  DoMetadataSizeTest(85376, 85376, true);
+}
+
+TEST_F(DeltaPerformerTest, MandatoryEmptyMetadataSignatureTest) {
+  DoMetadataSignatureTest(kEmptyMetadataSignature, true, true);
+}
+
+TEST_F(DeltaPerformerTest, NonMandatoryEmptyMetadataSignatureTest) {
+  DoMetadataSignatureTest(kEmptyMetadataSignature, true, false);
+}
+
+TEST_F(DeltaPerformerTest, MandatoryInvalidMetadataSignatureTest) {
+  DoMetadataSignatureTest(kInvalidMetadataSignature, true, true);
+}
+
+TEST_F(DeltaPerformerTest, NonMandatoryInvalidMetadataSignatureTest) {
+  DoMetadataSignatureTest(kInvalidMetadataSignature, true, false);
+}
+
+TEST_F(DeltaPerformerTest, MandatoryValidMetadataSignature1Test) {
+  DoMetadataSignatureTest(kValidMetadataSignature, false, true);
+}
+
+TEST_F(DeltaPerformerTest, MandatoryValidMetadataSignature2Test) {
+  DoMetadataSignatureTest(kValidMetadataSignature, true, true);
+}
+
+TEST_F(DeltaPerformerTest, NonMandatoryValidMetadataSignatureTest) {
+  DoMetadataSignatureTest(kValidMetadataSignature, true, false);
+}
+
+TEST_F(DeltaPerformerTest, UsePublicKeyFromResponse) {
+  base::FilePath key_path;
+
+  // The result of the GetPublicKeyResponse() method is based on three things
+  //
+  //  1. Whether it's an official build; and
+  //  2. Whether the Public RSA key to be used is in the root filesystem; and
+  //  3. Whether the response has a public key
+  //
+  // We test all eight combinations to ensure that we only use the
+  // public key in the response if
+  //
+  //  a. it's not an official build; and
+  //  b. there is no key in the root filesystem.
+
+  FakeHardware* fake_hardware = fake_system_state_.fake_hardware();
+
+  string temp_dir;
+  EXPECT_TRUE(utils::MakeTempDirectory("PublicKeyFromResponseTests.XXXXXX",
+                                       &temp_dir));
+  string non_existing_file = temp_dir + "/non-existing";
+  string existing_file = temp_dir + "/existing";
+  EXPECT_EQ(0, System(base::StringPrintf("touch %s", existing_file.c_str())));
+
+  // Non-official build, non-existing public-key, key in response -> true
+  fake_hardware->SetIsOfficialBuild(false);
+  performer_.public_key_path_ = non_existing_file;
+  install_plan_.public_key_rsa = "VGVzdAo="; // result of 'echo "Test" | base64'
+  EXPECT_TRUE(performer_.GetPublicKeyFromResponse(&key_path));
+  EXPECT_FALSE(key_path.empty());
+  EXPECT_EQ(unlink(key_path.value().c_str()), 0);
+  // Same with official build -> false
+  fake_hardware->SetIsOfficialBuild(true);
+  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
+
+  // Non-official build, existing public-key, key in response -> false
+  fake_hardware->SetIsOfficialBuild(false);
+  performer_.public_key_path_ = existing_file;
+  install_plan_.public_key_rsa = "VGVzdAo="; // result of 'echo "Test" | base64'
+  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
+  // Same with official build -> false
+  fake_hardware->SetIsOfficialBuild(true);
+  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
+
+  // Non-official build, non-existing public-key, no key in response -> false
+  fake_hardware->SetIsOfficialBuild(false);
+  performer_.public_key_path_ = non_existing_file;
+  install_plan_.public_key_rsa = "";
+  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
+  // Same with official build -> false
+  fake_hardware->SetIsOfficialBuild(true);
+  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
+
+  // Non-official build, existing public-key, no key in response -> false
+  fake_hardware->SetIsOfficialBuild(false);
+  performer_.public_key_path_ = existing_file;
+  install_plan_.public_key_rsa = "";
+  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
+  // Same with official build -> false
+  fake_hardware->SetIsOfficialBuild(true);
+  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
+
+  // Non-official build, non-existing public-key, key in response
+  // but invalid base64 -> false
+  fake_hardware->SetIsOfficialBuild(false);
+  performer_.public_key_path_ = non_existing_file;
+  install_plan_.public_key_rsa = "not-valid-base64";
+  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
+
+  EXPECT_TRUE(base::DeleteFile(base::FilePath(temp_dir), true));
+}
+
+TEST_F(DeltaPerformerTest, ConfVersionsMatch) {
+  // Test that the versions in update_engine.conf that is installed to the
+  // image match the supported delta versions in the update engine.
+  uint32_t minor_version;
+  brillo::KeyValueStore store;
+  EXPECT_TRUE(store.Load(base::FilePath("update_engine.conf")));
+  EXPECT_TRUE(utils::GetMinorVersion(store, &minor_version));
+  EXPECT_EQ(DeltaPerformer::kSupportedMinorPayloadVersion, minor_version);
+
+  string major_version_str;
+  uint64_t major_version;
+  EXPECT_TRUE(store.GetString("PAYLOAD_MAJOR_VERSION", &major_version_str));
+  EXPECT_TRUE(base::StringToUint64(major_version_str, &major_version));
+  EXPECT_EQ(DeltaPerformer::kSupportedMajorPayloadVersion, major_version);
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/download_action.cc b/payload_consumer/download_action.cc
new file mode 100644
index 0000000..0136f49
--- /dev/null
+++ b/payload_consumer/download_action.cc
@@ -0,0 +1,320 @@
+//
+// Copyright (C) 2011 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 "update_engine/payload_consumer/download_action.h"
+
+#include <errno.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include <base/files/file_path.h>
+#include <base/strings/stringprintf.h>
+
+#include "update_engine/common/action_pipe.h"
+#include "update_engine/common/boot_control_interface.h"
+#include "update_engine/common/utils.h"
+#include "update_engine/omaha_request_params.h"
+#include "update_engine/p2p_manager.h"
+#include "update_engine/payload_state_interface.h"
+
+using base::FilePath;
+using std::string;
+using std::vector;
+
+namespace chromeos_update_engine {
+
+DownloadAction::DownloadAction(PrefsInterface* prefs,
+                               SystemState* system_state,
+                               HttpFetcher* http_fetcher)
+    : prefs_(prefs),
+      system_state_(system_state),
+      http_fetcher_(http_fetcher),
+      writer_(nullptr),
+      code_(ErrorCode::kSuccess),
+      delegate_(nullptr),
+      bytes_received_(0),
+      p2p_sharing_fd_(-1),
+      p2p_visible_(true) {}
+
+DownloadAction::~DownloadAction() {}
+
+void DownloadAction::CloseP2PSharingFd(bool delete_p2p_file) {
+  if (p2p_sharing_fd_ != -1) {
+    if (close(p2p_sharing_fd_) != 0) {
+      PLOG(ERROR) << "Error closing p2p sharing fd";
+    }
+    p2p_sharing_fd_ = -1;
+  }
+
+  if (delete_p2p_file) {
+    FilePath path =
+      system_state_->p2p_manager()->FileGetPath(p2p_file_id_);
+    if (unlink(path.value().c_str()) != 0) {
+      PLOG(ERROR) << "Error deleting p2p file " << path.value();
+    } else {
+      LOG(INFO) << "Deleted p2p file " << path.value();
+    }
+  }
+
+  // Don't use p2p from this point onwards.
+  p2p_file_id_.clear();
+}
+
+bool DownloadAction::SetupP2PSharingFd() {
+  P2PManager *p2p_manager = system_state_->p2p_manager();
+
+  if (!p2p_manager->FileShare(p2p_file_id_, install_plan_.payload_size)) {
+    LOG(ERROR) << "Unable to share file via p2p";
+    CloseP2PSharingFd(true);  // delete p2p file
+    return false;
+  }
+
+  // File has already been created (and allocated, xattrs been
+  // populated etc.) by FileShare() so just open it for writing.
+  FilePath path = p2p_manager->FileGetPath(p2p_file_id_);
+  p2p_sharing_fd_ = open(path.value().c_str(), O_WRONLY);
+  if (p2p_sharing_fd_ == -1) {
+    PLOG(ERROR) << "Error opening file " << path.value();
+    CloseP2PSharingFd(true);  // Delete p2p file.
+    return false;
+  }
+
+  // Ensure file to share is world-readable, otherwise
+  // p2p-server and p2p-http-server can't access it.
+  //
+  // (Q: Why doesn't the file have mode 0644 already? A: Because
+  // the process-wide umask is set to 0700 in main.cc.)
+  if (fchmod(p2p_sharing_fd_, 0644) != 0) {
+    PLOG(ERROR) << "Error setting mode 0644 on " << path.value();
+    CloseP2PSharingFd(true);  // Delete p2p file.
+    return false;
+  }
+
+  // All good.
+  LOG(INFO) << "Writing payload contents to " << path.value();
+  p2p_manager->FileGetVisible(p2p_file_id_, &p2p_visible_);
+  return true;
+}
+
+void DownloadAction::WriteToP2PFile(const void* data,
+                                    size_t length,
+                                    off_t file_offset) {
+  if (p2p_sharing_fd_ == -1) {
+    if (!SetupP2PSharingFd())
+      return;
+  }
+
+  // Check that the file is at least |file_offset| bytes long - if
+  // it's not something is wrong and we must immediately delete the
+  // file to avoid propagating this problem to other peers.
+  //
+  // How can this happen? It could be that we're resuming an update
+  // after a system crash... in this case, it could be that
+  //
+  //  1. the p2p file didn't get properly synced to stable storage; or
+  //  2. the file was deleted at bootup (it's in /var/cache after all); or
+  //  3. other reasons
+  off_t p2p_size = utils::FileSize(p2p_sharing_fd_);
+  if (p2p_size < 0) {
+    PLOG(ERROR) << "Error getting file status for p2p file";
+    CloseP2PSharingFd(true);  // Delete p2p file.
+    return;
+  }
+  if (p2p_size < file_offset) {
+    LOG(ERROR) << "Wanting to write to file offset " << file_offset
+               << " but existing p2p file is only " << p2p_size
+               << " bytes.";
+    CloseP2PSharingFd(true);  // Delete p2p file.
+    return;
+  }
+
+  off_t cur_file_offset = lseek(p2p_sharing_fd_, file_offset, SEEK_SET);
+  if (cur_file_offset != static_cast<off_t>(file_offset)) {
+    PLOG(ERROR) << "Error seeking to position "
+                << file_offset << " in p2p file";
+    CloseP2PSharingFd(true);  // Delete p2p file.
+  } else {
+    // OK, seeking worked, now write the data
+    ssize_t bytes_written = write(p2p_sharing_fd_, data, length);
+    if (bytes_written != static_cast<ssize_t>(length)) {
+      PLOG(ERROR) << "Error writing "
+                  << length << " bytes at file offset "
+                  << file_offset << " in p2p file";
+      CloseP2PSharingFd(true);  // Delete p2p file.
+    }
+  }
+}
+
+void DownloadAction::PerformAction() {
+  http_fetcher_->set_delegate(this);
+
+  // Get the InstallPlan and read it
+  CHECK(HasInputObject());
+  install_plan_ = GetInputObject();
+  bytes_received_ = 0;
+
+  install_plan_.Dump();
+
+  LOG(INFO) << "Marking new slot as unbootable";
+  if (!system_state_->boot_control()->MarkSlotUnbootable(
+          install_plan_.target_slot)) {
+    LOG(WARNING) << "Unable to mark new slot "
+                 << BootControlInterface::SlotName(install_plan_.target_slot)
+                 << ". Proceeding with the update anyway.";
+  }
+
+  if (writer_) {
+    LOG(INFO) << "Using writer for test.";
+  } else {
+    delta_performer_.reset(new DeltaPerformer(prefs_,
+                                              system_state_,
+                                              &install_plan_));
+    writer_ = delta_performer_.get();
+  }
+  if (delegate_) {
+    delegate_->SetDownloadStatus(true);  // Set to active.
+  }
+
+  if (system_state_ != nullptr) {
+    const PayloadStateInterface* payload_state = system_state_->payload_state();
+    string file_id = utils::CalculateP2PFileId(install_plan_.payload_hash,
+                                               install_plan_.payload_size);
+    if (payload_state->GetUsingP2PForSharing()) {
+      // If we're sharing the update, store the file_id to convey
+      // that we should write to the file.
+      p2p_file_id_ = file_id;
+      LOG(INFO) << "p2p file id: " << p2p_file_id_;
+    } else {
+      // Even if we're not sharing the update, it could be that
+      // there's a partial file from a previous attempt with the same
+      // hash. If this is the case, we NEED to clean it up otherwise
+      // we're essentially timing out other peers downloading from us
+      // (since we're never going to complete the file).
+      FilePath path = system_state_->p2p_manager()->FileGetPath(file_id);
+      if (!path.empty()) {
+        if (unlink(path.value().c_str()) != 0) {
+          PLOG(ERROR) << "Error deleting p2p file " << path.value();
+        } else {
+          LOG(INFO) << "Deleting partial p2p file " << path.value()
+                    << " since we're not using p2p to share.";
+        }
+      }
+    }
+
+    // Tweak timeouts on the HTTP fetcher if we're downloading from a
+    // local peer.
+    if (payload_state->GetUsingP2PForDownloading() &&
+        payload_state->GetP2PUrl() == install_plan_.download_url) {
+      LOG(INFO) << "Tweaking HTTP fetcher since we're downloading via p2p";
+      http_fetcher_->set_low_speed_limit(kDownloadP2PLowSpeedLimitBps,
+                                         kDownloadP2PLowSpeedTimeSeconds);
+      http_fetcher_->set_max_retry_count(kDownloadP2PMaxRetryCount);
+      http_fetcher_->set_connect_timeout(kDownloadP2PConnectTimeoutSeconds);
+    }
+  }
+
+  http_fetcher_->BeginTransfer(install_plan_.download_url);
+}
+
+void DownloadAction::TerminateProcessing() {
+  if (writer_) {
+    writer_->Close();
+    writer_ = nullptr;
+  }
+  if (delegate_) {
+    delegate_->SetDownloadStatus(false);  // Set to inactive.
+  }
+  CloseP2PSharingFd(false);  // Keep p2p file.
+  // Terminates the transfer. The action is terminated, if necessary, when the
+  // TransferTerminated callback is received.
+  http_fetcher_->TerminateTransfer();
+}
+
+void DownloadAction::SeekToOffset(off_t offset) {
+  bytes_received_ = offset;
+}
+
+void DownloadAction::ReceivedBytes(HttpFetcher* fetcher,
+                                   const void* bytes,
+                                   size_t length) {
+  // Note that bytes_received_ is the current offset.
+  if (!p2p_file_id_.empty()) {
+    WriteToP2PFile(bytes, length, bytes_received_);
+  }
+
+  bytes_received_ += length;
+  if (delegate_)
+    delegate_->BytesReceived(bytes_received_, install_plan_.payload_size);
+  if (writer_ && !writer_->Write(bytes, length, &code_)) {
+    LOG(ERROR) << "Error " << code_ << " in DeltaPerformer's Write method when "
+               << "processing the received payload -- Terminating processing";
+    // Delete p2p file, if applicable.
+    if (!p2p_file_id_.empty())
+      CloseP2PSharingFd(true);
+    // Don't tell the action processor that the action is complete until we get
+    // the TransferTerminated callback. Otherwise, this and the HTTP fetcher
+    // objects may get destroyed before all callbacks are complete.
+    TerminateProcessing();
+    return;
+  }
+
+  // Call p2p_manager_->FileMakeVisible() when we've successfully
+  // verified the manifest!
+  if (!p2p_visible_ &&
+      delta_performer_.get() && delta_performer_->IsManifestValid()) {
+    LOG(INFO) << "Manifest has been validated. Making p2p file visible.";
+    system_state_->p2p_manager()->FileMakeVisible(p2p_file_id_);
+    p2p_visible_ = true;
+  }
+}
+
+void DownloadAction::TransferComplete(HttpFetcher* fetcher, bool successful) {
+  if (writer_) {
+    LOG_IF(WARNING, writer_->Close() != 0) << "Error closing the writer.";
+    writer_ = nullptr;
+  }
+  if (delegate_) {
+    delegate_->SetDownloadStatus(false);  // Set to inactive.
+  }
+  ErrorCode code =
+      successful ? ErrorCode::kSuccess : ErrorCode::kDownloadTransferError;
+  if (code == ErrorCode::kSuccess && delta_performer_.get()) {
+    code = delta_performer_->VerifyPayload(install_plan_.payload_hash,
+                                           install_plan_.payload_size);
+    if (code != ErrorCode::kSuccess) {
+      LOG(ERROR) << "Download of " << install_plan_.download_url
+                 << " failed due to payload verification error.";
+      // Delete p2p file, if applicable.
+      if (!p2p_file_id_.empty())
+        CloseP2PSharingFd(true);
+    }
+  }
+
+  // Write the path to the output pipe if we're successful.
+  if (code == ErrorCode::kSuccess && HasOutputPipe())
+    SetOutputObject(install_plan_);
+  processor_->ActionComplete(this, code);
+}
+
+void DownloadAction::TransferTerminated(HttpFetcher *fetcher) {
+  if (code_ != ErrorCode::kSuccess) {
+    processor_->ActionComplete(this, code_);
+  }
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/download_action.h b/payload_consumer/download_action.h
new file mode 100644
index 0000000..c0f0688
--- /dev/null
+++ b/payload_consumer/download_action.h
@@ -0,0 +1,166 @@
+//
+// Copyright (C) 2011 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.
+//
+
+#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_DOWNLOAD_ACTION_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_DOWNLOAD_ACTION_H_
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <memory>
+#include <string>
+
+#include <curl/curl.h>
+
+#include "update_engine/common/action.h"
+#include "update_engine/common/http_fetcher.h"
+#include "update_engine/payload_consumer/delta_performer.h"
+#include "update_engine/payload_consumer/install_plan.h"
+#include "update_engine/system_state.h"
+
+// The Download Action downloads a specified url to disk. The url should point
+// to an update in a delta payload format. The payload will be piped into a
+// DeltaPerformer that will apply the delta to the disk.
+
+namespace chromeos_update_engine {
+
+class DownloadActionDelegate {
+ public:
+  virtual ~DownloadActionDelegate() = default;
+
+  // Called right before starting the download with |active| set to
+  // true. Called after completing the download with |active| set to
+  // false.
+  virtual void SetDownloadStatus(bool active) = 0;
+
+  // Called periodically after bytes are received. This method will be
+  // invoked only if the download is active. |bytes_received| is the
+  // number of bytes downloaded thus far. |total| is the number of
+  // bytes expected.
+  virtual void BytesReceived(uint64_t bytes_received, uint64_t total) = 0;
+};
+
+class PrefsInterface;
+
+class DownloadAction : public InstallPlanAction,
+                       public HttpFetcherDelegate {
+ public:
+  // Takes ownership of the passed in HttpFetcher. Useful for testing.
+  // A good calling pattern is:
+  // DownloadAction(prefs, system_state, new WhateverHttpFetcher);
+  DownloadAction(PrefsInterface* prefs,
+                 SystemState* system_state,
+                 HttpFetcher* http_fetcher);
+  ~DownloadAction() override;
+  void PerformAction() override;
+  void TerminateProcessing() override;
+
+  // Testing
+  void SetTestFileWriter(FileWriter* writer) {
+    writer_ = writer;
+  }
+
+  int GetHTTPResponseCode() { return http_fetcher_->http_response_code(); }
+
+  // Debugging/logging
+  static std::string StaticType() { return "DownloadAction"; }
+  std::string Type() const override { return StaticType(); }
+
+  // HttpFetcherDelegate methods (see http_fetcher.h)
+  void ReceivedBytes(HttpFetcher* fetcher,
+                     const void* bytes, size_t length) override;
+  void SeekToOffset(off_t offset) override;
+  void TransferComplete(HttpFetcher* fetcher, bool successful) override;
+  void TransferTerminated(HttpFetcher* fetcher) override;
+
+  DownloadActionDelegate* delegate() const { return delegate_; }
+  void set_delegate(DownloadActionDelegate* delegate) {
+    delegate_ = delegate;
+  }
+
+  HttpFetcher* http_fetcher() { return http_fetcher_.get(); }
+
+  // Returns the p2p file id for the file being written or the empty
+  // string if we're not writing to a p2p file.
+  std::string p2p_file_id() { return p2p_file_id_; }
+
+ private:
+  // Closes the file descriptor for the p2p file being written and
+  // clears |p2p_file_id_| to indicate that we're no longer sharing
+  // the file. If |delete_p2p_file| is True, also deletes the file.
+  // If there is no p2p file descriptor, this method does nothing.
+  void CloseP2PSharingFd(bool delete_p2p_file);
+
+  // Starts sharing the p2p file. Must be called before
+  // WriteToP2PFile(). Returns True if this worked.
+  bool SetupP2PSharingFd();
+
+  // Writes |length| bytes of payload from |data| into |file_offset|
+  // of the p2p file. Also does sanity checks; for example ensures we
+  // don't end up with a file with holes in it.
+  //
+  // This method does nothing if SetupP2PSharingFd() hasn't been
+  // called or if CloseP2PSharingFd() has been called.
+  void WriteToP2PFile(const void* data, size_t length, off_t file_offset);
+
+  // The InstallPlan passed in
+  InstallPlan install_plan_;
+
+  // Update Engine preference store.
+  PrefsInterface* prefs_;
+
+  // Global context for the system.
+  SystemState* system_state_;
+
+  // Pointer to the HttpFetcher that does the http work.
+  std::unique_ptr<HttpFetcher> http_fetcher_;
+
+  // The FileWriter that downloaded data should be written to. It will
+  // either point to *decompressing_file_writer_ or *delta_performer_.
+  FileWriter* writer_;
+
+  std::unique_ptr<DeltaPerformer> delta_performer_;
+
+  // Used by TransferTerminated to figure if this action terminated itself or
+  // was terminated by the action processor.
+  ErrorCode code_;
+
+  // For reporting status to outsiders
+  DownloadActionDelegate* delegate_;
+  uint64_t bytes_received_;
+
+  // The file-id for the file we're sharing or the empty string
+  // if we're not using p2p to share.
+  std::string p2p_file_id_;
+
+  // The file descriptor for the p2p file used for caching the payload or -1
+  // if we're not using p2p to share.
+  int p2p_sharing_fd_;
+
+  // Set to |false| if p2p file is not visible.
+  bool p2p_visible_;
+
+  DISALLOW_COPY_AND_ASSIGN(DownloadAction);
+};
+
+// We want to be sure that we're compiled with large file support on linux,
+// just in case we find ourselves downloading large images.
+COMPILE_ASSERT(8 == sizeof(off_t), off_t_not_64_bit);
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_DOWNLOAD_ACTION_H_
diff --git a/payload_consumer/download_action_unittest.cc b/payload_consumer/download_action_unittest.cc
new file mode 100644
index 0000000..3bef196
--- /dev/null
+++ b/payload_consumer/download_action_unittest.cc
@@ -0,0 +1,634 @@
+//
+// Copyright (C) 2011 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 "update_engine/payload_consumer/download_action.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <base/bind.h>
+#include <base/files/file_path.h>
+#include <base/files/file_util.h>
+#include <base/location.h>
+#include <base/strings/stringprintf.h>
+#include <brillo/bind_lambda.h>
+#include <brillo/message_loops/fake_message_loop.h>
+#include <brillo/message_loops/message_loop.h>
+
+#include "update_engine/common/action_pipe.h"
+#include "update_engine/common/hash_calculator.h"
+#include "update_engine/common/mock_http_fetcher.h"
+#include "update_engine/common/mock_prefs.h"
+#include "update_engine/common/test_utils.h"
+#include "update_engine/common/utils.h"
+#include "update_engine/fake_p2p_manager_configuration.h"
+#include "update_engine/fake_system_state.h"
+#include "update_engine/update_manager/fake_update_manager.h"
+
+namespace chromeos_update_engine {
+
+using base::FilePath;
+using base::ReadFileToString;
+using base::WriteFile;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+using test_utils::ScopedTempFile;
+using testing::AtLeast;
+using testing::InSequence;
+using testing::Return;
+using testing::_;
+
+class DownloadActionTest : public ::testing::Test { };
+
+namespace {
+class DownloadActionDelegateMock : public DownloadActionDelegate {
+ public:
+  MOCK_METHOD1(SetDownloadStatus, void(bool active));
+  MOCK_METHOD2(BytesReceived, void(uint64_t bytes_received, uint64_t total));
+};
+
+class DownloadActionTestProcessorDelegate : public ActionProcessorDelegate {
+ public:
+  explicit DownloadActionTestProcessorDelegate(ErrorCode expected_code)
+      : processing_done_called_(false),
+        expected_code_(expected_code) {}
+  ~DownloadActionTestProcessorDelegate() override {
+    EXPECT_TRUE(processing_done_called_);
+  }
+  void ProcessingDone(const ActionProcessor* processor,
+                      ErrorCode code) override {
+    brillo::MessageLoop::current()->BreakLoop();
+    brillo::Blob found_data;
+    ASSERT_TRUE(utils::ReadFile(path_, &found_data));
+    if (expected_code_ != ErrorCode::kDownloadWriteError) {
+      ASSERT_EQ(expected_data_.size(), found_data.size());
+      for (unsigned i = 0; i < expected_data_.size(); i++) {
+        EXPECT_EQ(expected_data_[i], found_data[i]);
+      }
+    }
+    processing_done_called_ = true;
+  }
+
+  void ActionCompleted(ActionProcessor* processor,
+                       AbstractAction* action,
+                       ErrorCode code) override {
+    const string type = action->Type();
+    if (type == DownloadAction::StaticType()) {
+      EXPECT_EQ(expected_code_, code);
+    } else {
+      EXPECT_EQ(ErrorCode::kSuccess, code);
+    }
+  }
+
+  string path_;
+  brillo::Blob expected_data_;
+  bool processing_done_called_;
+  ErrorCode expected_code_;
+};
+
+class TestDirectFileWriter : public DirectFileWriter {
+ public:
+  TestDirectFileWriter() : fail_write_(0), current_write_(0) {}
+  void set_fail_write(int fail_write) { fail_write_ = fail_write; }
+
+  virtual bool Write(const void* bytes, size_t count) {
+    if (++current_write_ == fail_write_) {
+      return false;
+    }
+    return DirectFileWriter::Write(bytes, count);
+  }
+
+ private:
+  // If positive, fail on the |fail_write_| call to Write.
+  int fail_write_;
+  int current_write_;
+};
+
+void StartProcessorInRunLoop(ActionProcessor* processor,
+                             MockHttpFetcher* http_fetcher) {
+  processor->StartProcessing();
+  http_fetcher->SetOffset(1);
+}
+
+void TestWithData(const brillo::Blob& data,
+                  int fail_write,
+                  bool use_download_delegate) {
+  brillo::FakeMessageLoop loop(nullptr);
+  loop.SetAsCurrent();
+  FakeSystemState fake_system_state;
+
+  // TODO(adlr): see if we need a different file for build bots
+  ScopedTempFile output_temp_file;
+  TestDirectFileWriter writer;
+  EXPECT_EQ(0, writer.Open(output_temp_file.GetPath().c_str(),
+                           O_WRONLY | O_CREAT,
+                           0));
+  writer.set_fail_write(fail_write);
+
+  // We pull off the first byte from data and seek past it.
+  string hash = HashCalculator::HashOfBytes(&data[1], data.size() - 1);
+  uint64_t size = data.size();
+  InstallPlan install_plan(false,
+                           false,
+                           "",
+                           size,
+                           hash,
+                           0,
+                           "",
+                           "");
+  install_plan.source_slot = 0;
+  install_plan.target_slot = 1;
+  // We mark both slots as bootable. Only the target slot should be unbootable
+  // after the download starts.
+  fake_system_state.fake_boot_control()->SetSlotBootable(
+      install_plan.source_slot, true);
+  fake_system_state.fake_boot_control()->SetSlotBootable(
+      install_plan.target_slot, true);
+  ObjectFeederAction<InstallPlan> feeder_action;
+  feeder_action.set_obj(install_plan);
+  MockPrefs prefs;
+  MockHttpFetcher* http_fetcher = new MockHttpFetcher(data.data(),
+                                                      data.size(),
+                                                      nullptr);
+  // takes ownership of passed in HttpFetcher
+  DownloadAction download_action(&prefs, &fake_system_state, http_fetcher);
+  download_action.SetTestFileWriter(&writer);
+  BondActions(&feeder_action, &download_action);
+  DownloadActionDelegateMock download_delegate;
+  if (use_download_delegate) {
+    InSequence s;
+    download_action.set_delegate(&download_delegate);
+    EXPECT_CALL(download_delegate, SetDownloadStatus(true)).Times(1);
+    if (data.size() > kMockHttpFetcherChunkSize)
+      EXPECT_CALL(download_delegate,
+                  BytesReceived(1 + kMockHttpFetcherChunkSize, _));
+    EXPECT_CALL(download_delegate, BytesReceived(_, _)).Times(AtLeast(1));
+    EXPECT_CALL(download_delegate, SetDownloadStatus(false)).Times(1);
+  }
+  ErrorCode expected_code = ErrorCode::kSuccess;
+  if (fail_write > 0)
+    expected_code = ErrorCode::kDownloadWriteError;
+  DownloadActionTestProcessorDelegate delegate(expected_code);
+  delegate.expected_data_ = brillo::Blob(data.begin() + 1, data.end());
+  delegate.path_ = output_temp_file.GetPath();
+  ActionProcessor processor;
+  processor.set_delegate(&delegate);
+  processor.EnqueueAction(&feeder_action);
+  processor.EnqueueAction(&download_action);
+
+  loop.PostTask(FROM_HERE,
+                base::Bind(&StartProcessorInRunLoop, &processor, http_fetcher));
+  loop.Run();
+  EXPECT_FALSE(loop.PendingTasks());
+
+  EXPECT_TRUE(fake_system_state.fake_boot_control()->IsSlotBootable(
+      install_plan.source_slot));
+  EXPECT_FALSE(fake_system_state.fake_boot_control()->IsSlotBootable(
+      install_plan.target_slot));
+}
+}  // namespace
+
+TEST(DownloadActionTest, SimpleTest) {
+  brillo::Blob small;
+  const char* foo = "foo";
+  small.insert(small.end(), foo, foo + strlen(foo));
+  TestWithData(small,
+               0,  // fail_write
+               true);  // use_download_delegate
+}
+
+TEST(DownloadActionTest, LargeTest) {
+  brillo::Blob big(5 * kMockHttpFetcherChunkSize);
+  char c = '0';
+  for (unsigned int i = 0; i < big.size(); i++) {
+    big[i] = c;
+    c = ('9' == c) ? '0' : c + 1;
+  }
+  TestWithData(big,
+               0,  // fail_write
+               true);  // use_download_delegate
+}
+
+TEST(DownloadActionTest, FailWriteTest) {
+  brillo::Blob big(5 * kMockHttpFetcherChunkSize);
+  char c = '0';
+  for (unsigned int i = 0; i < big.size(); i++) {
+    big[i] = c;
+    c = ('9' == c) ? '0' : c + 1;
+  }
+  TestWithData(big,
+               2,  // fail_write
+               true);  // use_download_delegate
+}
+
+TEST(DownloadActionTest, NoDownloadDelegateTest) {
+  brillo::Blob small;
+  const char* foo = "foofoo";
+  small.insert(small.end(), foo, foo + strlen(foo));
+  TestWithData(small,
+               0,  // fail_write
+               false);  // use_download_delegate
+}
+
+namespace {
+class TerminateEarlyTestProcessorDelegate : public ActionProcessorDelegate {
+ public:
+  void ProcessingStopped(const ActionProcessor* processor) {
+    brillo::MessageLoop::current()->BreakLoop();
+  }
+};
+
+void TerminateEarlyTestStarter(ActionProcessor* processor) {
+  processor->StartProcessing();
+  CHECK(processor->IsRunning());
+  processor->StopProcessing();
+}
+
+void TestTerminateEarly(bool use_download_delegate) {
+  brillo::FakeMessageLoop loop(nullptr);
+  loop.SetAsCurrent();
+
+  brillo::Blob data(kMockHttpFetcherChunkSize +
+                      kMockHttpFetcherChunkSize / 2);
+  memset(data.data(), 0, data.size());
+
+  ScopedTempFile temp_file;
+  {
+    DirectFileWriter writer;
+    EXPECT_EQ(0, writer.Open(temp_file.GetPath().c_str(),
+                             O_WRONLY | O_CREAT,
+                             0));
+
+    // takes ownership of passed in HttpFetcher
+    ObjectFeederAction<InstallPlan> feeder_action;
+    InstallPlan install_plan(false, false, "", 0, "", 0, "", "");
+    feeder_action.set_obj(install_plan);
+    FakeSystemState fake_system_state_;
+    MockPrefs prefs;
+    DownloadAction download_action(&prefs, &fake_system_state_,
+                                   new MockHttpFetcher(data.data(),
+                                                       data.size(),
+                                                       nullptr));
+    download_action.SetTestFileWriter(&writer);
+    DownloadActionDelegateMock download_delegate;
+    if (use_download_delegate) {
+      InSequence s;
+      download_action.set_delegate(&download_delegate);
+      EXPECT_CALL(download_delegate, SetDownloadStatus(true)).Times(1);
+      EXPECT_CALL(download_delegate, SetDownloadStatus(false)).Times(1);
+    }
+    TerminateEarlyTestProcessorDelegate delegate;
+    ActionProcessor processor;
+    processor.set_delegate(&delegate);
+    processor.EnqueueAction(&feeder_action);
+    processor.EnqueueAction(&download_action);
+    BondActions(&feeder_action, &download_action);
+
+    loop.PostTask(FROM_HERE,
+                  base::Bind(&TerminateEarlyTestStarter, &processor));
+    loop.Run();
+    EXPECT_FALSE(loop.PendingTasks());
+  }
+
+  // 1 or 0 chunks should have come through
+  const off_t resulting_file_size(utils::FileSize(temp_file.GetPath()));
+  EXPECT_GE(resulting_file_size, 0);
+  if (resulting_file_size != 0)
+    EXPECT_EQ(kMockHttpFetcherChunkSize, resulting_file_size);
+}
+
+}  // namespace
+
+TEST(DownloadActionTest, TerminateEarlyTest) {
+  TestTerminateEarly(true);
+}
+
+TEST(DownloadActionTest, TerminateEarlyNoDownloadDelegateTest) {
+  TestTerminateEarly(false);
+}
+
+class DownloadActionTestAction;
+
+template<>
+class ActionTraits<DownloadActionTestAction> {
+ public:
+  typedef InstallPlan OutputObjectType;
+  typedef InstallPlan InputObjectType;
+};
+
+// This is a simple Action class for testing.
+class DownloadActionTestAction : public Action<DownloadActionTestAction> {
+ public:
+  DownloadActionTestAction() : did_run_(false) {}
+  typedef InstallPlan InputObjectType;
+  typedef InstallPlan OutputObjectType;
+  ActionPipe<InstallPlan>* in_pipe() { return in_pipe_.get(); }
+  ActionPipe<InstallPlan>* out_pipe() { return out_pipe_.get(); }
+  ActionProcessor* processor() { return processor_; }
+  void PerformAction() {
+    did_run_ = true;
+    ASSERT_TRUE(HasInputObject());
+    EXPECT_TRUE(expected_input_object_ == GetInputObject());
+    ASSERT_TRUE(processor());
+    processor()->ActionComplete(this, ErrorCode::kSuccess);
+  }
+  string Type() const { return "DownloadActionTestAction"; }
+  InstallPlan expected_input_object_;
+  bool did_run_;
+};
+
+namespace {
+// This class is an ActionProcessorDelegate that simply terminates the
+// run loop when the ActionProcessor has completed processing. It's used
+// only by the test PassObjectOutTest.
+class PassObjectOutTestProcessorDelegate : public ActionProcessorDelegate {
+ public:
+  void ProcessingDone(const ActionProcessor* processor, ErrorCode code) {
+    brillo::MessageLoop::current()->BreakLoop();
+  }
+};
+
+}  // namespace
+
+TEST(DownloadActionTest, PassObjectOutTest) {
+  brillo::FakeMessageLoop loop(nullptr);
+  loop.SetAsCurrent();
+
+  DirectFileWriter writer;
+  EXPECT_EQ(0, writer.Open("/dev/null", O_WRONLY | O_CREAT, 0));
+
+  // takes ownership of passed in HttpFetcher
+  InstallPlan install_plan(false,
+                           false,
+                           "",
+                           1,
+                           HashCalculator::HashOfString("x"),
+                           0,
+                           "",
+                           "");
+  ObjectFeederAction<InstallPlan> feeder_action;
+  feeder_action.set_obj(install_plan);
+  MockPrefs prefs;
+  FakeSystemState fake_system_state_;
+  DownloadAction download_action(&prefs, &fake_system_state_,
+                                 new MockHttpFetcher("x", 1, nullptr));
+  download_action.SetTestFileWriter(&writer);
+
+  DownloadActionTestAction test_action;
+  test_action.expected_input_object_ = install_plan;
+  BondActions(&feeder_action, &download_action);
+  BondActions(&download_action, &test_action);
+
+  ActionProcessor processor;
+  PassObjectOutTestProcessorDelegate delegate;
+  processor.set_delegate(&delegate);
+  processor.EnqueueAction(&feeder_action);
+  processor.EnqueueAction(&download_action);
+  processor.EnqueueAction(&test_action);
+
+  loop.PostTask(FROM_HERE,
+                base::Bind([&processor] { processor.StartProcessing(); }));
+  loop.Run();
+  EXPECT_FALSE(loop.PendingTasks());
+
+  EXPECT_EQ(true, test_action.did_run_);
+}
+
+// Test fixture for P2P tests.
+class P2PDownloadActionTest : public testing::Test {
+ protected:
+  P2PDownloadActionTest()
+    : start_at_offset_(0),
+      fake_um_(fake_system_state_.fake_clock()) {}
+
+  ~P2PDownloadActionTest() override {}
+
+  // Derived from testing::Test.
+  void SetUp() override {
+    loop_.SetAsCurrent();
+  }
+
+  // Derived from testing::Test.
+  void TearDown() override {
+    EXPECT_FALSE(loop_.PendingTasks());
+  }
+
+  // To be called by tests to setup the download. The
+  // |starting_offset| parameter is for where to resume.
+  void SetupDownload(off_t starting_offset) {
+    start_at_offset_ = starting_offset;
+    // Prepare data 10 kB of data.
+    data_.clear();
+    for (unsigned int i = 0; i < 10 * 1000; i++)
+      data_ += 'a' + (i % 25);
+
+    // Setup p2p.
+    FakeP2PManagerConfiguration *test_conf = new FakeP2PManagerConfiguration();
+    p2p_manager_.reset(P2PManager::Construct(
+        test_conf, nullptr, &fake_um_, "cros_au", 3,
+        base::TimeDelta::FromDays(5)));
+    fake_system_state_.set_p2p_manager(p2p_manager_.get());
+  }
+
+  // To be called by tests to perform the download. The
+  // |use_p2p_to_share| parameter is used to indicate whether the
+  // payload should be shared via p2p.
+  void StartDownload(bool use_p2p_to_share) {
+    EXPECT_CALL(*fake_system_state_.mock_payload_state(),
+                GetUsingP2PForSharing())
+        .WillRepeatedly(Return(use_p2p_to_share));
+
+    ScopedTempFile output_temp_file;
+    TestDirectFileWriter writer;
+    EXPECT_EQ(0, writer.Open(output_temp_file.GetPath().c_str(),
+                             O_WRONLY | O_CREAT,
+                             0));
+    InstallPlan install_plan(false,
+                             false,
+                             "",
+                             data_.length(),
+                             "1234hash",
+                             0,
+                             "",
+                             "");
+    ObjectFeederAction<InstallPlan> feeder_action;
+    feeder_action.set_obj(install_plan);
+    MockPrefs prefs;
+    http_fetcher_ = new MockHttpFetcher(data_.c_str(),
+                                        data_.length(),
+                                        nullptr);
+    // Note that DownloadAction takes ownership of the passed in HttpFetcher.
+    download_action_.reset(new DownloadAction(&prefs, &fake_system_state_,
+                                              http_fetcher_));
+    download_action_->SetTestFileWriter(&writer);
+    BondActions(&feeder_action, download_action_.get());
+    DownloadActionTestProcessorDelegate delegate(ErrorCode::kSuccess);
+    delegate.expected_data_ = brillo::Blob(data_.begin() + start_at_offset_,
+                                           data_.end());
+    delegate.path_ = output_temp_file.GetPath();
+    processor_.set_delegate(&delegate);
+    processor_.EnqueueAction(&feeder_action);
+    processor_.EnqueueAction(download_action_.get());
+
+    loop_.PostTask(FROM_HERE, base::Bind(
+        &P2PDownloadActionTest::StartProcessorInRunLoopForP2P,
+        base::Unretained(this)));
+    loop_.Run();
+  }
+
+  // Mainloop used to make StartDownload() synchronous.
+  brillo::FakeMessageLoop loop_{nullptr};
+
+  // The DownloadAction instance under test.
+  unique_ptr<DownloadAction> download_action_;
+
+  // The HttpFetcher used in the test.
+  MockHttpFetcher* http_fetcher_;
+
+  // The P2PManager used in the test.
+  unique_ptr<P2PManager> p2p_manager_;
+
+  // The ActionProcessor used for running the actions.
+  ActionProcessor processor_;
+
+  // A fake system state.
+  FakeSystemState fake_system_state_;
+
+  // The data being downloaded.
+  string data_;
+
+ private:
+  // Callback used in StartDownload() method.
+  void StartProcessorInRunLoopForP2P() {
+    processor_.StartProcessing();
+    http_fetcher_->SetOffset(start_at_offset_);
+  }
+
+  // The requested starting offset passed to SetupDownload().
+  off_t start_at_offset_;
+
+  chromeos_update_manager::FakeUpdateManager fake_um_;
+};
+
+TEST_F(P2PDownloadActionTest, IsWrittenTo) {
+  if (!test_utils::IsXAttrSupported(FilePath("/tmp"))) {
+    LOG(WARNING) << "Skipping test because /tmp does not support xattr. "
+                 << "Please update your system to support this feature.";
+    return;
+  }
+
+  SetupDownload(0);     // starting_offset
+  StartDownload(true);  // use_p2p_to_share
+
+  // Check the p2p file and its content matches what was sent.
+  string file_id = download_action_->p2p_file_id();
+  EXPECT_NE("", file_id);
+  EXPECT_EQ(data_.length(), p2p_manager_->FileGetSize(file_id));
+  EXPECT_EQ(data_.length(), p2p_manager_->FileGetExpectedSize(file_id));
+  string p2p_file_contents;
+  EXPECT_TRUE(ReadFileToString(p2p_manager_->FileGetPath(file_id),
+                               &p2p_file_contents));
+  EXPECT_EQ(data_, p2p_file_contents);
+}
+
+TEST_F(P2PDownloadActionTest, DeleteIfHoleExists) {
+  if (!test_utils::IsXAttrSupported(FilePath("/tmp"))) {
+    LOG(WARNING) << "Skipping test because /tmp does not support xattr. "
+                 << "Please update your system to support this feature.";
+    return;
+  }
+
+  SetupDownload(1000);  // starting_offset
+  StartDownload(true);  // use_p2p_to_share
+
+  // DownloadAction should convey that the file is not being shared.
+  // and that we don't have any p2p files.
+  EXPECT_EQ(download_action_->p2p_file_id(), "");
+  EXPECT_EQ(p2p_manager_->CountSharedFiles(), 0);
+}
+
+TEST_F(P2PDownloadActionTest, CanAppend) {
+  if (!test_utils::IsXAttrSupported(FilePath("/tmp"))) {
+    LOG(WARNING) << "Skipping test because /tmp does not support xattr. "
+                 << "Please update your system to support this feature.";
+    return;
+  }
+
+  SetupDownload(1000);  // starting_offset
+
+  // Prepare the file with existing data before starting to write to
+  // it via DownloadAction.
+  string file_id = utils::CalculateP2PFileId("1234hash", data_.length());
+  ASSERT_TRUE(p2p_manager_->FileShare(file_id, data_.length()));
+  string existing_data;
+  for (unsigned int i = 0; i < 1000; i++)
+    existing_data += '0' + (i % 10);
+  ASSERT_EQ(WriteFile(p2p_manager_->FileGetPath(file_id), existing_data.c_str(),
+                      1000), 1000);
+
+  StartDownload(true);  // use_p2p_to_share
+
+  // DownloadAction should convey the same file_id and the file should
+  // have the expected size.
+  EXPECT_EQ(download_action_->p2p_file_id(), file_id);
+  EXPECT_EQ(p2p_manager_->FileGetSize(file_id), data_.length());
+  EXPECT_EQ(p2p_manager_->FileGetExpectedSize(file_id), data_.length());
+  string p2p_file_contents;
+  // Check that the first 1000 bytes wasn't touched and that we
+  // appended the remaining as appropriate.
+  EXPECT_TRUE(ReadFileToString(p2p_manager_->FileGetPath(file_id),
+                               &p2p_file_contents));
+  EXPECT_EQ(existing_data, p2p_file_contents.substr(0, 1000));
+  EXPECT_EQ(data_.substr(1000), p2p_file_contents.substr(1000));
+}
+
+TEST_F(P2PDownloadActionTest, DeletePartialP2PFileIfResumingWithoutP2P) {
+  if (!test_utils::IsXAttrSupported(FilePath("/tmp"))) {
+    LOG(WARNING) << "Skipping test because /tmp does not support xattr. "
+                 << "Please update your system to support this feature.";
+    return;
+  }
+
+  SetupDownload(1000);  // starting_offset
+
+  // Prepare the file with all existing data before starting to write
+  // to it via DownloadAction.
+  string file_id = utils::CalculateP2PFileId("1234hash", data_.length());
+  ASSERT_TRUE(p2p_manager_->FileShare(file_id, data_.length()));
+  string existing_data;
+  for (unsigned int i = 0; i < 1000; i++)
+    existing_data += '0' + (i % 10);
+  ASSERT_EQ(WriteFile(p2p_manager_->FileGetPath(file_id), existing_data.c_str(),
+                      1000), 1000);
+
+  // Check that the file is there.
+  EXPECT_EQ(p2p_manager_->FileGetSize(file_id), 1000);
+  EXPECT_EQ(p2p_manager_->CountSharedFiles(), 1);
+
+  StartDownload(false);  // use_p2p_to_share
+
+  // DownloadAction should have deleted the p2p file. Check that it's gone.
+  EXPECT_EQ(p2p_manager_->FileGetSize(file_id), -1);
+  EXPECT_EQ(p2p_manager_->CountSharedFiles(), 0);
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/extent_writer.cc b/payload_consumer/extent_writer.cc
new file mode 100644
index 0000000..5501e22
--- /dev/null
+++ b/payload_consumer/extent_writer.cc
@@ -0,0 +1,71 @@
+//
+// Copyright (C) 2009 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 "update_engine/payload_consumer/extent_writer.h"
+
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <algorithm>
+
+#include "update_engine/common/utils.h"
+#include "update_engine/payload_consumer/payload_constants.h"
+
+using std::min;
+
+namespace chromeos_update_engine {
+
+bool DirectExtentWriter::Write(const void* bytes, size_t count) {
+  if (count == 0)
+    return true;
+  const char* c_bytes = reinterpret_cast<const char*>(bytes);
+  size_t bytes_written = 0;
+  while (count - bytes_written > 0) {
+    TEST_AND_RETURN_FALSE(next_extent_index_ < extents_.size());
+    uint64_t bytes_remaining_next_extent =
+        extents_[next_extent_index_].num_blocks() * block_size_ -
+        extent_bytes_written_;
+    CHECK_NE(bytes_remaining_next_extent, static_cast<uint64_t>(0));
+    size_t bytes_to_write =
+        static_cast<size_t>(min(static_cast<uint64_t>(count - bytes_written),
+                                bytes_remaining_next_extent));
+    TEST_AND_RETURN_FALSE(bytes_to_write > 0);
+
+    if (extents_[next_extent_index_].start_block() != kSparseHole) {
+      const off64_t offset =
+          extents_[next_extent_index_].start_block() * block_size_ +
+          extent_bytes_written_;
+      TEST_AND_RETURN_FALSE_ERRNO(fd_->Seek(offset, SEEK_SET) !=
+                                  static_cast<off64_t>(-1));
+      TEST_AND_RETURN_FALSE(
+          utils::WriteAll(fd_, c_bytes + bytes_written, bytes_to_write));
+    }
+    bytes_written += bytes_to_write;
+    extent_bytes_written_ += bytes_to_write;
+    if (bytes_remaining_next_extent == bytes_to_write) {
+      // We filled this extent
+      CHECK_EQ(extent_bytes_written_,
+               extents_[next_extent_index_].num_blocks() * block_size_);
+      // move to next extent
+      extent_bytes_written_ = 0;
+      next_extent_index_++;
+    }
+  }
+  return true;
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/extent_writer.h b/payload_consumer/extent_writer.h
new file mode 100644
index 0000000..6484ebf
--- /dev/null
+++ b/payload_consumer/extent_writer.h
@@ -0,0 +1,134 @@
+//
+// Copyright (C) 2009 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.
+//
+
+#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_EXTENT_WRITER_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_EXTENT_WRITER_H_
+
+#include <vector>
+
+#include <base/logging.h>
+#include <brillo/secure_blob.h>
+
+#include "update_engine/common/utils.h"
+#include "update_engine/payload_consumer/file_descriptor.h"
+#include "update_engine/update_metadata.pb.h"
+
+// ExtentWriter is an abstract class which synchronously writes to a given
+// file descriptor at the extents given.
+
+namespace chromeos_update_engine {
+
+class ExtentWriter {
+ public:
+  ExtentWriter() = default;
+  virtual ~ExtentWriter() {
+    LOG_IF(ERROR, !end_called_) << "End() not called on ExtentWriter.";
+  }
+
+  // Returns true on success.
+  virtual bool Init(FileDescriptorPtr fd,
+                    const std::vector<Extent>& extents,
+                    uint32_t block_size) = 0;
+
+  // Returns true on success.
+  virtual bool Write(const void* bytes, size_t count) = 0;
+
+  // Should be called when all writing is complete. Returns true on success.
+  // The fd is not closed. Caller is responsible for closing it.
+  bool End() {
+    end_called_ = true;
+    return EndImpl();
+  }
+  virtual bool EndImpl() = 0;
+ private:
+  bool end_called_{false};
+};
+
+// DirectExtentWriter is probably the simplest ExtentWriter implementation.
+// It writes the data directly into the extents.
+
+class DirectExtentWriter : public ExtentWriter {
+ public:
+  DirectExtentWriter() = default;
+  ~DirectExtentWriter() override = default;
+
+  bool Init(FileDescriptorPtr fd,
+            const std::vector<Extent>& extents,
+            uint32_t block_size) override {
+    fd_ = fd;
+    block_size_ = block_size;
+    extents_ = extents;
+    return true;
+  }
+  bool Write(const void* bytes, size_t count) override;
+  bool EndImpl() override { return true; }
+
+ private:
+  FileDescriptorPtr fd_{nullptr};
+
+  size_t block_size_{0};
+  // Bytes written into next_extent_index_ thus far
+  uint64_t extent_bytes_written_{0};
+  std::vector<Extent> extents_;
+  // The next call to write should correspond to extents_[next_extent_index_]
+  std::vector<Extent>::size_type next_extent_index_{0};
+};
+
+// Takes an underlying ExtentWriter to which all operations are delegated.
+// When End() is called, ZeroPadExtentWriter ensures that the total number
+// of bytes written is a multiple of block_size_. If not, it writes zeros
+// to pad as needed.
+
+class ZeroPadExtentWriter : public ExtentWriter {
+ public:
+  explicit ZeroPadExtentWriter(
+      std::unique_ptr<ExtentWriter> underlying_extent_writer)
+      : underlying_extent_writer_(std::move(underlying_extent_writer)) {}
+  ~ZeroPadExtentWriter() override = default;
+
+  bool Init(FileDescriptorPtr fd,
+            const std::vector<Extent>& extents,
+            uint32_t block_size) override {
+    block_size_ = block_size;
+    return underlying_extent_writer_->Init(fd, extents, block_size);
+  }
+  bool Write(const void* bytes, size_t count) override {
+    if (underlying_extent_writer_->Write(bytes, count)) {
+      bytes_written_mod_block_size_ += count;
+      bytes_written_mod_block_size_ %= block_size_;
+      return true;
+    }
+    return false;
+  }
+  bool EndImpl() override {
+    if (bytes_written_mod_block_size_) {
+      const size_t write_size = block_size_ - bytes_written_mod_block_size_;
+      brillo::Blob zeros(write_size, 0);
+      TEST_AND_RETURN_FALSE(underlying_extent_writer_->Write(zeros.data(),
+                                                             write_size));
+    }
+    return underlying_extent_writer_->End();
+  }
+
+ private:
+  std::unique_ptr<ExtentWriter> underlying_extent_writer_;
+  size_t block_size_{0};
+  size_t bytes_written_mod_block_size_{0};
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_EXTENT_WRITER_H_
diff --git a/payload_consumer/extent_writer_unittest.cc b/payload_consumer/extent_writer_unittest.cc
new file mode 100644
index 0000000..24ea5bf
--- /dev/null
+++ b/payload_consumer/extent_writer_unittest.cc
@@ -0,0 +1,270 @@
+//
+// Copyright (C) 2009 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 "update_engine/payload_consumer/extent_writer.h"
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include <brillo/make_unique_ptr.h>
+#include <brillo/secure_blob.h>
+#include <gtest/gtest.h>
+
+#include "update_engine/common/test_utils.h"
+#include "update_engine/common/utils.h"
+#include "update_engine/payload_consumer/payload_constants.h"
+
+using chromeos_update_engine::test_utils::ExpectVectorsEq;
+using std::min;
+using std::string;
+using std::vector;
+
+namespace chromeos_update_engine {
+
+COMPILE_ASSERT(sizeof(off_t) == 8, off_t_not_64_bit);
+
+namespace {
+const char kPathTemplate[] = "./ExtentWriterTest-file.XXXXXX";
+const size_t kBlockSize = 4096;
+}
+
+class ExtentWriterTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    memcpy(path_, kPathTemplate, sizeof(kPathTemplate));
+    fd_.reset(new EintrSafeFileDescriptor);
+    int fd = mkstemp(path_);
+    ASSERT_TRUE(fd_->Open(path_, O_RDWR, 0600));
+    close(fd);
+  }
+  void TearDown() override {
+    fd_->Close();
+    unlink(path_);
+  }
+
+  // Writes data to an extent writer in 'chunk_size' chunks with
+  // the first chunk of size first_chunk_size. It calculates what the
+  // resultant file should look like and ensure that the extent writer
+  // wrote the file correctly.
+  void WriteAlignedExtents(size_t chunk_size, size_t first_chunk_size);
+  void TestZeroPad(bool aligned_size);
+
+  FileDescriptorPtr fd_;
+  char path_[sizeof(kPathTemplate)];
+};
+
+TEST_F(ExtentWriterTest, SimpleTest) {
+  vector<Extent> extents;
+  Extent extent;
+  extent.set_start_block(1);
+  extent.set_num_blocks(1);
+  extents.push_back(extent);
+
+  const string bytes = "1234";
+
+  DirectExtentWriter direct_writer;
+  EXPECT_TRUE(direct_writer.Init(fd_, extents, kBlockSize));
+  EXPECT_TRUE(direct_writer.Write(bytes.data(), bytes.size()));
+  EXPECT_TRUE(direct_writer.End());
+
+  EXPECT_EQ(kBlockSize + bytes.size(), utils::FileSize(path_));
+
+  brillo::Blob result_file;
+  EXPECT_TRUE(utils::ReadFile(path_, &result_file));
+
+  brillo::Blob expected_file(kBlockSize);
+  expected_file.insert(expected_file.end(),
+                       bytes.data(), bytes.data() + bytes.size());
+  ExpectVectorsEq(expected_file, result_file);
+}
+
+TEST_F(ExtentWriterTest, ZeroLengthTest) {
+  vector<Extent> extents;
+  Extent extent;
+  extent.set_start_block(1);
+  extent.set_num_blocks(1);
+  extents.push_back(extent);
+
+  DirectExtentWriter direct_writer;
+  EXPECT_TRUE(direct_writer.Init(fd_, extents, kBlockSize));
+  EXPECT_TRUE(direct_writer.Write(nullptr, 0));
+  EXPECT_TRUE(direct_writer.End());
+}
+
+TEST_F(ExtentWriterTest, OverflowExtentTest) {
+  WriteAlignedExtents(kBlockSize * 3, kBlockSize * 3);
+}
+
+TEST_F(ExtentWriterTest, UnalignedWriteTest) {
+  WriteAlignedExtents(7, 7);
+}
+
+TEST_F(ExtentWriterTest, LargeUnalignedWriteTest) {
+  WriteAlignedExtents(kBlockSize * 2, kBlockSize / 2);
+}
+
+void ExtentWriterTest::WriteAlignedExtents(size_t chunk_size,
+                                           size_t first_chunk_size) {
+  vector<Extent> extents;
+  Extent extent;
+  extent.set_start_block(1);
+  extent.set_num_blocks(1);
+  extents.push_back(extent);
+  extent.set_start_block(0);
+  extent.set_num_blocks(1);
+  extents.push_back(extent);
+  extent.set_start_block(2);
+  extent.set_num_blocks(1);
+  extents.push_back(extent);
+
+  brillo::Blob data(kBlockSize * 3);
+  test_utils::FillWithData(&data);
+
+  DirectExtentWriter direct_writer;
+  EXPECT_TRUE(direct_writer.Init(fd_, extents, kBlockSize));
+
+  size_t bytes_written = 0;
+  while (bytes_written < data.size()) {
+    size_t bytes_to_write = min(data.size() - bytes_written, chunk_size);
+    if (bytes_written == 0) {
+      bytes_to_write = min(data.size() - bytes_written, first_chunk_size);
+    }
+    EXPECT_TRUE(direct_writer.Write(&data[bytes_written], bytes_to_write));
+    bytes_written += bytes_to_write;
+  }
+  EXPECT_TRUE(direct_writer.End());
+
+  EXPECT_EQ(data.size(), utils::FileSize(path_));
+
+  brillo::Blob result_file;
+  EXPECT_TRUE(utils::ReadFile(path_, &result_file));
+
+  brillo::Blob expected_file;
+  expected_file.insert(expected_file.end(),
+                       data.begin() + kBlockSize,
+                       data.begin() + kBlockSize * 2);
+  expected_file.insert(expected_file.end(),
+                       data.begin(), data.begin() + kBlockSize);
+  expected_file.insert(expected_file.end(),
+                       data.begin() + kBlockSize * 2, data.end());
+  ExpectVectorsEq(expected_file, result_file);
+}
+
+TEST_F(ExtentWriterTest, ZeroPadNullTest) {
+  TestZeroPad(true);
+}
+
+TEST_F(ExtentWriterTest, ZeroPadFillTest) {
+  TestZeroPad(false);
+}
+
+void ExtentWriterTest::TestZeroPad(bool aligned_size) {
+  vector<Extent> extents;
+  Extent extent;
+  extent.set_start_block(1);
+  extent.set_num_blocks(1);
+  extents.push_back(extent);
+  extent.set_start_block(0);
+  extent.set_num_blocks(1);
+  extents.push_back(extent);
+
+  brillo::Blob data(kBlockSize * 2);
+  test_utils::FillWithData(&data);
+
+  ZeroPadExtentWriter zero_pad_writer(
+      brillo::make_unique_ptr(new DirectExtentWriter()));
+
+  EXPECT_TRUE(zero_pad_writer.Init(fd_, extents, kBlockSize));
+  size_t bytes_to_write = data.size();
+  const size_t missing_bytes = (aligned_size ? 0 : 9);
+  bytes_to_write -= missing_bytes;
+  fd_->Seek(kBlockSize - missing_bytes, SEEK_SET);
+  EXPECT_EQ(3, fd_->Write("xxx", 3));
+  ASSERT_TRUE(zero_pad_writer.Write(data.data(), bytes_to_write));
+  EXPECT_TRUE(zero_pad_writer.End());
+
+  EXPECT_EQ(data.size(), utils::FileSize(path_));
+
+  brillo::Blob result_file;
+  EXPECT_TRUE(utils::ReadFile(path_, &result_file));
+
+  brillo::Blob expected_file;
+  expected_file.insert(expected_file.end(),
+                       data.begin() + kBlockSize,
+                       data.begin() + kBlockSize * 2);
+  expected_file.insert(expected_file.end(),
+                       data.begin(), data.begin() + kBlockSize);
+  if (missing_bytes) {
+    memset(&expected_file[kBlockSize - missing_bytes], 0, missing_bytes);
+  }
+
+  ExpectVectorsEq(expected_file, result_file);
+}
+
+TEST_F(ExtentWriterTest, SparseFileTest) {
+  vector<Extent> extents;
+  Extent extent;
+  extent.set_start_block(1);
+  extent.set_num_blocks(1);
+  extents.push_back(extent);
+  extent.set_start_block(kSparseHole);
+  extent.set_num_blocks(2);
+  extents.push_back(extent);
+  extent.set_start_block(0);
+  extent.set_num_blocks(1);
+  extents.push_back(extent);
+  const int block_count = 4;
+  const int on_disk_count = 2;
+
+  brillo::Blob data(17);
+  test_utils::FillWithData(&data);
+
+  DirectExtentWriter direct_writer;
+  EXPECT_TRUE(direct_writer.Init(fd_, extents, kBlockSize));
+
+  size_t bytes_written = 0;
+  while (bytes_written < (block_count * kBlockSize)) {
+    size_t bytes_to_write = min(block_count * kBlockSize - bytes_written,
+                                data.size());
+    EXPECT_TRUE(direct_writer.Write(data.data(), bytes_to_write));
+    bytes_written += bytes_to_write;
+  }
+  EXPECT_TRUE(direct_writer.End());
+
+  // check file size, then data inside
+  ASSERT_EQ(2 * kBlockSize, utils::FileSize(path_));
+
+  brillo::Blob resultant_data;
+  EXPECT_TRUE(utils::ReadFile(path_, &resultant_data));
+
+  // Create expected data
+  brillo::Blob expected_data(on_disk_count * kBlockSize);
+  brillo::Blob big(block_count * kBlockSize);
+  for (brillo::Blob::size_type i = 0; i < big.size(); i++) {
+    big[i] = data[i % data.size()];
+  }
+  memcpy(&expected_data[kBlockSize], &big[0], kBlockSize);
+  memcpy(&expected_data[0], &big[3 * kBlockSize], kBlockSize);
+  ExpectVectorsEq(expected_data, resultant_data);
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/fake_extent_writer.h b/payload_consumer/fake_extent_writer.h
new file mode 100644
index 0000000..762c6d5
--- /dev/null
+++ b/payload_consumer/fake_extent_writer.h
@@ -0,0 +1,71 @@
+//
+// Copyright (C) 2015 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.
+//
+
+#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_FAKE_EXTENT_WRITER_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_FAKE_EXTENT_WRITER_H_
+
+#include <memory>
+#include <vector>
+
+#include <brillo/secure_blob.h>
+
+#include "update_engine/payload_consumer/extent_writer.h"
+
+namespace chromeos_update_engine {
+
+// FakeExtentWriter is a concrete ExtentWriter subclass that keeps track of all
+// the written data, useful for testing.
+class FakeExtentWriter : public ExtentWriter {
+ public:
+  FakeExtentWriter() = default;
+  ~FakeExtentWriter() override = default;
+
+  // ExtentWriter overrides.
+  bool Init(FileDescriptorPtr /* fd */,
+            const std::vector<Extent>& /* extents */,
+            uint32_t /* block_size */) override {
+    init_called_ = true;
+    return true;
+  };
+  bool Write(const void* bytes, size_t count) override {
+    if (!init_called_ || end_called_)
+      return false;
+    written_data_.insert(written_data_.end(),
+                         reinterpret_cast<const uint8_t*>(bytes),
+                         reinterpret_cast<const uint8_t*>(bytes) + count);
+    return true;
+  }
+  bool EndImpl() override {
+    end_called_ = true;
+    return true;
+  }
+
+  // Fake methods.
+  bool InitCalled() { return init_called_; }
+  bool EndCalled() { return end_called_; }
+  brillo::Blob WrittenData() { return written_data_; }
+
+ private:
+  bool init_called_{false};
+  bool end_called_{false};
+  brillo::Blob written_data_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeExtentWriter);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_FAKE_EXTENT_WRITER_H_
diff --git a/payload_consumer/file_descriptor.cc b/payload_consumer/file_descriptor.cc
new file mode 100644
index 0000000..f26be28
--- /dev/null
+++ b/payload_consumer/file_descriptor.cc
@@ -0,0 +1,116 @@
+//
+// Copyright (C) 2012 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 "update_engine/payload_consumer/file_descriptor.h"
+
+#include <fcntl.h>
+#include <linux/fs.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <base/posix/eintr_wrapper.h>
+
+namespace chromeos_update_engine {
+
+bool EintrSafeFileDescriptor::Open(const char* path, int flags, mode_t mode) {
+  CHECK_EQ(fd_, -1);
+  return ((fd_ = HANDLE_EINTR(open(path, flags, mode))) >= 0);
+}
+
+bool EintrSafeFileDescriptor::Open(const char* path, int flags) {
+  CHECK_EQ(fd_, -1);
+  return ((fd_ = HANDLE_EINTR(open(path, flags))) >= 0);
+}
+
+ssize_t EintrSafeFileDescriptor::Read(void* buf, size_t count) {
+  CHECK_GE(fd_, 0);
+  return HANDLE_EINTR(read(fd_, buf, count));
+}
+
+ssize_t EintrSafeFileDescriptor::Write(const void* buf, size_t count) {
+  CHECK_GE(fd_, 0);
+
+  // Attempt repeated writes, as long as some progress is being made.
+  char* char_buf = const_cast<char*>(reinterpret_cast<const char*>(buf));
+  ssize_t written = 0;
+  while (count > 0) {
+    ssize_t ret = HANDLE_EINTR(write(fd_, char_buf, count));
+
+    // Fail on either an error or no progress.
+    if (ret <= 0)
+      return (written ? written : ret);
+    written += ret;
+    count -= ret;
+    char_buf += ret;
+  }
+  return written;
+}
+
+off64_t EintrSafeFileDescriptor::Seek(off64_t offset, int whence) {
+  CHECK_GE(fd_, 0);
+  return lseek64(fd_, offset, whence);
+}
+
+bool EintrSafeFileDescriptor::BlkIoctl(int request,
+                                       uint64_t start,
+                                       uint64_t length,
+                                       int* result) {
+  DCHECK(request == BLKDISCARD || request == BLKZEROOUT ||
+         request == BLKSECDISCARD);
+  // On some devices, the BLKDISCARD will actually read back as zeros, instead
+  // of "undefined" data. The BLKDISCARDZEROES ioctl tells whether that's the
+  // case, so we issue a BLKDISCARD in those cases to speed up the writes.
+  unsigned int arg;
+  if (request == BLKZEROOUT && ioctl(fd_, BLKDISCARDZEROES, &arg) == 0 && arg)
+    request = BLKDISCARD;
+
+  // Ensure the |fd_| is in O_DIRECT mode during this operation, so the write
+  // cache for this region is invalidated. This is required since otherwise
+  // reading back this region could consume stale data from the cache.
+  int flags = fcntl(fd_, F_GETFL, 0);
+  if (flags == -1) {
+    PLOG(WARNING) << "Couldn't get flags on fd " << fd_;
+    return false;
+  }
+  if ((flags & O_DIRECT) == 0 && fcntl(fd_, F_SETFL, flags | O_DIRECT) == -1) {
+    PLOG(WARNING) << "Couldn't set O_DIRECT on fd " << fd_;
+    return false;
+  }
+
+  uint64_t range[2] = {start, length};
+  *result = ioctl(fd_, request, range);
+
+  if ((flags & O_DIRECT) == 0 && fcntl(fd_, F_SETFL, flags) == -1) {
+    PLOG(WARNING) << "Couldn't remove O_DIRECT on fd " << fd_;
+    return false;
+  }
+  return true;
+}
+
+bool EintrSafeFileDescriptor::Close() {
+  CHECK_GE(fd_, 0);
+  if (IGNORE_EINTR(close(fd_)))
+    return false;
+  Reset();
+  return true;
+}
+
+void EintrSafeFileDescriptor::Reset() {
+  fd_ = -1;
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/file_descriptor.h b/payload_consumer/file_descriptor.h
new file mode 100644
index 0000000..3c15415
--- /dev/null
+++ b/payload_consumer/file_descriptor.h
@@ -0,0 +1,141 @@
+//
+// Copyright (C) 2012 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.
+//
+
+#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_FILE_DESCRIPTOR_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_FILE_DESCRIPTOR_H_
+
+#include <errno.h>
+#include <memory>
+#include <sys/types.h>
+
+#include <base/logging.h>
+
+// Abstraction for managing opening, reading, writing and closing of file
+// descriptors. This includes an abstract class and one standard implementation
+// based on POSIX system calls.
+//
+// TODO(garnold) this class is modeled after (and augments the functionality of)
+// the FileWriter class; ultimately, the latter should be replaced by the former
+// throughout the codebase.  A few deviations from the original FileWriter:
+//
+// * Providing two flavors of Open()
+//
+// * A FileDescriptor is reusable and can be used to read/write multiple files
+//   as long as open/close preconditions are respected.
+//
+// * Write() returns the number of bytes written: this appears to be more useful
+//   for clients, who may wish to retry or otherwise do something useful with
+//   the remaining data that was not written.
+//
+// * Provides a Reset() method, which will force to abandon a currently open
+//   file descriptor and allow opening another file, without necessarily
+//   properly closing the old one. This may be useful in cases where a "closer"
+//   class does not care whether Close() was successful, but may need to reuse
+//   the same file descriptor again.
+
+namespace chromeos_update_engine {
+
+class FileDescriptor;
+using FileDescriptorPtr = std::shared_ptr<FileDescriptor>;
+
+// An abstract class defining the file descriptor API.
+class FileDescriptor {
+ public:
+  FileDescriptor() {}
+  virtual ~FileDescriptor() {}
+
+  // Opens a file descriptor. The descriptor must be in the closed state prior
+  // to this call. Returns true on success, false otherwise. Specific
+  // implementations may set errno accordingly.
+  virtual bool Open(const char* path, int flags, mode_t mode) = 0;
+  virtual bool Open(const char* path, int flags) = 0;
+
+  // Reads from a file descriptor up to a given count. The descriptor must be
+  // open prior to this call. Returns the number of bytes read, or -1 on error.
+  // Specific implementations may set errno accordingly.
+  virtual ssize_t Read(void* buf, size_t count) = 0;
+
+  // Writes to a file descriptor. The descriptor must be open prior to this
+  // call. Returns the number of bytes written, or -1 if an error occurred and
+  // no bytes were written. Specific implementations may set errno accordingly.
+  virtual ssize_t Write(const void* buf, size_t count) = 0;
+
+  // Seeks to an offset. Returns the resulting offset location as measured in
+  // bytes from the beginning. On error, return -1. Specific implementations
+  // may set errno accordingly.
+  virtual off64_t Seek(off64_t offset, int whence) = 0;
+
+  // Runs a ioctl() on the file descriptor if supported. Returns whether
+  // the operation is supported. The |request| can be one of BLKDISCARD,
+  // BLKZEROOUT and BLKSECDISCARD to discard, write zeros or securely discard
+  // the blocks. These ioctls accept a range of bytes (|start| and |length|)
+  // over which they perform the operation. The return value from the ioctl is
+  // stored in |result|.
+  virtual bool BlkIoctl(int request,
+                        uint64_t start,
+                        uint64_t length,
+                        int* result) = 0;
+
+  // Closes a file descriptor. The descriptor must be open prior to this call.
+  // Returns true on success, false otherwise. Specific implementations may set
+  // errno accordingly.
+  virtual bool Close() = 0;
+
+  // Resets the file descriptor, abandoning a currently open file and returning
+  // the descriptor to the closed state.
+  virtual void Reset() = 0;
+
+  // Indicates whether or not an implementation sets meaningful errno.
+  virtual bool IsSettingErrno() = 0;
+
+  // Indicates whether the descriptor is currently open.
+  virtual bool IsOpen() = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FileDescriptor);
+};
+
+// A simple EINTR-immune wrapper implementation around standard system calls.
+class EintrSafeFileDescriptor : public FileDescriptor {
+ public:
+  EintrSafeFileDescriptor() : fd_(-1) {}
+
+  // Interface methods.
+  bool Open(const char* path, int flags, mode_t mode) override;
+  bool Open(const char* path, int flags) override;
+  ssize_t Read(void* buf, size_t count) override;
+  ssize_t Write(const void* buf, size_t count) override;
+  off64_t Seek(off64_t offset, int whence) override;
+  bool BlkIoctl(int request,
+                uint64_t start,
+                uint64_t length,
+                int* result) override;
+  bool Close() override;
+  void Reset() override;
+  bool IsSettingErrno() override {
+    return true;
+  }
+  bool IsOpen() override {
+    return (fd_ >= 0);
+  }
+
+ protected:
+  int fd_;
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_FILE_DESCRIPTOR_H_
diff --git a/payload_consumer/file_writer.cc b/payload_consumer/file_writer.cc
new file mode 100644
index 0000000..d280ddb
--- /dev/null
+++ b/payload_consumer/file_writer.cc
@@ -0,0 +1,60 @@
+//
+// Copyright (C) 2009 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 "update_engine/payload_consumer/file_writer.h"
+
+#include <errno.h>
+
+namespace chromeos_update_engine {
+
+int DirectFileWriter::Open(const char* path, int flags, mode_t mode) {
+  CHECK_EQ(fd_, -1);
+  fd_ = open(path, flags, mode);
+  if (fd_ < 0)
+    return -errno;
+  return 0;
+}
+
+bool DirectFileWriter::Write(const void* bytes, size_t count) {
+  CHECK_GE(fd_, 0);
+  const char* char_bytes = reinterpret_cast<const char*>(bytes);
+
+  size_t bytes_written = 0;
+  while (bytes_written < count) {
+    ssize_t rc = write(fd_, char_bytes + bytes_written,
+                       count - bytes_written);
+    if (rc < 0)
+      return false;
+    bytes_written += rc;
+  }
+  CHECK_EQ(bytes_written, count);
+  return bytes_written == count;
+}
+
+int DirectFileWriter::Close() {
+  CHECK_GE(fd_, 0);
+  int rc = close(fd_);
+
+  // This can be any negative number that's not -1. This way, this FileWriter
+  // won't be used again for another file.
+  fd_ = -2;
+
+  if (rc < 0)
+    return -errno;
+  return rc;
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/file_writer.h b/payload_consumer/file_writer.h
new file mode 100644
index 0000000..96ebde6
--- /dev/null
+++ b/payload_consumer/file_writer.h
@@ -0,0 +1,103 @@
+//
+// Copyright (C) 2009 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.
+//
+
+#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_FILE_WRITER_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_FILE_WRITER_H_
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <base/logging.h>
+
+#include "update_engine/common/error_code.h"
+#include "update_engine/common/utils.h"
+
+// FileWriter is a class that is used to (synchronously, for now) write to
+// a file. This file is a thin wrapper around open/write/close system calls,
+// but provides and interface that can be customized by subclasses that wish
+// to filter the data.
+
+namespace chromeos_update_engine {
+
+class FileWriter {
+ public:
+  FileWriter() {}
+  virtual ~FileWriter() {}
+
+  // Wrapper around write. Returns true if all requested bytes
+  // were written, or false on any error, regardless of progress.
+  virtual bool Write(const void* bytes, size_t count) = 0;
+
+  // Same as the Write method above but returns a detailed |error| code
+  // in addition if the returned value is false. By default this method
+  // returns kActionExitDownloadWriteError as the error code, but subclasses
+  // can override if they wish to return more specific error codes.
+  virtual bool Write(const void* bytes,
+                     size_t count,
+                     ErrorCode* error) {
+     *error = ErrorCode::kDownloadWriteError;
+     return Write(bytes, count);
+  }
+
+  // Wrapper around close. Returns 0 on success or -errno on error.
+  virtual int Close() = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FileWriter);
+};
+
+// Direct file writer is probably the simplest FileWriter implementation.
+// It calls the system calls directly.
+
+class DirectFileWriter : public FileWriter {
+ public:
+  DirectFileWriter() = default;
+
+  // FileWriter overrides.
+  bool Write(const void* bytes, size_t count) override;
+  int Close() override;
+
+  // Wrapper around open. Returns 0 on success or -errno on error.
+  int Open(const char* path, int flags, mode_t mode);
+
+  int fd() const { return fd_; }
+
+ private:
+  int fd_{-1};
+
+  DISALLOW_COPY_AND_ASSIGN(DirectFileWriter);
+};
+
+class ScopedFileWriterCloser {
+ public:
+  explicit ScopedFileWriterCloser(FileWriter* writer) : writer_(writer) {}
+  ~ScopedFileWriterCloser() {
+    int err = writer_->Close();
+    if (err)
+      LOG(ERROR) << "FileWriter::Close failed: "
+                 << utils::ErrnoNumberAsString(-err);
+  }
+ private:
+  FileWriter* writer_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedFileWriterCloser);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_FILE_WRITER_H_
diff --git a/payload_consumer/file_writer_unittest.cc b/payload_consumer/file_writer_unittest.cc
new file mode 100644
index 0000000..debb4c3
--- /dev/null
+++ b/payload_consumer/file_writer_unittest.cc
@@ -0,0 +1,79 @@
+//
+// Copyright (C) 2009 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 "update_engine/payload_consumer/file_writer.h"
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+#include <brillo/secure_blob.h>
+#include <gtest/gtest.h>
+
+#include "update_engine/common/test_utils.h"
+#include "update_engine/common/utils.h"
+
+using std::string;
+using std::vector;
+
+namespace chromeos_update_engine {
+
+class FileWriterTest : public ::testing::Test { };
+
+TEST(FileWriterTest, SimpleTest) {
+  // Create a uniquely named file for testing.
+  string path;
+  ASSERT_TRUE(utils::MakeTempFile("FileWriterTest-XXXXXX", &path, nullptr));
+  ScopedPathUnlinker path_unlinker(path);
+
+  DirectFileWriter file_writer;
+  EXPECT_EQ(0, file_writer.Open(path.c_str(),
+                                O_CREAT | O_LARGEFILE | O_TRUNC | O_WRONLY,
+                                0644));
+  EXPECT_TRUE(file_writer.Write("test", 4));
+  brillo::Blob actual_data;
+  EXPECT_TRUE(utils::ReadFile(path, &actual_data));
+
+  EXPECT_FALSE(memcmp("test", actual_data.data(), actual_data.size()));
+  EXPECT_EQ(0, file_writer.Close());
+}
+
+TEST(FileWriterTest, ErrorTest) {
+  DirectFileWriter file_writer;
+  const string path("/tmp/ENOENT/FileWriterTest");
+  EXPECT_EQ(-ENOENT, file_writer.Open(path.c_str(),
+                                      O_CREAT | O_LARGEFILE | O_TRUNC, 0644));
+}
+
+TEST(FileWriterTest, WriteErrorTest) {
+  // Create a uniquely named file for testing.
+  string path;
+  ASSERT_TRUE(utils::MakeTempFile("FileWriterTest-XXXXXX", &path, nullptr));
+  ScopedPathUnlinker path_unlinker(path);
+
+  DirectFileWriter file_writer;
+  EXPECT_EQ(0, file_writer.Open(path.c_str(),
+                                O_CREAT | O_LARGEFILE | O_TRUNC | O_RDONLY,
+                                0644));
+  EXPECT_FALSE(file_writer.Write("x", 1));
+  EXPECT_EQ(0, file_writer.Close());
+}
+
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/filesystem_verifier_action.cc b/payload_consumer/filesystem_verifier_action.cc
new file mode 100644
index 0000000..6768407
--- /dev/null
+++ b/payload_consumer/filesystem_verifier_action.cc
@@ -0,0 +1,259 @@
+//
+// Copyright (C) 2012 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 "update_engine/payload_consumer/filesystem_verifier_action.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <algorithm>
+#include <cstdlib>
+#include <string>
+
+#include <base/bind.h>
+#include <brillo/streams/file_stream.h>
+
+#include "update_engine/common/boot_control_interface.h"
+#include "update_engine/common/utils.h"
+#include "update_engine/payload_consumer/payload_constants.h"
+
+using std::string;
+
+namespace chromeos_update_engine {
+
+namespace {
+const off_t kReadFileBufferSize = 128 * 1024;
+}  // namespace
+
+FilesystemVerifierAction::FilesystemVerifierAction(
+    const BootControlInterface* boot_control,
+    VerifierMode verifier_mode)
+    : verifier_mode_(verifier_mode),
+      boot_control_(boot_control) {}
+
+void FilesystemVerifierAction::PerformAction() {
+  // Will tell the ActionProcessor we've failed if we return.
+  ScopedActionCompleter abort_action_completer(processor_, this);
+
+  if (!HasInputObject()) {
+    LOG(ERROR) << "FilesystemVerifierAction missing input object.";
+    return;
+  }
+  install_plan_ = GetInputObject();
+
+  // For delta updates (major version 1) we need to populate the source
+  // partition hash if not pre-populated.
+  if (!install_plan_.is_full_update && install_plan_.partitions.empty() &&
+      verifier_mode_ == VerifierMode::kComputeSourceHash) {
+    LOG(INFO) << "Using legacy partition names.";
+    InstallPlan::Partition part;
+    string part_path;
+
+    part.name = kLegacyPartitionNameRoot;
+    if (!boot_control_->GetPartitionDevice(
+        part.name, install_plan_.source_slot, &part_path))
+      return;
+    int block_count = 0, block_size = 0;
+    if (utils::GetFilesystemSize(part_path, &block_count, &block_size)) {
+      part.source_size = static_cast<int64_t>(block_count) * block_size;
+      LOG(INFO) << "Partition " << part.name << " size: " << part.source_size
+                << " bytes (" << block_count << "x" << block_size << ").";
+    }
+    install_plan_.partitions.push_back(part);
+
+    part.name = kLegacyPartitionNameKernel;
+    if (!boot_control_->GetPartitionDevice(
+        part.name, install_plan_.source_slot, &part_path))
+      return;
+    off_t kernel_part_size = utils::FileSize(part_path);
+    if (kernel_part_size < 0)
+      return;
+    LOG(INFO) << "Partition " << part.name << " size: " << kernel_part_size
+              << " bytes.";
+    part.source_size = kernel_part_size;
+    install_plan_.partitions.push_back(part);
+  }
+
+  if (install_plan_.partitions.empty()) {
+    LOG(INFO) << "No partitions to verify.";
+    if (HasOutputPipe())
+      SetOutputObject(install_plan_);
+    abort_action_completer.set_code(ErrorCode::kSuccess);
+    return;
+  }
+
+  StartPartitionHashing();
+  abort_action_completer.set_should_complete(false);
+}
+
+void FilesystemVerifierAction::TerminateProcessing() {
+  cancelled_ = true;
+  Cleanup(ErrorCode::kSuccess);  // error code is ignored if canceled_ is true.
+}
+
+bool FilesystemVerifierAction::IsCleanupPending() const {
+  return src_stream_ != nullptr;
+}
+
+void FilesystemVerifierAction::Cleanup(ErrorCode code) {
+  src_stream_.reset();
+  // This memory is not used anymore.
+  buffer_.clear();
+
+  if (cancelled_)
+    return;
+  if (code == ErrorCode::kSuccess && HasOutputPipe())
+    SetOutputObject(install_plan_);
+  processor_->ActionComplete(this, code);
+}
+
+void FilesystemVerifierAction::StartPartitionHashing() {
+  if (partition_index_ == install_plan_.partitions.size()) {
+    Cleanup(ErrorCode::kSuccess);
+    return;
+  }
+  InstallPlan::Partition& partition =
+      install_plan_.partitions[partition_index_];
+
+  string part_path;
+  switch (verifier_mode_) {
+    case VerifierMode::kComputeSourceHash:
+      boot_control_->GetPartitionDevice(
+          partition.name, install_plan_.source_slot, &part_path);
+      remaining_size_ = partition.source_size;
+      break;
+    case VerifierMode::kVerifyTargetHash:
+      boot_control_->GetPartitionDevice(
+          partition.name, install_plan_.target_slot, &part_path);
+      remaining_size_ = partition.target_size;
+      break;
+  }
+  LOG(INFO) << "Hashing partition " << partition_index_ << " ("
+            << partition.name << ") on device " << part_path;
+  if (part_path.empty())
+    return Cleanup(ErrorCode::kFilesystemVerifierError);
+
+  brillo::ErrorPtr error;
+  src_stream_ = brillo::FileStream::Open(
+      base::FilePath(part_path),
+      brillo::Stream::AccessMode::READ,
+      brillo::FileStream::Disposition::OPEN_EXISTING,
+      &error);
+
+  if (!src_stream_) {
+    LOG(ERROR) << "Unable to open " << part_path << " for reading";
+    return Cleanup(ErrorCode::kFilesystemVerifierError);
+  }
+
+  buffer_.resize(kReadFileBufferSize);
+  read_done_ = false;
+  hasher_.reset(new HashCalculator());
+
+  // Start the first read.
+  ScheduleRead();
+}
+
+void FilesystemVerifierAction::ScheduleRead() {
+  size_t bytes_to_read = std::min(static_cast<int64_t>(buffer_.size()),
+                                  remaining_size_);
+  if (!bytes_to_read) {
+    OnReadDoneCallback(0);
+    return;
+  }
+
+  bool read_async_ok = src_stream_->ReadAsync(
+    buffer_.data(),
+    bytes_to_read,
+    base::Bind(&FilesystemVerifierAction::OnReadDoneCallback,
+               base::Unretained(this)),
+    base::Bind(&FilesystemVerifierAction::OnReadErrorCallback,
+               base::Unretained(this)),
+    nullptr);
+
+  if (!read_async_ok) {
+    LOG(ERROR) << "Unable to schedule an asynchronous read from the stream.";
+    Cleanup(ErrorCode::kError);
+  }
+}
+
+void FilesystemVerifierAction::OnReadDoneCallback(size_t bytes_read) {
+  if (bytes_read == 0) {
+    read_done_ = true;
+  } else {
+    remaining_size_ -= bytes_read;
+    CHECK(!read_done_);
+    if (!hasher_->Update(buffer_.data(), bytes_read)) {
+      LOG(ERROR) << "Unable to update the hash.";
+      Cleanup(ErrorCode::kError);
+      return;
+    }
+  }
+
+  // We either terminate the current partition or have more data to read.
+  if (cancelled_)
+    return Cleanup(ErrorCode::kError);
+
+  if (read_done_ || remaining_size_ == 0) {
+    if (remaining_size_ != 0) {
+      LOG(ERROR) << "Failed to read the remaining " << remaining_size_
+                 << " bytes from partition "
+                 << install_plan_.partitions[partition_index_].name;
+      return Cleanup(ErrorCode::kFilesystemVerifierError);
+    }
+    return FinishPartitionHashing();
+  }
+  ScheduleRead();
+}
+
+void FilesystemVerifierAction::OnReadErrorCallback(
+      const brillo::Error* error) {
+  // TODO(deymo): Transform the read-error into an specific ErrorCode.
+  LOG(ERROR) << "Asynchronous read failed.";
+  Cleanup(ErrorCode::kError);
+}
+
+void FilesystemVerifierAction::FinishPartitionHashing() {
+  if (!hasher_->Finalize()) {
+    LOG(ERROR) << "Unable to finalize the hash.";
+    return Cleanup(ErrorCode::kError);
+  }
+  InstallPlan::Partition& partition =
+      install_plan_.partitions[partition_index_];
+  LOG(INFO) << "Hash of " << partition.name << ": " << hasher_->hash();
+
+  switch (verifier_mode_) {
+    case VerifierMode::kComputeSourceHash:
+      partition.source_hash = hasher_->raw_hash();
+      break;
+    case VerifierMode::kVerifyTargetHash:
+      if (partition.target_hash != hasher_->raw_hash()) {
+        LOG(ERROR) << "New '" << partition.name
+                   << "' partition verification failed.";
+        return Cleanup(ErrorCode::kNewRootfsVerificationError);
+      }
+      break;
+  }
+  // Start hashing the next partition, if any.
+  partition_index_++;
+  hasher_.reset();
+  buffer_.clear();
+  src_stream_->CloseBlocking(nullptr);
+  StartPartitionHashing();
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/filesystem_verifier_action.h b/payload_consumer/filesystem_verifier_action.h
new file mode 100644
index 0000000..0a66b01
--- /dev/null
+++ b/payload_consumer/filesystem_verifier_action.h
@@ -0,0 +1,129 @@
+//
+// Copyright (C) 2012 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.
+//
+
+#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_FILESYSTEM_VERIFIER_ACTION_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_FILESYSTEM_VERIFIER_ACTION_H_
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <string>
+#include <vector>
+
+#include <brillo/streams/stream.h>
+#include <gtest/gtest_prod.h>  // for FRIEND_TEST
+
+#include "update_engine/common/action.h"
+#include "update_engine/common/hash_calculator.h"
+#include "update_engine/payload_consumer/install_plan.h"
+
+// This action will hash all the partitions of a single slot involved in the
+// update (either source or target slot). The hashes are then either stored in
+// the InstallPlan (for source partitions) or verified against it (for target
+// partitions).
+
+namespace chromeos_update_engine {
+
+// The mode we are running the FilesystemVerifier on. On kComputeSourceHash mode
+// it computes the source_hash of all the partitions in the InstallPlan, based
+// on the already populated source_size values. On kVerifyTargetHash it computes
+// the hash on the target partitions based on the already populated size and
+// verifies it matches the one in the target_hash in the InstallPlan.
+enum class VerifierMode {
+  kComputeSourceHash,
+  kVerifyTargetHash,
+};
+
+class FilesystemVerifierAction : public InstallPlanAction {
+ public:
+  FilesystemVerifierAction(const BootControlInterface* boot_control,
+                           VerifierMode verifier_mode);
+
+  void PerformAction() override;
+  void TerminateProcessing() override;
+
+  // Used for testing. Return true if Cleanup() has not yet been called due
+  // to a callback upon the completion or cancellation of the verifier action.
+  // A test should wait until IsCleanupPending() returns false before
+  // terminating the main loop.
+  bool IsCleanupPending() const;
+
+  // Debugging/logging
+  static std::string StaticType() { return "FilesystemVerifierAction"; }
+  std::string Type() const override { return StaticType(); }
+
+ private:
+  friend class FilesystemVerifierActionTest;
+  FRIEND_TEST(FilesystemVerifierActionTest,
+              RunAsRootDetermineFilesystemSizeTest);
+
+  // Starts the hashing of the current partition. If there aren't any partitions
+  // remaining to be hashed, if finishes the action.
+  void StartPartitionHashing();
+
+  // Schedules the asynchronous read of the filesystem.
+  void ScheduleRead();
+
+  // Called from the main loop when a single read from |src_stream_| succeeds or
+  // fails, calling OnReadDoneCallback() and OnReadErrorCallback() respectively.
+  void OnReadDoneCallback(size_t bytes_read);
+  void OnReadErrorCallback(const brillo::Error* error);
+
+  // When the read is done, finalize the hash checking of the current partition
+  // and continue checking the next one.
+  void FinishPartitionHashing();
+
+  // Cleans up all the variables we use for async operations and tells the
+  // ActionProcessor we're done w/ |code| as passed in. |cancelled_| should be
+  // true if TerminateProcessing() was called.
+  void Cleanup(ErrorCode code);
+
+  // The type of the partition that we are verifying.
+  const VerifierMode verifier_mode_;
+
+  // The BootControlInterface used to get the partitions based on the slots.
+  const BootControlInterface* const boot_control_;
+
+  // The index in the install_plan_.partitions vector of the partition currently
+  // being hashed.
+  size_t partition_index_{0};
+
+  // If not null, the FileStream used to read from the device.
+  brillo::StreamPtr src_stream_;
+
+  // Buffer for storing data we read.
+  brillo::Blob buffer_;
+
+  bool read_done_{false};  // true if reached EOF on the input stream.
+  bool cancelled_{false};  // true if the action has been cancelled.
+
+  // The install plan we're passed in via the input pipe.
+  InstallPlan install_plan_;
+
+  // Calculates the hash of the data.
+  std::unique_ptr<HashCalculator> hasher_;
+
+  // Reads and hashes this many bytes from the head of the input stream. This
+  // field is initialized from the corresponding InstallPlan::Partition size,
+  // when the partition starts to be hashed.
+  int64_t remaining_size_{0};
+
+  DISALLOW_COPY_AND_ASSIGN(FilesystemVerifierAction);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_FILESYSTEM_VERIFIER_ACTION_H_
diff --git a/payload_consumer/filesystem_verifier_action_unittest.cc b/payload_consumer/filesystem_verifier_action_unittest.cc
new file mode 100644
index 0000000..7b88aca
--- /dev/null
+++ b/payload_consumer/filesystem_verifier_action_unittest.cc
@@ -0,0 +1,387 @@
+//
+// Copyright (C) 2012 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 "update_engine/payload_consumer/filesystem_verifier_action.h"
+
+#include <fcntl.h>
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include <base/bind.h>
+#include <base/posix/eintr_wrapper.h>
+#include <base/strings/string_util.h>
+#include <base/strings/stringprintf.h>
+#include <brillo/bind_lambda.h>
+#include <brillo/message_loops/fake_message_loop.h>
+#include <brillo/message_loops/message_loop_utils.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "update_engine/common/fake_boot_control.h"
+#include "update_engine/common/hash_calculator.h"
+#include "update_engine/common/test_utils.h"
+#include "update_engine/common/utils.h"
+#include "update_engine/payload_consumer/payload_constants.h"
+
+using brillo::MessageLoop;
+using std::set;
+using std::string;
+using std::vector;
+
+namespace chromeos_update_engine {
+
+class FilesystemVerifierActionTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    loop_.SetAsCurrent();
+  }
+
+  void TearDown() override {
+    EXPECT_EQ(0, brillo::MessageLoopRunMaxIterations(&loop_, 1));
+  }
+
+  // Returns true iff test has completed successfully.
+  bool DoTest(bool terminate_early,
+              bool hash_fail,
+              VerifierMode verifier_mode);
+
+  brillo::FakeMessageLoop loop_{nullptr};
+  FakeBootControl fake_boot_control_;
+};
+
+class FilesystemVerifierActionTestDelegate : public ActionProcessorDelegate {
+ public:
+  explicit FilesystemVerifierActionTestDelegate(
+      FilesystemVerifierAction* action)
+      : action_(action), ran_(false), code_(ErrorCode::kError) {}
+  void ExitMainLoop() {
+    // We need to wait for the Action to call Cleanup.
+    if (action_->IsCleanupPending()) {
+      LOG(INFO) << "Waiting for Cleanup() to be called.";
+      MessageLoop::current()->PostDelayedTask(
+          FROM_HERE,
+          base::Bind(&FilesystemVerifierActionTestDelegate::ExitMainLoop,
+                     base::Unretained(this)),
+          base::TimeDelta::FromMilliseconds(100));
+    } else {
+      MessageLoop::current()->BreakLoop();
+    }
+  }
+  void ProcessingDone(const ActionProcessor* processor, ErrorCode code) {
+    ExitMainLoop();
+  }
+  void ProcessingStopped(const ActionProcessor* processor) {
+    ExitMainLoop();
+  }
+  void ActionCompleted(ActionProcessor* processor,
+                       AbstractAction* action,
+                       ErrorCode code) {
+    if (action->Type() == FilesystemVerifierAction::StaticType()) {
+      ran_ = true;
+      code_ = code;
+    }
+  }
+  bool ran() const { return ran_; }
+  ErrorCode code() const { return code_; }
+
+ private:
+  FilesystemVerifierAction* action_;
+  bool ran_;
+  ErrorCode code_;
+};
+
+void StartProcessorInRunLoop(ActionProcessor* processor,
+                             FilesystemVerifierAction* filesystem_copier_action,
+                             bool terminate_early) {
+  processor->StartProcessing();
+  if (terminate_early) {
+    EXPECT_NE(nullptr, filesystem_copier_action);
+    processor->StopProcessing();
+  }
+}
+
+// TODO(garnold) Temporarily disabling this test, see chromium-os:31082 for
+// details; still trying to track down the root cause for these rare write
+// failures and whether or not they are due to the test setup or an inherent
+// issue with the chroot environment, library versions we use, etc.
+TEST_F(FilesystemVerifierActionTest, DISABLED_RunAsRootSimpleTest) {
+  ASSERT_EQ(0, getuid());
+  bool test = DoTest(false, false, VerifierMode::kComputeSourceHash);
+  EXPECT_TRUE(test);
+  if (!test)
+    return;
+  test = DoTest(false, false, VerifierMode::kVerifyTargetHash);
+  EXPECT_TRUE(test);
+}
+
+bool FilesystemVerifierActionTest::DoTest(bool terminate_early,
+                                          bool hash_fail,
+                                          VerifierMode verifier_mode) {
+  string a_loop_file;
+
+  if (!(utils::MakeTempFile("a_loop_file.XXXXXX", &a_loop_file, nullptr))) {
+    ADD_FAILURE();
+    return false;
+  }
+  ScopedPathUnlinker a_loop_file_unlinker(a_loop_file);
+
+  // Make random data for a.
+  const size_t kLoopFileSize = 10 * 1024 * 1024 + 512;
+  brillo::Blob a_loop_data(kLoopFileSize);
+  test_utils::FillWithData(&a_loop_data);
+
+  // Write data to disk
+  if (!(test_utils::WriteFileVector(a_loop_file, a_loop_data))) {
+    ADD_FAILURE();
+    return false;
+  }
+
+  // Attach loop devices to the files
+  string a_dev;
+  test_utils::ScopedLoopbackDeviceBinder a_dev_releaser(a_loop_file, &a_dev);
+  if (!(a_dev_releaser.is_bound())) {
+    ADD_FAILURE();
+    return false;
+  }
+
+  LOG(INFO) << "verifying: "  << a_loop_file << " (" << a_dev << ")";
+
+  bool success = true;
+
+  // Set up the action objects
+  InstallPlan install_plan;
+  install_plan.source_slot = 0;
+  install_plan.target_slot = 1;
+  InstallPlan::Partition part;
+  part.name = "part";
+  switch (verifier_mode) {
+    case VerifierMode::kVerifyTargetHash:
+      part.target_size = kLoopFileSize - (hash_fail ? 1 : 0);
+      part.target_path = a_dev;
+      fake_boot_control_.SetPartitionDevice(
+          part.name, install_plan.target_slot, a_dev);
+      if (!HashCalculator::RawHashOfData(a_loop_data, &part.target_hash)) {
+        ADD_FAILURE();
+        success = false;
+      }
+      break;
+    case VerifierMode::kComputeSourceHash:
+      part.source_size = kLoopFileSize;
+      part.source_path = a_dev;
+      fake_boot_control_.SetPartitionDevice(
+          part.name, install_plan.source_slot, a_dev);
+      if (!HashCalculator::RawHashOfData(a_loop_data, &part.source_hash)) {
+        ADD_FAILURE();
+        success = false;
+      }
+      break;
+  }
+  install_plan.partitions = {part};
+
+  ActionProcessor processor;
+
+  ObjectFeederAction<InstallPlan> feeder_action;
+  FilesystemVerifierAction copier_action(&fake_boot_control_, verifier_mode);
+  ObjectCollectorAction<InstallPlan> collector_action;
+
+  BondActions(&feeder_action, &copier_action);
+  BondActions(&copier_action, &collector_action);
+
+  FilesystemVerifierActionTestDelegate delegate(&copier_action);
+  processor.set_delegate(&delegate);
+  processor.EnqueueAction(&feeder_action);
+  processor.EnqueueAction(&copier_action);
+  processor.EnqueueAction(&collector_action);
+
+  feeder_action.set_obj(install_plan);
+
+  loop_.PostTask(FROM_HERE, base::Bind(&StartProcessorInRunLoop,
+                                       &processor,
+                                       &copier_action,
+                                       terminate_early));
+  loop_.Run();
+
+  if (!terminate_early) {
+    bool is_delegate_ran = delegate.ran();
+    EXPECT_TRUE(is_delegate_ran);
+    success = success && is_delegate_ran;
+  } else {
+    EXPECT_EQ(ErrorCode::kError, delegate.code());
+    return (ErrorCode::kError == delegate.code());
+  }
+  if (hash_fail) {
+    ErrorCode expected_exit_code = ErrorCode::kNewRootfsVerificationError;
+    EXPECT_EQ(expected_exit_code, delegate.code());
+    return (expected_exit_code == delegate.code());
+  }
+  EXPECT_EQ(ErrorCode::kSuccess, delegate.code());
+
+  // Make sure everything in the out_image is there
+  brillo::Blob a_out;
+  if (!utils::ReadFile(a_dev, &a_out)) {
+    ADD_FAILURE();
+    return false;
+  }
+  const bool is_a_file_reading_eq =
+      test_utils::ExpectVectorsEq(a_loop_data, a_out);
+  EXPECT_TRUE(is_a_file_reading_eq);
+  success = success && is_a_file_reading_eq;
+
+  bool is_install_plan_eq = (collector_action.object() == install_plan);
+  EXPECT_TRUE(is_install_plan_eq);
+  success = success && is_install_plan_eq;
+  return success;
+}
+
+class FilesystemVerifierActionTest2Delegate : public ActionProcessorDelegate {
+ public:
+  void ActionCompleted(ActionProcessor* processor,
+                       AbstractAction* action,
+                       ErrorCode code) {
+    if (action->Type() == FilesystemVerifierAction::StaticType()) {
+      ran_ = true;
+      code_ = code;
+    }
+  }
+  bool ran_;
+  ErrorCode code_;
+};
+
+TEST_F(FilesystemVerifierActionTest, MissingInputObjectTest) {
+  ActionProcessor processor;
+  FilesystemVerifierActionTest2Delegate delegate;
+
+  processor.set_delegate(&delegate);
+
+  FilesystemVerifierAction copier_action(&fake_boot_control_,
+                                         VerifierMode::kVerifyTargetHash);
+  ObjectCollectorAction<InstallPlan> collector_action;
+
+  BondActions(&copier_action, &collector_action);
+
+  processor.EnqueueAction(&copier_action);
+  processor.EnqueueAction(&collector_action);
+  processor.StartProcessing();
+  EXPECT_FALSE(processor.IsRunning());
+  EXPECT_TRUE(delegate.ran_);
+  EXPECT_EQ(ErrorCode::kError, delegate.code_);
+}
+
+TEST_F(FilesystemVerifierActionTest, NonExistentDriveTest) {
+  ActionProcessor processor;
+  FilesystemVerifierActionTest2Delegate delegate;
+
+  processor.set_delegate(&delegate);
+
+  ObjectFeederAction<InstallPlan> feeder_action;
+  InstallPlan install_plan(false,
+                           false,
+                           "",
+                           0,
+                           "",
+                           0,
+                           "",
+                           "");
+  InstallPlan::Partition part;
+  part.name = "nope";
+  part.source_path = "/no/such/file";
+  part.target_path = "/no/such/file";
+  install_plan.partitions = {part};
+
+  feeder_action.set_obj(install_plan);
+  FilesystemVerifierAction verifier_action(&fake_boot_control_,
+                                           VerifierMode::kVerifyTargetHash);
+  ObjectCollectorAction<InstallPlan> collector_action;
+
+  BondActions(&verifier_action, &collector_action);
+
+  processor.EnqueueAction(&feeder_action);
+  processor.EnqueueAction(&verifier_action);
+  processor.EnqueueAction(&collector_action);
+  processor.StartProcessing();
+  EXPECT_FALSE(processor.IsRunning());
+  EXPECT_TRUE(delegate.ran_);
+  EXPECT_EQ(ErrorCode::kError, delegate.code_);
+}
+
+TEST_F(FilesystemVerifierActionTest, RunAsRootVerifyHashTest) {
+  ASSERT_EQ(0, getuid());
+  EXPECT_TRUE(DoTest(false, false, VerifierMode::kVerifyTargetHash));
+  EXPECT_TRUE(DoTest(false, false, VerifierMode::kComputeSourceHash));
+}
+
+TEST_F(FilesystemVerifierActionTest, RunAsRootVerifyHashFailTest) {
+  ASSERT_EQ(0, getuid());
+  EXPECT_TRUE(DoTest(false, true, VerifierMode::kVerifyTargetHash));
+}
+
+TEST_F(FilesystemVerifierActionTest, RunAsRootTerminateEarlyTest) {
+  ASSERT_EQ(0, getuid());
+  EXPECT_TRUE(DoTest(true, false, VerifierMode::kVerifyTargetHash));
+  // TerminateEarlyTest may leak some null callbacks from the Stream class.
+  while (loop_.RunOnce(false)) {}
+}
+
+// Test that the rootfs and kernel size used for hashing in delta payloads for
+// major version 1 is properly read.
+TEST_F(FilesystemVerifierActionTest, RunAsRootDetermineLegacySizeTest) {
+  string img;
+  EXPECT_TRUE(utils::MakeTempFile("img.XXXXXX", &img, nullptr));
+  ScopedPathUnlinker img_unlinker(img);
+  test_utils::CreateExtImageAtPath(img, nullptr);
+  // Extend the "partition" holding the file system from 10MiB to 20MiB.
+  EXPECT_EQ(0, truncate(img.c_str(), 20 * 1024 * 1024));
+
+  InstallPlan install_plan;
+  install_plan.source_slot = 1;
+
+  fake_boot_control_.SetPartitionDevice(
+      kLegacyPartitionNameRoot, install_plan.source_slot, img);
+  fake_boot_control_.SetPartitionDevice(
+      kLegacyPartitionNameKernel, install_plan.source_slot, img);
+  FilesystemVerifierAction action(&fake_boot_control_,
+                                  VerifierMode::kComputeSourceHash);
+
+  ObjectFeederAction<InstallPlan> feeder_action;
+  feeder_action.set_obj(install_plan);
+
+  ObjectCollectorAction<InstallPlan> collector_action;
+
+  BondActions(&feeder_action, &action);
+  BondActions(&action, &collector_action);
+  ActionProcessor processor;
+  processor.EnqueueAction(&feeder_action);
+  processor.EnqueueAction(&action);
+  processor.EnqueueAction(&collector_action);
+
+  loop_.PostTask(FROM_HERE,
+                 base::Bind([&processor]{ processor.StartProcessing(); }));
+  loop_.Run();
+  install_plan = collector_action.object();
+
+  ASSERT_EQ(2, install_plan.partitions.size());
+  // When computing the size of the rootfs on legacy delta updates we use the
+  // size of the filesystem, but when updating the kernel we use the whole
+  // partition.
+  EXPECT_EQ(10 * 1024 * 1024, install_plan.partitions[0].source_size);
+  EXPECT_EQ(kLegacyPartitionNameRoot, install_plan.partitions[0].name);
+  EXPECT_EQ(20 * 1024 * 1024, install_plan.partitions[1].source_size);
+  EXPECT_EQ(kLegacyPartitionNameKernel, install_plan.partitions[1].name);
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/install_plan.cc b/payload_consumer/install_plan.cc
new file mode 100644
index 0000000..f404c20
--- /dev/null
+++ b/payload_consumer/install_plan.cc
@@ -0,0 +1,124 @@
+//
+// Copyright (C) 2013 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 "update_engine/payload_consumer/install_plan.h"
+
+#include <base/format_macros.h>
+#include <base/logging.h>
+#include <base/strings/stringprintf.h>
+
+#include "update_engine/common/utils.h"
+#include "update_engine/payload_consumer/payload_constants.h"
+
+using std::string;
+
+namespace chromeos_update_engine {
+
+InstallPlan::InstallPlan(bool is_resume,
+                         bool is_full_update,
+                         const string& url,
+                         uint64_t payload_size,
+                         const string& payload_hash,
+                         uint64_t metadata_size,
+                         const string& metadata_signature,
+                         const string& public_key_rsa)
+    : is_resume(is_resume),
+      is_full_update(is_full_update),
+      download_url(url),
+      payload_size(payload_size),
+      payload_hash(payload_hash),
+      metadata_size(metadata_size),
+      metadata_signature(metadata_signature),
+      hash_checks_mandatory(false),
+      powerwash_required(false),
+      public_key_rsa(public_key_rsa) {}
+
+
+bool InstallPlan::operator==(const InstallPlan& that) const {
+  return ((is_resume == that.is_resume) &&
+          (is_full_update == that.is_full_update) &&
+          (download_url == that.download_url) &&
+          (payload_size == that.payload_size) &&
+          (payload_hash == that.payload_hash) &&
+          (metadata_size == that.metadata_size) &&
+          (metadata_signature == that.metadata_signature) &&
+          (source_slot == that.source_slot) &&
+          (target_slot == that.target_slot) &&
+          (partitions == that.partitions));
+}
+
+bool InstallPlan::operator!=(const InstallPlan& that) const {
+  return !((*this) == that);
+}
+
+void InstallPlan::Dump() const {
+  string partitions_str;
+  for (const auto& partition : partitions) {
+    partitions_str += base::StringPrintf(
+        ", part: %s (source_size: %" PRIu64 ", target_size %" PRIu64 ")",
+        partition.name.c_str(), partition.source_size, partition.target_size);
+  }
+
+  LOG(INFO) << "InstallPlan: "
+            << (is_resume ? "resume" : "new_update")
+            << ", payload type: " << (is_full_update ? "full" : "delta")
+            << ", source_slot: " << BootControlInterface::SlotName(source_slot)
+            << ", target_slot: " << BootControlInterface::SlotName(target_slot)
+            << ", url: " << download_url
+            << ", payload size: " << payload_size
+            << ", payload hash: " << payload_hash
+            << ", metadata size: " << metadata_size
+            << ", metadata signature: " << metadata_signature
+            << partitions_str
+            << ", hash_checks_mandatory: " << utils::ToString(
+                hash_checks_mandatory)
+            << ", powerwash_required: " << utils::ToString(
+                powerwash_required);
+}
+
+bool InstallPlan::LoadPartitionsFromSlots(SystemState* system_state) {
+  bool result = true;
+  for (Partition& partition : partitions) {
+    if (source_slot != BootControlInterface::kInvalidSlot) {
+      result = system_state->boot_control()->GetPartitionDevice(
+          partition.name, source_slot, &partition.source_path) && result;
+    } else {
+      partition.source_path.clear();
+    }
+
+    if (target_slot != BootControlInterface::kInvalidSlot) {
+      result = system_state->boot_control()->GetPartitionDevice(
+          partition.name, target_slot, &partition.target_path) && result;
+    } else {
+      partition.target_path.clear();
+    }
+  }
+  return result;
+}
+
+bool InstallPlan::Partition::operator==(
+    const InstallPlan::Partition& that) const {
+  return (name == that.name &&
+          source_path == that.source_path &&
+          source_size == that.source_size &&
+          source_hash == that.source_hash &&
+          target_path == that.target_path &&
+          target_size == that.target_size &&
+          target_hash == that.target_hash &&
+          run_postinstall == that.run_postinstall);
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/install_plan.h b/payload_consumer/install_plan.h
new file mode 100644
index 0000000..f412499
--- /dev/null
+++ b/payload_consumer/install_plan.h
@@ -0,0 +1,157 @@
+//
+// Copyright (C) 2011 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.
+//
+
+#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_INSTALL_PLAN_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_INSTALL_PLAN_H_
+
+#include <string>
+#include <vector>
+
+#include <base/macros.h>
+#include <brillo/secure_blob.h>
+
+#include "update_engine/common/action.h"
+#include "update_engine/common/boot_control_interface.h"
+#include "update_engine/system_state.h"
+
+// InstallPlan is a simple struct that contains relevant info for many
+// parts of the update system about the install that should happen.
+namespace chromeos_update_engine {
+
+struct InstallPlan {
+  InstallPlan(bool is_resume,
+              bool is_full_update,
+              const std::string& url,
+              uint64_t payload_size,
+              const std::string& payload_hash,
+              uint64_t metadata_size,
+              const std::string& metadata_signature,
+              const std::string& public_key_rsa);
+
+  // Default constructor.
+  InstallPlan() = default;
+
+  bool operator==(const InstallPlan& that) const;
+  bool operator!=(const InstallPlan& that) const;
+
+  void Dump() const;
+
+  // Load the |source_path| and |target_path| of all |partitions| based on the
+  // |source_slot| and |target_slot| if available. Returns whether it succeeded
+  // to load all the partitions for the valid slots.
+  bool LoadPartitionsFromSlots(SystemState* system_state);
+
+  bool is_resume{false};
+  bool is_full_update{false};
+  std::string download_url;  // url to download from
+  std::string version;       // version we are installing.
+
+  uint64_t payload_size{0};              // size of the payload
+  std::string payload_hash;              // SHA256 hash of the payload
+  uint64_t metadata_size{0};             // size of the metadata
+  std::string metadata_signature;        // signature of the  metadata
+
+  // The partition slots used for the update.
+  BootControlInterface::Slot source_slot{BootControlInterface::kInvalidSlot};
+  BootControlInterface::Slot target_slot{BootControlInterface::kInvalidSlot};
+
+  // The vector below is used for partition verification. The flow is:
+  //
+  // 1. FilesystemVerifierAction computes and fills in the source partition
+  // hash based on the guessed source size for delta major version 1 updates.
+  //
+  // 2. DownloadAction verifies the source partition sizes and hashes against
+  // the expected values transmitted in the update manifest. It fills in the
+  // expected target partition sizes and hashes based on the manifest.
+  //
+  // 3. FilesystemVerifierAction computes and verifies the applied partition
+  // sizes and hashes against the expected values in target_partition_hashes.
+  struct Partition {
+    bool operator==(const Partition& that) const;
+
+    // The name of the partition.
+    std::string name;
+
+    std::string source_path;
+    uint64_t source_size{0};
+    brillo::Blob source_hash;
+
+    std::string target_path;
+    uint64_t target_size{0};
+    brillo::Blob target_hash;
+
+    // Whether we should run the postinstall script from this partition.
+    bool run_postinstall{false};
+  };
+  std::vector<Partition> partitions;
+
+  // True if payload hash checks are mandatory based on the system state and
+  // the Omaha response.
+  bool hash_checks_mandatory{false};
+
+  // True if Powerwash is required on reboot after applying the payload.
+  // False otherwise.
+  bool powerwash_required{false};
+
+  // If not blank, a base-64 encoded representation of the PEM-encoded
+  // public key in the response.
+  std::string public_key_rsa;
+};
+
+class InstallPlanAction;
+
+template<>
+class ActionTraits<InstallPlanAction> {
+ public:
+  // Takes the install plan as input
+  typedef InstallPlan InputObjectType;
+  // Passes the install plan as output
+  typedef InstallPlan OutputObjectType;
+};
+
+// Basic action that only receives and sends Install Plans.
+// Can be used to construct an Install Plan to send to any other Action that
+// accept an InstallPlan.
+class InstallPlanAction : public Action<InstallPlanAction> {
+ public:
+  InstallPlanAction() {}
+  explicit InstallPlanAction(const InstallPlan& install_plan):
+    install_plan_(install_plan) {}
+
+  void PerformAction() override {
+    if (HasOutputPipe()) {
+      SetOutputObject(install_plan_);
+    }
+    processor_->ActionComplete(this, ErrorCode::kSuccess);
+  }
+
+  InstallPlan* install_plan() { return &install_plan_; }
+
+  static std::string StaticType() { return "InstallPlanAction"; }
+  std::string Type() const override { return StaticType(); }
+
+  typedef ActionTraits<InstallPlanAction>::InputObjectType InputObjectType;
+  typedef ActionTraits<InstallPlanAction>::OutputObjectType OutputObjectType;
+
+ private:
+  InstallPlan install_plan_;
+
+  DISALLOW_COPY_AND_ASSIGN(InstallPlanAction);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_INSTALL_PLAN_H_
diff --git a/payload_consumer/mtd_file_descriptor.cc b/payload_consumer/mtd_file_descriptor.cc
new file mode 100644
index 0000000..6f4fae8
--- /dev/null
+++ b/payload_consumer/mtd_file_descriptor.cc
@@ -0,0 +1,265 @@
+//
+// Copyright (C) 2014 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 "update_engine/payload_consumer/mtd_file_descriptor.h"
+
+#include <fcntl.h>
+#include <mtd/ubi-user.h>
+#include <string>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <vector>
+
+#include <base/files/file_path.h>
+#include <base/strings/string_number_conversions.h>
+#include <base/strings/string_util.h>
+#include <base/strings/stringprintf.h>
+#include <update_engine/subprocess.h>
+
+#include "update_engine/common/utils.h"
+
+using std::string;
+using std::vector;
+
+namespace {
+
+static const char kSysfsClassUbi[] = "/sys/class/ubi/";
+static const char kUsableEbSize[] = "/usable_eb_size";
+static const char kReservedEbs[] = "/reserved_ebs";
+
+using chromeos_update_engine::UbiVolumeInfo;
+using chromeos_update_engine::utils::ReadFile;
+
+// Return a UbiVolumeInfo pointer if |path| is a UBI volume. Otherwise, return
+// a null unique pointer.
+std::unique_ptr<UbiVolumeInfo> GetUbiVolumeInfo(const string& path) {
+  base::FilePath device_node(path);
+  base::FilePath ubi_name(device_node.BaseName());
+
+  string sysfs_node(kSysfsClassUbi);
+  sysfs_node.append(ubi_name.MaybeAsASCII());
+
+  std::unique_ptr<UbiVolumeInfo> ret;
+
+  // Obtain volume info from sysfs.
+  string s_reserved_ebs;
+  if (!ReadFile(sysfs_node + kReservedEbs, &s_reserved_ebs)) {
+    LOG(ERROR) << "Cannot read " << sysfs_node + kReservedEbs;
+    return ret;
+  }
+  string s_eb_size;
+  if (!ReadFile(sysfs_node + kUsableEbSize, &s_eb_size)) {
+    LOG(ERROR) << "Cannot read " << sysfs_node + kUsableEbSize;
+    return ret;
+  }
+
+  base::TrimWhitespaceASCII(s_reserved_ebs,
+                            base::TRIM_TRAILING,
+                            &s_reserved_ebs);
+  base::TrimWhitespaceASCII(s_eb_size, base::TRIM_TRAILING, &s_eb_size);
+
+  uint64_t reserved_ebs, eb_size;
+  if (!base::StringToUint64(s_reserved_ebs, &reserved_ebs)) {
+    LOG(ERROR) << "Cannot parse reserved_ebs: " << s_reserved_ebs;
+    return ret;
+  }
+  if (!base::StringToUint64(s_eb_size, &eb_size)) {
+    LOG(ERROR) << "Cannot parse usable_eb_size: " << s_eb_size;
+    return ret;
+  }
+
+  ret.reset(new UbiVolumeInfo);
+  ret->reserved_ebs = reserved_ebs;
+  ret->eraseblock_size = eb_size;
+  return ret;
+}
+
+}  // namespace
+
+namespace chromeos_update_engine {
+
+MtdFileDescriptor::MtdFileDescriptor()
+    : read_ctx_(nullptr, &mtd_read_close),
+      write_ctx_(nullptr, &mtd_write_close) {}
+
+bool MtdFileDescriptor::IsMtd(const char* path) {
+  uint64_t size;
+  return mtd_node_info(path, &size, nullptr, nullptr) == 0;
+}
+
+bool MtdFileDescriptor::Open(const char* path, int flags, mode_t mode) {
+  // This File Descriptor does not support read and write.
+  TEST_AND_RETURN_FALSE((flags & O_ACCMODE) != O_RDWR);
+  // But we need to open the underlying file descriptor in O_RDWR mode because
+  // during write, we need to read back to verify the write actually sticks or
+  // we have to skip the block. That job is done by mtdutils library.
+  if ((flags & O_ACCMODE) == O_WRONLY) {
+    flags &= ~O_ACCMODE;
+    flags |= O_RDWR;
+  }
+  TEST_AND_RETURN_FALSE(
+      EintrSafeFileDescriptor::Open(path, flags | O_CLOEXEC, mode));
+
+  if ((flags & O_ACCMODE) == O_RDWR) {
+    write_ctx_.reset(mtd_write_descriptor(fd_, path));
+    nr_written_ = 0;
+  } else {
+    read_ctx_.reset(mtd_read_descriptor(fd_, path));
+  }
+
+  if (!read_ctx_ && !write_ctx_) {
+    Close();
+    return false;
+  }
+
+  return true;
+}
+
+bool MtdFileDescriptor::Open(const char* path, int flags) {
+  mode_t cur = umask(022);
+  umask(cur);
+  return Open(path, flags, 0777 & ~cur);
+}
+
+ssize_t MtdFileDescriptor::Read(void* buf, size_t count) {
+  CHECK(read_ctx_);
+  return mtd_read_data(read_ctx_.get(), static_cast<char*>(buf), count);
+}
+
+ssize_t MtdFileDescriptor::Write(const void* buf, size_t count) {
+  CHECK(write_ctx_);
+  ssize_t result = mtd_write_data(write_ctx_.get(),
+                                  static_cast<const char*>(buf),
+                                  count);
+  if (result > 0) {
+    nr_written_ += result;
+  }
+  return result;
+}
+
+off64_t MtdFileDescriptor::Seek(off64_t offset, int whence) {
+  if (write_ctx_) {
+    // Ignore seek in write mode.
+    return nr_written_;
+  }
+  return EintrSafeFileDescriptor::Seek(offset, whence);
+}
+
+bool MtdFileDescriptor::Close() {
+  read_ctx_.reset();
+  write_ctx_.reset();
+  return EintrSafeFileDescriptor::Close();
+}
+
+bool UbiFileDescriptor::IsUbi(const char* path) {
+  base::FilePath device_node(path);
+  base::FilePath ubi_name(device_node.BaseName());
+  TEST_AND_RETURN_FALSE(
+      base::StartsWithASCII(ubi_name.MaybeAsASCII(), "ubi", true));
+
+  return static_cast<bool>(GetUbiVolumeInfo(path));
+}
+
+bool UbiFileDescriptor::Open(const char* path, int flags, mode_t mode) {
+  std::unique_ptr<UbiVolumeInfo> info = GetUbiVolumeInfo(path);
+  if (!info) {
+    return false;
+  }
+
+  // This File Descriptor does not support read and write.
+  TEST_AND_RETURN_FALSE((flags & O_ACCMODE) != O_RDWR);
+  TEST_AND_RETURN_FALSE(
+      EintrSafeFileDescriptor::Open(path, flags | O_CLOEXEC, mode));
+
+  usable_eb_blocks_ = info->reserved_ebs;
+  eraseblock_size_ = info->eraseblock_size;
+  volume_size_ = usable_eb_blocks_ * eraseblock_size_;
+
+  if ((flags & O_ACCMODE) == O_WRONLY) {
+    // It's best to use volume update ioctl so that UBI layer will mark the
+    // volume as being updated, and only clear that mark if the update is
+    // successful. We will need to pad to the whole volume size at close.
+    uint64_t vsize = volume_size_;
+    if (ioctl(fd_, UBI_IOCVOLUP, &vsize) != 0) {
+      PLOG(ERROR) << "Cannot issue volume update ioctl";
+      EintrSafeFileDescriptor::Close();
+      return false;
+    }
+    mode_ = kWriteOnly;
+    nr_written_ = 0;
+  } else {
+    mode_ = kReadOnly;
+  }
+
+  return true;
+}
+
+bool UbiFileDescriptor::Open(const char* path, int flags) {
+  mode_t cur = umask(022);
+  umask(cur);
+  return Open(path, flags, 0777 & ~cur);
+}
+
+ssize_t UbiFileDescriptor::Read(void* buf, size_t count) {
+  CHECK(mode_ == kReadOnly);
+  return EintrSafeFileDescriptor::Read(buf, count);
+}
+
+ssize_t UbiFileDescriptor::Write(const void* buf, size_t count) {
+  CHECK(mode_ == kWriteOnly);
+  ssize_t nr_chunk = EintrSafeFileDescriptor::Write(buf, count);
+  if (nr_chunk >= 0) {
+    nr_written_ += nr_chunk;
+  }
+  return nr_chunk;
+}
+
+off64_t UbiFileDescriptor::Seek(off64_t offset, int whence) {
+  if (mode_ == kWriteOnly) {
+    // Ignore seek in write mode.
+    return nr_written_;
+  }
+  return EintrSafeFileDescriptor::Seek(offset, whence);
+}
+
+bool UbiFileDescriptor::Close() {
+  bool pad_ok = true;
+  if (IsOpen() && mode_ == kWriteOnly) {
+    char buf[1024];
+    memset(buf, 0xFF, sizeof(buf));
+    while (nr_written_ < volume_size_) {
+      // We have written less than the whole volume. In order for us to clear
+      // the update marker, we need to fill the rest. It is recommended to fill
+      // UBI writes with 0xFF.
+      uint64_t to_write = volume_size_ - nr_written_;
+      if (to_write > sizeof(buf)) {
+        to_write = sizeof(buf);
+      }
+      ssize_t nr_chunk = EintrSafeFileDescriptor::Write(buf, to_write);
+      if (nr_chunk < 0) {
+        LOG(ERROR) << "Cannot 0xFF-pad before closing.";
+        // There is an error, but we can't really do any meaningful thing here.
+        pad_ok = false;
+        break;
+      }
+      nr_written_ += nr_chunk;
+    }
+  }
+  return EintrSafeFileDescriptor::Close() && pad_ok;
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/mtd_file_descriptor.h b/payload_consumer/mtd_file_descriptor.h
new file mode 100644
index 0000000..9ac1ec1
--- /dev/null
+++ b/payload_consumer/mtd_file_descriptor.h
@@ -0,0 +1,102 @@
+//
+// Copyright (C) 2014 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.
+//
+
+#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_MTD_FILE_DESCRIPTOR_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_MTD_FILE_DESCRIPTOR_H_
+
+// This module defines file descriptors that deal with NAND media. We are
+// concerned with raw NAND access (as MTD device), and through UBI layer.
+
+#include <mtdutils.h>
+
+#include "update_engine/payload_consumer/file_descriptor.h"
+
+namespace chromeos_update_engine {
+
+// A class defining the file descriptor API for raw MTD device. This file
+// descriptor supports either random read, or sequential write but not both at
+// once.
+class MtdFileDescriptor : public EintrSafeFileDescriptor {
+ public:
+  MtdFileDescriptor();
+
+  static bool IsMtd(const char* path);
+
+  bool Open(const char* path, int flags, mode_t mode) override;
+  bool Open(const char* path, int flags) override;
+  ssize_t Read(void* buf, size_t count) override;
+  ssize_t Write(const void* buf, size_t count) override;
+  off64_t Seek(off64_t offset, int whence) override;
+  bool BlkIoctl(int request,
+                uint64_t start,
+                uint64_t length,
+                int* result) override {
+    return false;
+  }
+  bool Close() override;
+
+ private:
+  std::unique_ptr<MtdReadContext, decltype(&mtd_read_close)> read_ctx_;
+  std::unique_ptr<MtdWriteContext, decltype(&mtd_write_close)> write_ctx_;
+  uint64_t nr_written_;
+};
+
+struct UbiVolumeInfo {
+  // Number of eraseblocks.
+  uint64_t reserved_ebs;
+  // Size of each eraseblock.
+  uint64_t eraseblock_size;
+};
+
+// A file descriptor to update a UBI volume, similar to MtdFileDescriptor.
+// Once the file descriptor is opened for write, the volume is marked as being
+// updated. The volume will not be usable until an update is completed. See
+// UBI_IOCVOLUP ioctl operation.
+class UbiFileDescriptor : public EintrSafeFileDescriptor {
+ public:
+  // Perform some queries about |path| to see if it is a UBI volume.
+  static bool IsUbi(const char* path);
+
+  bool Open(const char* path, int flags, mode_t mode) override;
+  bool Open(const char* path, int flags) override;
+  ssize_t Read(void* buf, size_t count) override;
+  ssize_t Write(const void* buf, size_t count) override;
+  off64_t Seek(off64_t offset, int whence) override;
+  bool BlkIoctl(int request,
+                uint64_t start,
+                uint64_t length,
+                int* result) override {
+    return false;
+  }
+  bool Close() override;
+
+ private:
+  enum Mode {
+    kReadOnly,
+    kWriteOnly
+  };
+
+  uint64_t usable_eb_blocks_;
+  uint64_t eraseblock_size_;
+  uint64_t volume_size_;
+  uint64_t nr_written_;
+
+  Mode mode_;
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_MTD_FILE_DESCRIPTOR_H_
diff --git a/payload_consumer/payload_constants.cc b/payload_consumer/payload_constants.cc
new file mode 100644
index 0000000..72abf8c
--- /dev/null
+++ b/payload_consumer/payload_constants.cc
@@ -0,0 +1,59 @@
+//
+// Copyright (C) 2014 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 "update_engine/payload_consumer/payload_constants.h"
+
+namespace chromeos_update_engine {
+
+const uint64_t kChromeOSMajorPayloadVersion = 1;
+const uint64_t kBrilloMajorPayloadVersion = 2;
+
+const uint32_t kFullPayloadMinorVersion = 0;
+const uint32_t kInPlaceMinorPayloadVersion = 1;
+const uint32_t kSourceMinorPayloadVersion = 2;
+const uint32_t kOpSrcHashMinorPayloadVersion = 3;
+
+const char kLegacyPartitionNameKernel[] = "boot";
+const char kLegacyPartitionNameRoot[] = "system";
+
+const char kDeltaMagic[4] = {'C', 'r', 'A', 'U'};
+const char kBspatchPath[] = "bspatch";
+
+const char* InstallOperationTypeName(InstallOperation_Type op_type) {
+  switch (op_type) {
+    case InstallOperation::BSDIFF:
+      return "BSDIFF";
+    case InstallOperation::MOVE:
+      return "MOVE";
+    case InstallOperation::REPLACE:
+      return "REPLACE";
+    case InstallOperation::REPLACE_BZ:
+      return "REPLACE_BZ";
+    case InstallOperation::SOURCE_COPY:
+      return "SOURCE_COPY";
+    case InstallOperation::SOURCE_BSDIFF:
+      return "SOURCE_BSDIFF";
+    case InstallOperation::ZERO:
+      return "ZERO";
+    case InstallOperation::DISCARD:
+      return "DISCARD";
+    case InstallOperation::REPLACE_XZ:
+      return "REPLACE_XZ";
+  }
+  return "<unknown_op>";
+}
+
+};  // namespace chromeos_update_engine
diff --git a/payload_consumer/payload_constants.h b/payload_consumer/payload_constants.h
new file mode 100644
index 0000000..c3cd363
--- /dev/null
+++ b/payload_consumer/payload_constants.h
@@ -0,0 +1,65 @@
+//
+// Copyright (C) 2014 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.
+//
+
+#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_PAYLOAD_CONSTANTS_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_PAYLOAD_CONSTANTS_H_
+
+#include <stdint.h>
+
+#include <limits>
+
+#include "update_engine/update_metadata.pb.h"
+
+namespace chromeos_update_engine {
+
+// The major version used by Chrome OS.
+extern const uint64_t kChromeOSMajorPayloadVersion;
+
+// The major version used by Brillo.
+extern const uint64_t kBrilloMajorPayloadVersion;
+
+// The minor version used for all full payloads.
+extern const uint32_t kFullPayloadMinorVersion;
+
+// The minor version used by the in-place delta generator algorithm.
+extern const uint32_t kInPlaceMinorPayloadVersion;
+
+// The minor version used by the A to B delta generator algorithm.
+extern const uint32_t kSourceMinorPayloadVersion;
+
+// The minor version that allows per-operation source hash.
+extern const uint32_t kOpSrcHashMinorPayloadVersion;
+
+
+// The kernel and rootfs partition names used by the BootControlInterface when
+// handling update payloads with a major version 1. The names of the updated
+// partitions are include in the payload itself for major version 2.
+extern const char kLegacyPartitionNameKernel[];
+extern const char kLegacyPartitionNameRoot[];
+
+extern const char kBspatchPath[];
+extern const char kDeltaMagic[4];
+
+// A block number denoting a hole on a sparse file. Used on Extents to refer to
+// section of blocks not present on disk on a sparse file.
+const uint64_t kSparseHole = std::numeric_limits<uint64_t>::max();
+
+// Return the name of the operation type.
+const char* InstallOperationTypeName(InstallOperation_Type op_type);
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_PAYLOAD_CONSTANTS_H_
diff --git a/payload_consumer/payload_verifier.cc b/payload_consumer/payload_verifier.cc
new file mode 100644
index 0000000..ab5238c
--- /dev/null
+++ b/payload_consumer/payload_verifier.cc
@@ -0,0 +1,183 @@
+//
+// Copyright (C) 2014 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 "update_engine/payload_consumer/payload_verifier.h"
+
+#include <base/logging.h>
+#include <openssl/pem.h>
+
+#include "update_engine/common/hash_calculator.h"
+#include "update_engine/common/utils.h"
+#include "update_engine/update_metadata.pb.h"
+
+using std::string;
+
+namespace chromeos_update_engine {
+
+namespace {
+
+// The following is a standard PKCS1-v1_5 padding for SHA256 signatures, as
+// defined in RFC3447. It is prepended to the actual signature (32 bytes) to
+// form a sequence of 256 bytes (2048 bits) that is amenable to RSA signing. The
+// padded hash will look as follows:
+//
+//    0x00 0x01 0xff ... 0xff 0x00  ASN1HEADER  SHA256HASH
+//   |--------------205-----------||----19----||----32----|
+//
+// where ASN1HEADER is the ASN.1 description of the signed data. The complete 51
+// bytes of actual data (i.e. the ASN.1 header complete with the hash) are
+// packed as follows:
+//
+//  SEQUENCE(2+49) {
+//   SEQUENCE(2+13) {
+//    OBJECT(2+9) id-sha256
+//    NULL(2+0)
+//   }
+//   OCTET STRING(2+32) <actual signature bytes...>
+//  }
+const uint8_t kRSA2048SHA256Padding[] = {
+  // PKCS1-v1_5 padding
+  0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0x00,
+  // ASN.1 header
+  0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+  0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+  0x00, 0x04, 0x20,
+};
+
+}  // namespace
+
+bool PayloadVerifier::VerifySignature(const brillo::Blob& signature_blob,
+                                      const string& public_key_path,
+                                      const brillo::Blob& hash_data) {
+  TEST_AND_RETURN_FALSE(!public_key_path.empty());
+
+  Signatures signatures;
+  LOG(INFO) << "signature blob size = " <<  signature_blob.size();
+  TEST_AND_RETURN_FALSE(signatures.ParseFromArray(signature_blob.data(),
+                                                  signature_blob.size()));
+
+  if (!signatures.signatures_size()) {
+    LOG(ERROR) << "No signatures stored in the blob.";
+    return false;
+  }
+
+  std::vector<brillo::Blob> tested_hashes;
+  // Tries every signature in the signature blob.
+  for (int i = 0; i < signatures.signatures_size(); i++) {
+    const Signatures_Signature& signature = signatures.signatures(i);
+    brillo::Blob sig_data(signature.data().begin(), signature.data().end());
+    brillo::Blob sig_hash_data;
+    if (!GetRawHashFromSignature(sig_data, public_key_path, &sig_hash_data))
+      continue;
+
+    if (hash_data == sig_hash_data) {
+      LOG(INFO) << "Verified correct signature " << i + 1 << " out of "
+                << signatures.signatures_size() << " signatures.";
+      return true;
+    }
+    tested_hashes.push_back(sig_hash_data);
+  }
+  LOG(ERROR) << "None of the " << signatures.signatures_size()
+             << " signatures is correct. Expected:";
+  utils::HexDumpVector(hash_data);
+  LOG(ERROR) << "But found decrypted hashes:";
+  for (const auto& sig_hash_data : tested_hashes) {
+    utils::HexDumpVector(sig_hash_data);
+  }
+  return false;
+}
+
+
+bool PayloadVerifier::GetRawHashFromSignature(
+    const brillo::Blob& sig_data,
+    const string& public_key_path,
+    brillo::Blob* out_hash_data) {
+  TEST_AND_RETURN_FALSE(!public_key_path.empty());
+
+  // The code below executes the equivalent of:
+  //
+  // openssl rsautl -verify -pubin -inkey |public_key_path|
+  //   -in |sig_data| -out |out_hash_data|
+
+  // Loads the public key.
+  FILE* fpubkey = fopen(public_key_path.c_str(), "rb");
+  if (!fpubkey) {
+    LOG(ERROR) << "Unable to open public key file: " << public_key_path;
+    return false;
+  }
+
+  char dummy_password[] = { ' ', 0 };  // Ensure no password is read from stdin.
+  RSA* rsa = PEM_read_RSA_PUBKEY(fpubkey, nullptr, nullptr, dummy_password);
+  fclose(fpubkey);
+  TEST_AND_RETURN_FALSE(rsa != nullptr);
+  unsigned int keysize = RSA_size(rsa);
+  if (sig_data.size() > 2 * keysize) {
+    LOG(ERROR) << "Signature size is too big for public key size.";
+    RSA_free(rsa);
+    return false;
+  }
+
+  // Decrypts the signature.
+  brillo::Blob hash_data(keysize);
+  int decrypt_size = RSA_public_decrypt(sig_data.size(),
+                                        sig_data.data(),
+                                        hash_data.data(),
+                                        rsa,
+                                        RSA_NO_PADDING);
+  RSA_free(rsa);
+  TEST_AND_RETURN_FALSE(decrypt_size > 0 &&
+                        decrypt_size <= static_cast<int>(hash_data.size()));
+  hash_data.resize(decrypt_size);
+  out_hash_data->swap(hash_data);
+  return true;
+}
+
+bool PayloadVerifier::PadRSA2048SHA256Hash(brillo::Blob* hash) {
+  TEST_AND_RETURN_FALSE(hash->size() == 32);
+  hash->insert(hash->begin(),
+               reinterpret_cast<const char*>(kRSA2048SHA256Padding),
+               reinterpret_cast<const char*>(kRSA2048SHA256Padding +
+                                             sizeof(kRSA2048SHA256Padding)));
+  TEST_AND_RETURN_FALSE(hash->size() == 256);
+  return true;
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/payload_verifier.h b/payload_consumer/payload_verifier.h
new file mode 100644
index 0000000..22ced40
--- /dev/null
+++ b/payload_consumer/payload_verifier.h
@@ -0,0 +1,65 @@
+//
+// Copyright (C) 2014 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.
+//
+
+#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_PAYLOAD_VERIFIER_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_PAYLOAD_VERIFIER_H_
+
+#include <string>
+#include <vector>
+
+#include <base/macros.h>
+#include <brillo/secure_blob.h>
+
+#include "update_engine/update_metadata.pb.h"
+
+// This class encapsulates methods used for payload signature verification.
+// See payload_generator/payload_signer.h for payload signing.
+
+namespace chromeos_update_engine {
+
+class PayloadVerifier {
+ public:
+  // Interprets |signature_blob| as a protocol buffer containing the Signatures
+  // message and decrypts each signature data using the |public_key_path|.
+  // Returns whether *any* of the decrypted hashes matches the |hash_data|.
+  // In case of any error parsing the signatures or the public key, returns
+  // false.
+  static bool VerifySignature(const brillo::Blob& signature_blob,
+                              const std::string& public_key_path,
+                              const brillo::Blob& hash_data);
+
+  // Decrypts sig_data with the given public_key_path and populates
+  // out_hash_data with the decoded raw hash. Returns true if successful,
+  // false otherwise.
+  static bool GetRawHashFromSignature(const brillo::Blob& sig_data,
+                                      const std::string& public_key_path,
+                                      brillo::Blob* out_hash_data);
+
+  // Pads a SHA256 hash so that it may be encrypted/signed with RSA2048
+  // using the PKCS#1 v1.5 scheme.
+  // hash should be a pointer to vector of exactly 256 bits. The vector
+  // will be modified in place and will result in having a length of
+  // 2048 bits. Returns true on success, false otherwise.
+  static bool PadRSA2048SHA256Hash(brillo::Blob* hash);
+
+ private:
+  // This should never be constructed
+  DISALLOW_IMPLICIT_CONSTRUCTORS(PayloadVerifier);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_PAYLOAD_VERIFIER_H_
diff --git a/payload_consumer/postinstall_runner_action.cc b/payload_consumer/postinstall_runner_action.cc
new file mode 100644
index 0000000..33bbf5b
--- /dev/null
+++ b/payload_consumer/postinstall_runner_action.cc
@@ -0,0 +1,187 @@
+//
+// Copyright (C) 2011 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 "update_engine/payload_consumer/postinstall_runner_action.h"
+
+#include <stdlib.h>
+#include <sys/mount.h>
+#include <vector>
+
+#include <base/bind.h>
+#include <base/files/file_path.h>
+#include <base/files/file_util.h>
+
+#include "update_engine/common/action_processor.h"
+#include "update_engine/common/subprocess.h"
+#include "update_engine/common/utils.h"
+
+namespace chromeos_update_engine {
+
+using std::string;
+using std::vector;
+
+namespace {
+// The absolute path to the post install command.
+const char kPostinstallScript[] = "/postinst";
+
+// Path to the binary file used by kPostinstallScript. Used to get and log the
+// file format of the binary to debug issues when the ELF format on the update
+// doesn't match the one on the current system. This path is not executed.
+const char kDebugPostinstallBinaryPath[] = "/usr/bin/cros_installer";
+}
+
+void PostinstallRunnerAction::PerformAction() {
+  CHECK(HasInputObject());
+  install_plan_ = GetInputObject();
+
+  if (install_plan_.powerwash_required) {
+    if (utils::CreatePowerwashMarkerFile(powerwash_marker_file_)) {
+      powerwash_marker_created_ = true;
+    } else {
+      return CompletePostinstall(ErrorCode::kPostinstallPowerwashError);
+    }
+  }
+
+  PerformPartitionPostinstall();
+}
+
+void PostinstallRunnerAction::PerformPartitionPostinstall() {
+  // Skip all the partitions that don't have a post-install step.
+  while (current_partition_ < install_plan_.partitions.size() &&
+         !install_plan_.partitions[current_partition_].run_postinstall) {
+    VLOG(1) << "Skipping post-install on partition "
+            << install_plan_.partitions[current_partition_].name;
+    current_partition_++;
+  }
+  if (current_partition_ == install_plan_.partitions.size())
+    return CompletePostinstall(ErrorCode::kSuccess);
+
+  const InstallPlan::Partition& partition =
+      install_plan_.partitions[current_partition_];
+
+  const string mountable_device =
+      utils::MakePartitionNameForMount(partition.target_path);
+  if (mountable_device.empty()) {
+    LOG(ERROR) << "Cannot make mountable device from " << partition.target_path;
+    return CompletePostinstall(ErrorCode::kPostinstallRunnerError);
+  }
+
+  // Perform post-install for the current_partition_ partition. At this point we
+  // need to call CompletePartitionPostinstall to complete the operation and
+  // cleanup.
+  TEST_AND_RETURN(
+      utils::MakeTempDirectory("au_postint_mount.XXXXXX", &temp_rootfs_dir_));
+
+  if (!utils::MountFilesystem(mountable_device, temp_rootfs_dir_, MS_RDONLY)) {
+    return CompletePartitionPostinstall(
+        1, "Error mounting the device " + mountable_device);
+  }
+
+  LOG(INFO) << "Performing postinst (" << kPostinstallScript
+            << ") installed on device " << partition.target_path
+            << " and mountable device " << mountable_device;
+
+  // Logs the file format of the postinstall script we are about to run. This
+  // will help debug when the postinstall script doesn't match the architecture
+  // of our build.
+  LOG(INFO) << "Format file for new " <<  kPostinstallScript << " is: "
+            << utils::GetFileFormat(temp_rootfs_dir_ + kPostinstallScript);
+  LOG(INFO) << "Format file for new " <<  kDebugPostinstallBinaryPath << " is: "
+            << utils::GetFileFormat(
+                temp_rootfs_dir_ + kDebugPostinstallBinaryPath);
+
+  // Runs the postinstall script asynchronously to free up the main loop while
+  // it's running.
+  vector<string> command;
+  if (!install_plan_.download_url.empty()) {
+    command.push_back(temp_rootfs_dir_ + kPostinstallScript);
+  } else {
+    // TODO(sosa): crbug.com/366207.
+    // If we're doing a rollback, just run our own postinstall.
+    command.push_back(kPostinstallScript);
+  }
+  command.push_back(partition.target_path);
+  if (!Subprocess::Get().Exec(
+          command,
+          base::Bind(
+              &PostinstallRunnerAction::CompletePartitionPostinstall,
+              base::Unretained(this)))) {
+    CompletePartitionPostinstall(1, "Postinstall didn't launch");
+  }
+}
+
+void PostinstallRunnerAction::CompletePartitionPostinstall(
+    int return_code,
+    const string& output) {
+  utils::UnmountFilesystem(temp_rootfs_dir_);
+  if (!base::DeleteFile(base::FilePath(temp_rootfs_dir_), false)) {
+    PLOG(WARNING) << "Not removing mountpoint " << temp_rootfs_dir_;
+  }
+  temp_rootfs_dir_.clear();
+
+  if (return_code != 0) {
+    LOG(ERROR) << "Postinst command failed with code: " << return_code;
+    ErrorCode error_code = ErrorCode::kPostinstallRunnerError;
+
+    if (return_code == 3) {
+      // This special return code means that we tried to update firmware,
+      // but couldn't because we booted from FW B, and we need to reboot
+      // to get back to FW A.
+      error_code = ErrorCode::kPostinstallBootedFromFirmwareB;
+    }
+
+    if (return_code == 4) {
+      // This special return code means that we tried to update firmware,
+      // but couldn't because we booted from FW B, and we need to reboot
+      // to get back to FW A.
+      error_code = ErrorCode::kPostinstallFirmwareRONotUpdatable;
+    }
+    return CompletePostinstall(error_code);
+  }
+  current_partition_++;
+  PerformPartitionPostinstall();
+}
+
+void PostinstallRunnerAction::CompletePostinstall(ErrorCode error_code) {
+  // We only attempt to mark the new slot as active if all the postinstall
+  // steps succeeded.
+  if (error_code == ErrorCode::kSuccess &&
+      !system_state_->boot_control()->SetActiveBootSlot(
+          install_plan_.target_slot)) {
+    error_code = ErrorCode::kPostinstallRunnerError;
+  }
+
+  ScopedActionCompleter completer(processor_, this);
+
+  if (error_code != ErrorCode::kSuccess) {
+    LOG(ERROR) << "Postinstall action failed.";
+
+    // Undo any changes done to trigger Powerwash using clobber-state.
+    if (powerwash_marker_created_)
+      utils::DeletePowerwashMarkerFile(powerwash_marker_file_);
+
+    return;
+  }
+
+  LOG(INFO) << "All post-install commands succeeded";
+  if (HasOutputPipe()) {
+    SetOutputObject(install_plan_);
+  }
+
+  completer.set_code(ErrorCode::kSuccess);
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/postinstall_runner_action.h b/payload_consumer/postinstall_runner_action.h
new file mode 100644
index 0000000..de19c0c
--- /dev/null
+++ b/payload_consumer/postinstall_runner_action.h
@@ -0,0 +1,86 @@
+//
+// Copyright (C) 2010 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.
+//
+
+#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_POSTINSTALL_RUNNER_ACTION_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_POSTINSTALL_RUNNER_ACTION_H_
+
+#include <string>
+
+#include "update_engine/common/action.h"
+#include "update_engine/payload_consumer/install_plan.h"
+#include "update_engine/system_state.h"
+
+// The Postinstall Runner Action is responsible for running the postinstall
+// script of a successfully downloaded update.
+
+namespace chromeos_update_engine {
+
+class PostinstallRunnerAction : public InstallPlanAction {
+ public:
+  explicit PostinstallRunnerAction(SystemState* system_state)
+      : PostinstallRunnerAction(system_state, nullptr) {}
+
+  void PerformAction();
+
+  // Note that there's no support for terminating this action currently.
+  void TerminateProcessing() { CHECK(false); }
+
+  // Debugging/logging
+  static std::string StaticType() { return "PostinstallRunnerAction"; }
+  std::string Type() const { return StaticType(); }
+
+ private:
+  friend class PostinstallRunnerActionTest;
+
+  // Special constructor used for testing purposes.
+  PostinstallRunnerAction(SystemState* system_state,
+                          const char* powerwash_marker_file)
+      : system_state_(system_state),
+        powerwash_marker_file_(powerwash_marker_file) {}
+
+  void PerformPartitionPostinstall();
+
+  // Subprocess::Exec callback.
+  void CompletePartitionPostinstall(int return_code,
+                                    const std::string& output);
+
+  //
+  void CompletePostinstall(ErrorCode error_code);
+
+  InstallPlan install_plan_;
+  std::string temp_rootfs_dir_;
+
+  // The partition being processed on the list of partitions specified in the
+  // InstallPlan.
+  size_t current_partition_{0};
+
+  // The main SystemState singleton.
+  SystemState* system_state_;
+
+  // True if Powerwash Marker was created before invoking post-install script.
+  // False otherwise. Used for cleaning up if post-install fails.
+  bool powerwash_marker_created_{false};
+
+  // Non-null value will cause post-install to override the default marker
+  // file name; used for testing.
+  const char* powerwash_marker_file_;
+
+  DISALLOW_COPY_AND_ASSIGN(PostinstallRunnerAction);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_POSTINSTALL_RUNNER_ACTION_H_
diff --git a/payload_consumer/postinstall_runner_action_unittest.cc b/payload_consumer/postinstall_runner_action_unittest.cc
new file mode 100644
index 0000000..c54ace8
--- /dev/null
+++ b/payload_consumer/postinstall_runner_action_unittest.cc
@@ -0,0 +1,260 @@
+//
+// Copyright (C) 2012 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 "update_engine/payload_consumer/postinstall_runner_action.h"
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <base/files/file_util.h>
+#include <base/message_loop/message_loop.h>
+#include <base/strings/string_util.h>
+#include <base/strings/stringprintf.h>
+#include <brillo/bind_lambda.h>
+#include <brillo/message_loops/base_message_loop.h>
+#include <brillo/message_loops/message_loop_utils.h>
+#include <gtest/gtest.h>
+
+#include "update_engine/common/constants.h"
+#include "update_engine/common/test_utils.h"
+#include "update_engine/common/utils.h"
+#include "update_engine/fake_system_state.h"
+
+using brillo::MessageLoop;
+using chromeos_update_engine::test_utils::System;
+using chromeos_update_engine::test_utils::WriteFileString;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+namespace chromeos_update_engine {
+
+class PostinstallRunnerActionTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    loop_.SetAsCurrent();
+    async_signal_handler_.Init();
+    subprocess_.Init(&async_signal_handler_);
+  }
+
+  // DoTest with various combinations of do_losetup, err_code and
+  // powerwash_required.
+  void DoTest(bool do_losetup, int err_code, bool powerwash_required);
+
+ protected:
+  static const char* kImageMountPointTemplate;
+
+  base::MessageLoopForIO base_loop_;
+  brillo::BaseMessageLoop loop_{&base_loop_};
+  brillo::AsynchronousSignalHandler async_signal_handler_;
+  Subprocess subprocess_;
+  FakeSystemState fake_system_state_;
+};
+
+class PostinstActionProcessorDelegate : public ActionProcessorDelegate {
+ public:
+  PostinstActionProcessorDelegate()
+      : code_(ErrorCode::kError),
+        code_set_(false) {}
+  void ProcessingDone(const ActionProcessor* processor,
+                      ErrorCode code) {
+    MessageLoop::current()->BreakLoop();
+  }
+  void ActionCompleted(ActionProcessor* processor,
+                       AbstractAction* action,
+                       ErrorCode code) {
+    if (action->Type() == PostinstallRunnerAction::StaticType()) {
+      code_ = code;
+      code_set_ = true;
+    }
+  }
+  ErrorCode code_;
+  bool code_set_;
+};
+
+TEST_F(PostinstallRunnerActionTest, RunAsRootSimpleTest) {
+  DoTest(true, 0, false);
+}
+
+TEST_F(PostinstallRunnerActionTest, RunAsRootPowerwashRequiredTest) {
+  DoTest(true, 0, true);
+}
+
+TEST_F(PostinstallRunnerActionTest, RunAsRootCantMountTest) {
+  DoTest(false, 0, true);
+}
+
+TEST_F(PostinstallRunnerActionTest, RunAsRootErrScriptTest) {
+  DoTest(true, 1, false);
+}
+
+TEST_F(PostinstallRunnerActionTest, RunAsRootFirmwareBErrScriptTest) {
+  DoTest(true, 3, false);
+}
+
+TEST_F(PostinstallRunnerActionTest, RunAsRootFirmwareROErrScriptTest) {
+  DoTest(true, 4, false);
+}
+
+const char* PostinstallRunnerActionTest::kImageMountPointTemplate =
+    "au_destination-XXXXXX";
+
+void PostinstallRunnerActionTest::DoTest(
+    bool do_losetup,
+    int err_code,
+    bool powerwash_required) {
+  ASSERT_EQ(0, getuid()) << "Run me as root. Ideally don't run other tests "
+                         << "as root, tho.";
+  // True if the post-install action is expected to succeed.
+  bool should_succeed = do_losetup && !err_code;
+
+  string orig_cwd;
+  {
+    vector<char> buf(1000);
+    ASSERT_EQ(buf.data(), getcwd(buf.data(), buf.size()));
+    orig_cwd = string(buf.data(), strlen(buf.data()));
+  }
+
+  // Create a unique named working directory and chdir into it.
+  string cwd;
+  ASSERT_TRUE(utils::MakeTempDirectory(
+          "postinstall_runner_action_unittest-XXXXXX",
+          &cwd));
+  ASSERT_EQ(0, test_utils::Chdir(cwd));
+
+  // Create a 10MiB sparse file to be used as image; format it as ext2.
+  ASSERT_EQ(0, System(
+          "dd if=/dev/zero of=image.dat seek=10485759 bs=1 count=1 "
+          "status=none"));
+  ASSERT_EQ(0, System("mkfs.ext2 -F image.dat"));
+
+  // Create a uniquely named image mount point, mount the image.
+  ASSERT_EQ(0, System(string("mkdir -p ") + kStatefulPartition));
+  string mountpoint;
+  ASSERT_TRUE(utils::MakeTempDirectory(
+          string(kStatefulPartition) + "/" + kImageMountPointTemplate,
+          &mountpoint));
+  ASSERT_EQ(0, System(string("mount -o loop image.dat ") + mountpoint));
+
+  // Generate a fake postinst script inside the image.
+  string script = (err_code ?
+                   base::StringPrintf("#!/bin/bash\nexit %d", err_code) :
+                   base::StringPrintf(
+                       "#!/bin/bash\n"
+                       "mount | grep au_postint_mount | grep ext2\n"
+                       "if [ $? -eq 0 ]; then\n"
+                       "  touch %s/postinst_called\n"
+                       "fi\n",
+                       cwd.c_str()));
+  const string script_file_name = mountpoint + "/postinst";
+  ASSERT_TRUE(WriteFileString(script_file_name, script));
+  ASSERT_EQ(0, System(string("chmod a+x ") + script_file_name));
+
+  // Unmount image; do not remove the uniquely named directory as it will be
+  // reused during the test.
+  ASSERT_TRUE(utils::UnmountFilesystem(mountpoint));
+
+  // get a loop device we can use for the install device
+  string dev = "/dev/null";
+
+  unique_ptr<test_utils::ScopedLoopbackDeviceBinder> loop_releaser;
+  if (do_losetup) {
+    loop_releaser.reset(new test_utils::ScopedLoopbackDeviceBinder(
+            cwd + "/image.dat", &dev));
+  }
+
+  // We use a test-specific powerwash marker file, to avoid race conditions.
+  string powerwash_marker_file = mountpoint + "/factory_install_reset";
+  LOG(INFO) << ">>> powerwash_marker_file=" << powerwash_marker_file;
+
+  ActionProcessor processor;
+  ObjectFeederAction<InstallPlan> feeder_action;
+  InstallPlan::Partition part;
+  part.name = "part";
+  part.target_path = dev;
+  part.run_postinstall = true;
+  InstallPlan install_plan;
+  install_plan.partitions = {part};
+  install_plan.download_url = "http://devserver:8080/update";
+  install_plan.powerwash_required = powerwash_required;
+  feeder_action.set_obj(install_plan);
+  PostinstallRunnerAction runner_action(&fake_system_state_,
+                                        powerwash_marker_file.c_str());
+  BondActions(&feeder_action, &runner_action);
+  ObjectCollectorAction<InstallPlan> collector_action;
+  BondActions(&runner_action, &collector_action);
+  PostinstActionProcessorDelegate delegate;
+  processor.EnqueueAction(&feeder_action);
+  processor.EnqueueAction(&runner_action);
+  processor.EnqueueAction(&collector_action);
+  processor.set_delegate(&delegate);
+
+  loop_.PostTask(FROM_HERE,
+                 base::Bind([&processor] { processor.StartProcessing(); }));
+  loop_.Run();
+  ASSERT_FALSE(processor.IsRunning());
+
+  EXPECT_TRUE(delegate.code_set_);
+  EXPECT_EQ(should_succeed, delegate.code_ == ErrorCode::kSuccess);
+  if (should_succeed)
+    EXPECT_TRUE(install_plan == collector_action.object());
+
+  const base::FilePath kPowerwashMarkerPath(powerwash_marker_file);
+  string actual_cmd;
+  if (should_succeed && powerwash_required) {
+    EXPECT_TRUE(base::ReadFileToString(kPowerwashMarkerPath, &actual_cmd));
+    EXPECT_EQ(kPowerwashCommand, actual_cmd);
+  } else {
+    EXPECT_FALSE(
+        base::ReadFileToString(kPowerwashMarkerPath, &actual_cmd));
+  }
+
+  if (err_code == 2)
+    EXPECT_EQ(ErrorCode::kPostinstallBootedFromFirmwareB, delegate.code_);
+
+  struct stat stbuf;
+  int rc = lstat((string(cwd) + "/postinst_called").c_str(), &stbuf);
+  if (should_succeed)
+    ASSERT_EQ(0, rc);
+  else
+    ASSERT_LT(rc, 0);
+
+  if (do_losetup) {
+    loop_releaser.reset(nullptr);
+  }
+
+  // Remove unique stateful directory.
+  ASSERT_EQ(0, System(string("rm -fr ") + mountpoint));
+
+  // Remove the temporary work directory.
+  ASSERT_EQ(0, test_utils::Chdir(orig_cwd));
+  ASSERT_EQ(0, System(string("rm -fr ") + cwd));
+}
+
+// Death tests don't seem to be working on Hardy
+TEST_F(PostinstallRunnerActionTest, DISABLED_RunAsRootDeathTest) {
+  ASSERT_EQ(0, getuid());
+  PostinstallRunnerAction runner_action(&fake_system_state_);
+  ASSERT_DEATH({ runner_action.TerminateProcessing(); },
+               "postinstall_runner_action.h:.*] Check failed");
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/xz_extent_writer.cc b/payload_consumer/xz_extent_writer.cc
new file mode 100644
index 0000000..4bd893d
--- /dev/null
+++ b/payload_consumer/xz_extent_writer.cc
@@ -0,0 +1,118 @@
+//
+// Copyright (C) 2015 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 "update_engine/payload_consumer/xz_extent_writer.h"
+
+using std::vector;
+
+namespace chromeos_update_engine {
+
+namespace {
+const brillo::Blob::size_type kOutputBufferLength = 16 * 1024;
+
+// xz uses a variable dictionary size which impacts on the compression ratio
+// and is required to be reconstructed in RAM during decompression. While we
+// control the required memory from the compressor side, the decompressor allows
+// to set a limit on this dictionary size, rejecting compressed streams that
+// require more than that. "xz -9" requires up to 64 MiB, so a 64 MiB limit
+// will allow compressed streams up to -9, the maximum compression setting.
+const uint32_t kXzMaxDictSize = 64 * 1024 * 1024;
+
+const char* XzErrorString(enum xz_ret error) {
+  #define __XZ_ERROR_STRING_CASE(code) case code: return #code;
+  switch (error) {
+    __XZ_ERROR_STRING_CASE(XZ_OK)
+    __XZ_ERROR_STRING_CASE(XZ_STREAM_END)
+    __XZ_ERROR_STRING_CASE(XZ_UNSUPPORTED_CHECK)
+    __XZ_ERROR_STRING_CASE(XZ_MEM_ERROR)
+    __XZ_ERROR_STRING_CASE(XZ_MEMLIMIT_ERROR)
+    __XZ_ERROR_STRING_CASE(XZ_FORMAT_ERROR)
+    __XZ_ERROR_STRING_CASE(XZ_OPTIONS_ERROR)
+    __XZ_ERROR_STRING_CASE(XZ_DATA_ERROR)
+    __XZ_ERROR_STRING_CASE(XZ_BUF_ERROR)
+    default:
+      return "<unknown xz error>";
+  }
+  #undef __XZ_ERROR_STRING_CASE
+};
+}  // namespace
+
+XzExtentWriter::~XzExtentWriter() {
+  xz_dec_end(stream_);
+}
+
+bool XzExtentWriter::Init(FileDescriptorPtr fd,
+                          const vector<Extent>& extents,
+                          uint32_t block_size) {
+  stream_ = xz_dec_init(XZ_DYNALLOC, kXzMaxDictSize);
+  TEST_AND_RETURN_FALSE(stream_ != nullptr);
+  return underlying_writer_->Init(fd, extents, block_size);
+}
+
+bool XzExtentWriter::Write(const void* bytes, size_t count) {
+  // Copy the input data into |input_buffer_| only if |input_buffer_| already
+  // contains unconsumed data. Otherwise, process the data directly from the
+  // source.
+  const uint8_t* input = reinterpret_cast<const uint8_t*>(bytes);
+  if (!input_buffer_.empty()) {
+    input_buffer_.insert(input_buffer_.end(), input, input + count);
+    input = input_buffer_.data();
+    count = input_buffer_.size();
+  }
+
+  xz_buf request;
+  request.in = input;
+  request.in_pos = 0;
+  request.in_size = count;
+
+  brillo::Blob output_buffer(kOutputBufferLength);
+  request.out = output_buffer.data();
+  request.out_size = output_buffer.size();
+  for (;;) {
+    request.out_pos = 0;
+
+    xz_ret ret = xz_dec_run(stream_, &request);
+    if (ret != XZ_OK && ret != XZ_STREAM_END) {
+      LOG(ERROR) << "xz_dec_run returned " << XzErrorString(ret);
+      return false;
+    }
+
+    if (request.out_pos == 0)
+      break;
+
+    TEST_AND_RETURN_FALSE(
+        underlying_writer_->Write(output_buffer.data(), request.out_pos));
+    if (ret == XZ_STREAM_END)
+      CHECK_EQ(request.in_size, request.in_pos);
+    if (request.in_size == request.in_pos)
+      break;  // No more input to process.
+  }
+  output_buffer.clear();
+
+  // Store unconsumed data (if any) in |input_buffer_|. Since |input| can point
+  // to the existing |input_buffer_| we create a new one before assigning it.
+  brillo::Blob new_input_buffer(request.in + request.in_pos,
+                                request.in + request.in_size);
+  input_buffer_ = std::move(new_input_buffer);
+  return true;
+}
+
+bool XzExtentWriter::EndImpl() {
+  TEST_AND_RETURN_FALSE(input_buffer_.empty());
+  return underlying_writer_->End();
+}
+
+}  // namespace chromeos_update_engine
diff --git a/payload_consumer/xz_extent_writer.h b/payload_consumer/xz_extent_writer.h
new file mode 100644
index 0000000..a6b3257
--- /dev/null
+++ b/payload_consumer/xz_extent_writer.h
@@ -0,0 +1,60 @@
+//
+// Copyright (C) 2015 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.
+//
+
+#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_XZ_EXTENT_WRITER_H_
+#define UPDATE_ENGINE_PAYLOAD_CONSUMER_XZ_EXTENT_WRITER_H_
+
+#include <xz.h>
+
+#include <memory>
+#include <vector>
+
+#include <brillo/secure_blob.h>
+
+#include "update_engine/payload_consumer/extent_writer.h"
+
+// XzExtentWriter is a concrete ExtentWriter subclass that xz-decompresses
+// what it's given in Write using xz-embedded. Note that xz-embedded only
+// supports files with either no CRC or CRC-32. It passes the decompressed data
+// to an underlying ExtentWriter.
+
+namespace chromeos_update_engine {
+
+class XzExtentWriter : public ExtentWriter {
+ public:
+  explicit XzExtentWriter(std::unique_ptr<ExtentWriter> underlying_writer)
+      : underlying_writer_(std::move(underlying_writer)) {}
+  ~XzExtentWriter() override;
+
+  bool Init(FileDescriptorPtr fd,
+            const std::vector<Extent>& extents,
+            uint32_t block_size) override;
+  bool Write(const void* bytes, size_t count) override;
+  bool EndImpl() override;
+
+ private:
+  // The underlying ExtentWriter.
+  std::unique_ptr<ExtentWriter> underlying_writer_;
+  // The opaque xz decompressor struct.
+  xz_dec* stream_{nullptr};
+  brillo::Blob input_buffer_;
+
+  DISALLOW_COPY_AND_ASSIGN(XzExtentWriter);
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_XZ_EXTENT_WRITER_H_
diff --git a/payload_consumer/xz_extent_writer_unittest.cc b/payload_consumer/xz_extent_writer_unittest.cc
new file mode 100644
index 0000000..fb8bb40
--- /dev/null
+++ b/payload_consumer/xz_extent_writer_unittest.cc
@@ -0,0 +1,165 @@
+//
+// Copyright (C) 2015 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 "update_engine/payload_consumer/xz_extent_writer.h"
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include <brillo/make_unique_ptr.h>
+#include <gtest/gtest.h>
+
+#include "update_engine/common/test_utils.h"
+#include "update_engine/common/utils.h"
+#include "update_engine/payload_consumer/fake_extent_writer.h"
+
+using std::string;
+using std::vector;
+
+namespace chromeos_update_engine {
+
+namespace {
+
+const char kSampleData[] = "Redundaaaaaaaaaaaaaant\n";
+
+// Compressed data with CRC-32 check, generated with:
+// echo "Redundaaaaaaaaaaaaaant" | xz -9 --check=crc32 |
+// hexdump -v -e '"    " 12/1 "0x%02x, " "\n"'
+const uint8_t kCompressedDataCRC32[] = {
+    0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x01, 0x69, 0x22, 0xde, 0x36,
+    0x02, 0x00, 0x21, 0x01, 0x1c, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x58, 0xcc,
+    0xe0, 0x00, 0x16, 0x00, 0x10, 0x5d, 0x00, 0x29, 0x19, 0x48, 0x87, 0x88,
+    0xec, 0x49, 0x88, 0x73, 0x8b, 0x5d, 0xa6, 0x46, 0xb4, 0x00, 0x00, 0x00,
+    0x68, 0xfc, 0x7b, 0x25, 0x00, 0x01, 0x28, 0x17, 0x46, 0x9e, 0x08, 0xfe,
+    0x90, 0x42, 0x99, 0x0d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5a,
+};
+
+// Compressed data without checksum, generated with:
+// echo "Redundaaaaaaaaaaaaaant" | xz -9 --check=none |
+// hexdump -v -e '"    " 12/1 "0x%02x, " "\n"'
+const uint8_t kCompressedDataNoCheck[] = {
+    0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x00, 0xff, 0x12, 0xd9, 0x41,
+    0x02, 0x00, 0x21, 0x01, 0x1c, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x58, 0xcc,
+    0xe0, 0x00, 0x16, 0x00, 0x10, 0x5d, 0x00, 0x29, 0x19, 0x48, 0x87, 0x88,
+    0xec, 0x49, 0x88, 0x73, 0x8b, 0x5d, 0xa6, 0x46, 0xb4, 0x00, 0x00, 0x00,
+    0x00, 0x01, 0x24, 0x17, 0x4a, 0xd1, 0xbd, 0x52, 0x06, 0x72, 0x9e, 0x7a,
+    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x5a,
+};
+
+// Highly redundant data bigger than the internal buffer, generated with:
+// dd if=/dev/zero bs=30K count=1 | tr '\0' 'a' | xz -9 --check=crc32 |
+// hexdump -v -e '"    " 12/1 "0x%02x, " "\n"'
+const uint8_t kCompressed30KiBofA[] = {
+    0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x01, 0x69, 0x22, 0xde, 0x36,
+    0x02, 0x00, 0x21, 0x01, 0x1c, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x58, 0xcc,
+    0xe0, 0x77, 0xff, 0x00, 0x41, 0x5d, 0x00, 0x30, 0xef, 0xfb, 0xbf, 0xfe,
+    0xa3, 0xb1, 0x5e, 0xe5, 0xf8, 0x3f, 0xb2, 0xaa, 0x26, 0x55, 0xf8, 0x68,
+    0x70, 0x41, 0x70, 0x15, 0x0f, 0x8d, 0xfd, 0x1e, 0x4c, 0x1b, 0x8a, 0x42,
+    0xb7, 0x19, 0xf4, 0x69, 0x18, 0x71, 0xae, 0x66, 0x23, 0x8a, 0x8a, 0x4d,
+    0x2f, 0xa3, 0x0d, 0xd9, 0x7f, 0xa6, 0xe3, 0x8c, 0x23, 0x11, 0x53, 0xe0,
+    0x59, 0x18, 0xc5, 0x75, 0x8a, 0xe2, 0x76, 0x4c, 0xee, 0x30, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xf9, 0x47, 0xb5, 0xee, 0x00, 0x01, 0x59, 0x80,
+    0xf0, 0x01, 0x00, 0x00, 0xe0, 0x41, 0x96, 0xde, 0x3e, 0x30, 0x0d, 0x8b,
+    0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5a,
+};
+
+}  // namespace
+
+class XzExtentWriterTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    fake_extent_writer_ = new FakeExtentWriter();
+    xz_writer_.reset(
+        new XzExtentWriter(brillo::make_unique_ptr(fake_extent_writer_)));
+  }
+
+  void WriteAll(const brillo::Blob& compressed) {
+    EXPECT_TRUE(xz_writer_->Init(fd_, {}, 1024));
+    EXPECT_TRUE(xz_writer_->Write(compressed.data(), compressed.size()));
+    EXPECT_TRUE(xz_writer_->End());
+
+    EXPECT_TRUE(fake_extent_writer_->InitCalled());
+    EXPECT_TRUE(fake_extent_writer_->EndCalled());
+  }
+
+  // Owned by |xz_writer_|. This object is invalidated after |xz_writer_| is
+  // deleted.
+  FakeExtentWriter* fake_extent_writer_{nullptr};
+  std::unique_ptr<XzExtentWriter> xz_writer_;
+
+  const brillo::Blob sample_data_{
+      std::begin(kSampleData),
+      std::begin(kSampleData) + strlen(kSampleData)};
+  FileDescriptorPtr fd_;
+};
+
+TEST_F(XzExtentWriterTest, CreateAndDestroy) {
+  // Test that no Init() or End() called doesn't crash the program.
+  EXPECT_FALSE(fake_extent_writer_->InitCalled());
+  EXPECT_FALSE(fake_extent_writer_->EndCalled());
+}
+
+TEST_F(XzExtentWriterTest, CompressedSampleData) {
+  WriteAll(brillo::Blob(std::begin(kCompressedDataNoCheck),
+                          std::end(kCompressedDataNoCheck)));
+  EXPECT_EQ(sample_data_, fake_extent_writer_->WrittenData());
+}
+
+TEST_F(XzExtentWriterTest, CompressedSampleDataWithCrc) {
+  WriteAll(brillo::Blob(std::begin(kCompressedDataCRC32),
+                          std::end(kCompressedDataCRC32)));
+  EXPECT_EQ(sample_data_, fake_extent_writer_->WrittenData());
+}
+
+TEST_F(XzExtentWriterTest, CompressedDataBiggerThanTheBuffer) {
+  // Test that even if the output data is bigger than the internal buffer, all
+  // the data is written.
+  WriteAll(brillo::Blob(std::begin(kCompressed30KiBofA),
+                          std::end(kCompressed30KiBofA)));
+  brillo::Blob expected_data(30 * 1024, 'a');
+  EXPECT_EQ(expected_data, fake_extent_writer_->WrittenData());
+}
+
+TEST_F(XzExtentWriterTest, GarbageDataRejected) {
+  EXPECT_TRUE(xz_writer_->Init(fd_, {}, 1024));
+  // The sample_data_ is an uncompressed string.
+  EXPECT_FALSE(xz_writer_->Write(sample_data_.data(), sample_data_.size()));
+  EXPECT_TRUE(xz_writer_->End());
+
+  EXPECT_TRUE(fake_extent_writer_->EndCalled());
+}
+
+TEST_F(XzExtentWriterTest, PartialDataIsKept) {
+  brillo::Blob compressed(std::begin(kCompressed30KiBofA),
+                            std::end(kCompressed30KiBofA));
+  EXPECT_TRUE(xz_writer_->Init(fd_, {}, 1024));
+  for (uint8_t byte : compressed) {
+    EXPECT_TRUE(xz_writer_->Write(&byte, 1));
+  }
+  EXPECT_TRUE(xz_writer_->End());
+
+  // The sample_data_ is an uncompressed string.
+  brillo::Blob expected_data(30 * 1024, 'a');
+  EXPECT_EQ(expected_data, fake_extent_writer_->WrittenData());
+}
+
+}  // namespace chromeos_update_engine
