AU: Gut code for old updater. New protobuf for v2 updater.

Review URL: http://codereview.chromium.org/545072
diff --git a/SConstruct b/SConstruct
index 1f7ff0f..d408cb7 100644
--- a/SConstruct
+++ b/SConstruct
@@ -2,6 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import os
+
 # Protobuffer compilation
 """ Inputs:
         target: list of targets to compile to
@@ -90,7 +92,6 @@
                    filesystem_iterator.cc
                    file_writer.cc
                    gzip.cc
-                   install_action.cc
                    libcurl_http_fetcher.cc
                    omaha_hash_calculator.cc
                    omaha_request_prep_action.cc
@@ -114,8 +115,6 @@
                             filesystem_iterator_unittest.cc
                             gzip_unittest.cc
                             http_fetcher_unittest.cc
-                            install_action_unittest.cc
-                            integration_unittest.cc
                             mock_http_fetcher.cc
                             omaha_hash_calculator_unittest.cc
                             omaha_request_prep_action_unittest.cc
diff --git a/delta_diff_generator.cc b/delta_diff_generator.cc
index 2dacfdf..4114c32 100644
--- a/delta_diff_generator.cc
+++ b/delta_diff_generator.cc
@@ -3,523 +3,3 @@
 // found in the LICENSE file.
 
 #include "update_engine/delta_diff_generator.h"
-#include <dirent.h>
-#include <endian.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <algorithm>
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-#include <tr1/memory>
-#include <zlib.h>
-#include "chromeos/obsolete_logging.h"
-#include "base/scoped_ptr.h"
-#include "update_engine/delta_diff_parser.h"
-#include "update_engine/gzip.h"
-#include "update_engine/subprocess.h"
-#include "update_engine/utils.h"
-
-using std::map;
-using std::set;
-using std::string;
-using std::vector;
-using std::tr1::shared_ptr;
-using chromeos_update_engine::DeltaArchiveManifest;
-
-namespace chromeos_update_engine {
-
-namespace {
-
-const char* kBsdiffPath = "/usr/bin/bsdiff";
-
-// These structs and methods are helpers for EncodeDataToDeltaFile()
-
-// Before moving the data into a proto buffer, the data is stored in
-// memory in these Node and Child structures.
-
-// Each Node struct represents a file on disk (which can be regular file,
-// directory, fifo, socket, symlink, etc). Nodes that contain children
-// (just directories) will have a vector of Child objects. Each child
-// object has a filename and a pointer to the associated Node. Thus,
-// filenames for files are stored with their parents, not as part of
-// the file itself.
-
-// These structures are easier to work with than the protobuf format
-// when adding files. When generating a delta file, we add an entry
-// for each file to a root Node object. Then, we sort each Node's
-// children vector so the children are stored alphabetically. Then,
-// we assign an index value to the idx field of each Node by a preorder
-// tree traversal. The index value assigned to a Node is the index it
-// will have in the DeltaArchiveManifest protobuf.
-// Finally, we add each Node to a DeltaArchiveManifest protobuf.
-
-struct Node;
-
-struct Child {
-  Child(const string& the_name,
-        Node* the_node)
-      : name(the_name),
-        node(the_node) {}
-  string name;
-  // Use shared_ptr here rather than scoped_ptr b/c this struct will be copied
-  // in stl containers
-  scoped_ptr<Node> node;
-};
-
-// For the C++ sort() function.
-struct ChildLessThan {
-  bool operator()(const shared_ptr<Child>& a, const shared_ptr<Child>& b) {
-    return a->name < b->name;
-  }
-};
-
-struct Node {
-  Node()
-      : mode(0),
-        uid(0),
-        gid(0),
-        nlink(0),
-        inode(0),
-        compressed(false),
-        offset(-1),
-        length(0),
-        idx(0) {}
-
-  mode_t mode;
-  uid_t uid;
-  gid_t gid;
-
-  // a file may be a potential hardlink if it's not a directory
-  // and it has a link count > 1.
-  bool IsPotentialHardlink() const {
-    return !S_ISDIR(mode) && nlink > 1;
-  }
-  nlink_t nlink;  // number of hard links
-  ino_t inode;
-
-  // data
-  bool compressed;
-  int offset;  // -1 means no data
-  int length;
-
-  vector<shared_ptr<Child> > children;
-  int idx;
-};
-
-// This function sets *node's variables to match what's at path.
-// This includes calling this function recursively on all children. Children
-// not on the same device as the original node will not be considered.
-// Returns true on success.
-bool UpdateNodeFromPath(const string& path, Node* node) {
-  // Set metadata
-  struct stat stbuf;
-  TEST_AND_RETURN_FALSE_ERRNO(lstat(path.c_str(), &stbuf) == 0);
-  const dev_t dev = stbuf.st_dev;
-  node->mode = stbuf.st_mode;
-  node->uid = stbuf.st_uid;
-  node->gid = stbuf.st_gid;
-  node->nlink = stbuf.st_nlink;
-  node->inode = stbuf.st_ino;
-  if (!S_ISDIR(node->mode)) {
-    return true;
-  }
-
-  DIR* dir = opendir(path.c_str());
-  TEST_AND_RETURN_FALSE(dir);
-
-  struct dirent entry;
-  struct dirent* dir_entry;
-
-  for (;;) {
-    TEST_AND_RETURN_FALSE_ERRNO(readdir_r(dir, &entry, &dir_entry) == 0);
-    if (!dir_entry) {
-      // done
-      break;
-    }
-    if (!strcmp(".", dir_entry->d_name))
-      continue;
-    if (!strcmp("..", dir_entry->d_name))
-      continue;
-
-    string child_path = path + "/" + dir_entry->d_name;
-    struct stat child_stbuf;
-    TEST_AND_RETURN_FALSE_ERRNO(lstat(child_path.c_str(), &child_stbuf) == 0);
-    // make sure it's on the same dev
-    if (child_stbuf.st_dev != dev)
-      continue;
-    shared_ptr<Child> child(new Child(dir_entry->d_name, new Node));
-    node->children.push_back(child);
-    TEST_AND_RETURN_FALSE(UpdateNodeFromPath(path + "/" + child->name,
-                                             child->node.get()));
-  }
-  TEST_AND_RETURN_FALSE_ERRNO(closedir(dir) == 0);
-  // Done with all subdirs. sort children.
-  sort(node->children.begin(), node->children.end(), ChildLessThan());
-  return true;
-}
-
-// We go through n setting the index value of each Node to
-// *next_index_value, then increment next_index_value.
-// We then recursively assign index values to children.
-// The first caller should call this with *next_index_value == 0 and
-// the root Node, thus setting the root Node's index to 0.
-void PopulateChildIndexes(Node* n, int* next_index_value) {
-  n->idx = (*next_index_value)++;
-  for (unsigned int i = 0; i < n->children.size(); i++) {
-    PopulateChildIndexes(n->children[i]->node.get(), next_index_value);
-  }
-}
-
-// This converts a Node tree rooted at n into a DeltaArchiveManifest.
-void NodeToDeltaArchiveManifest(Node* n, DeltaArchiveManifest* archive,
-                                map<ino_t, string>* hard_links,
-                                const string& path) {
-  DeltaArchiveManifest_File *f = archive->add_files();
-  f->set_mode(n->mode);
-  f->set_uid(n->uid);
-  f->set_gid(n->gid);
-  if (utils::MapContainsKey(*hard_links, n->inode)) {
-    // We have a hard link
-    CHECK(!S_ISDIR(n->mode));
-    f->set_hardlink_path((*hard_links)[n->inode]);
-  } else if (n->IsPotentialHardlink()) {
-    (*hard_links)[n->inode] = path;
-  }
-  if (!S_ISDIR(n->mode))
-    return;
-  for (unsigned int i = 0; i < n->children.size(); i++) {
-    DeltaArchiveManifest_File_Child* child = f->add_children();
-    child->set_name(n->children[i]->name);
-    child->set_index(n->children[i]->node->idx);
-  }
-  for (unsigned int i = 0; i < n->children.size(); i++) {
-    NodeToDeltaArchiveManifest(n->children[i]->node.get(), archive, hard_links,
-                               path + "/" + n->children[i]->name);
-  }
-}
-
-}  // namespace {}
-
-// For each file in archive, write a delta for it into out_file
-// and update 'file' to refer to the delta.
-// This is a recursive function. Returns true on success.
-bool DeltaDiffGenerator::WriteFileDiffsToDeltaFile(
-    DeltaArchiveManifest* archive,
-    DeltaArchiveManifest_File* file,
-    const string& file_name,
-    const string& old_path,
-    const string& new_path,
-    FileWriter* out_file_writer,
-    int* out_file_length,
-    set<string> always_full_target_paths,
-    const string& force_compress_dev_path) {
-  TEST_AND_RETURN_FALSE(file->has_mode());
-
-  // Stat the actual file, too
-  struct stat stbuf;
-  TEST_AND_RETURN_FALSE_ERRNO(lstat((new_path + "/" + file_name).c_str(),
-                                    &stbuf) == 0);
-  TEST_AND_RETURN_FALSE(stbuf.st_mode == file->mode());
-
-  // See if we're a directory or not
-  if (S_ISDIR(file->mode())) {
-    for (int i = 0; i < file->children_size(); i++) {
-      DeltaArchiveManifest_File_Child* child = file->mutable_children(i);
-      DeltaArchiveManifest_File* child_file =
-          archive->mutable_files(child->index());
-      string recurse_old_path = old_path;
-      string recurse_new_path = new_path;
-      if (!file_name.empty()) {
-        recurse_new_path += "/" + file_name;
-        recurse_old_path += "/" + file_name;
-      }
-      TEST_AND_RETURN_FALSE(WriteFileDiffsToDeltaFile(
-          archive,
-          child_file,
-          child->name(),
-          recurse_old_path,
-          recurse_new_path,
-          out_file_writer,
-          out_file_length,
-          always_full_target_paths,
-          force_compress_dev_path));
-    }
-    return true;
-  }
-
-  if (S_ISFIFO(file->mode()) || S_ISSOCK(file->mode()) ||
-      file->has_hardlink_path()) {
-    // These don't store any additional data
-    return true;
-  }
-
-  vector<char> data;
-  bool should_compress = true;
-  bool format_set = false;
-  DeltaArchiveManifest_File_DataFormat format;
-  if (S_ISLNK(file->mode())) {
-    TEST_AND_RETURN_FALSE(EncodeLink(new_path + "/" + file_name, &data));
-  } else if (S_ISCHR(file->mode()) || S_ISBLK(file->mode())) {
-    TEST_AND_RETURN_FALSE(EncodeDev(stbuf, &data, &format,
-                                    new_path + "/" + file_name ==
-                                    force_compress_dev_path));
-    format_set = true;
-  } else if (S_ISREG(file->mode())) {
-    // regular file. We may use a delta here.
-    const bool avoid_diff = utils::SetContainsKey(always_full_target_paths,
-                                                  new_path + "/" + file_name);
-    bool no_change = false;
-    TEST_AND_RETURN_FALSE(EncodeFile(old_path, new_path, file_name,
-                                     avoid_diff, &format, &data, &no_change));
-    if (no_change) {
-      // No data change. We're done!
-      return true;
-    }
-    should_compress = false;
-    format_set = true;
-    if ((format == DeltaArchiveManifest_File_DataFormat_BSDIFF) ||
-        (format == DeltaArchiveManifest_File_DataFormat_FULL_GZ))
-      TEST_AND_RETURN_FALSE(!data.empty());
-  } else {
-    // Should never get here; unhandled mode type.
-    LOG(ERROR) << "Unhandled mode type: " << file->mode();
-    return false;
-  }
-
-  if (!format_set) {
-    // Pick a format now
-    vector<char> compressed_data;
-    TEST_AND_RETURN_FALSE(GzipCompress(data, &compressed_data));
-    if (compressed_data.size() < data.size()) {
-      format = DeltaArchiveManifest_File_DataFormat_FULL_GZ;
-      data.swap(compressed_data);
-    } else {
-      format = DeltaArchiveManifest_File_DataFormat_FULL;
-    }
-    format_set = true;
-  }
-
-  TEST_AND_RETURN_FALSE(format_set);
-  file->set_data_format(format);
-  file->set_data_offset(*out_file_length);
-  TEST_AND_RETURN_FALSE(static_cast<ssize_t>(data.size()) ==
-                        out_file_writer->Write(&data[0], data.size()));
-  file->set_data_length(data.size());
-  *out_file_length += data.size();
-  return true;
-}
-
-bool DeltaDiffGenerator::EncodeLink(const string& path, vector<char>* out) {
-  // Store symlink path as file data
-  vector<char> link_data(4096);
-  int rc = readlink(path.c_str(), &link_data[0], link_data.size());
-  TEST_AND_RETURN_FALSE_ERRNO(rc >= 0);
-  link_data.resize(rc);
-  out->swap(link_data);
-  return true;
-}
-
-bool DeltaDiffGenerator::EncodeDev(
-    const struct stat& stbuf,
-    vector<char>* out,
-    DeltaArchiveManifest_File_DataFormat* format,
-    bool force_compression) {
-  LinuxDevice dev;
-  dev.set_major(major(stbuf.st_rdev));
-  dev.set_minor(minor(stbuf.st_rdev));
-  out->resize(dev.ByteSize());
-  TEST_AND_RETURN_FALSE(dev.SerializeToArray(&(*out)[0], out->size()));
-  if (force_compression) {
-    vector<char> compressed;
-    TEST_AND_RETURN_FALSE(GzipCompress(*out, &compressed));
-    out->swap(compressed);
-    *format = DeltaArchiveManifest_File_DataFormat_FULL_GZ;
-  } else {
-    *format = DeltaArchiveManifest_File_DataFormat_FULL;
-  }
-  return true;
-}
-
-// Encode the file at new_path + "/" + file_name. It may be a binary diff
-// based on old_path + "/" + file_name. out_data_format will be set to
-// the format used. out_data_format may not be NULL.
-bool DeltaDiffGenerator::EncodeFile(
-    const string& old_dir,
-    const string& new_dir,
-    const string& file_name,
-    const bool avoid_diff,
-    DeltaArchiveManifest_File_DataFormat* out_data_format,
-    vector<char>* out,
-    bool* no_change) {
-  TEST_AND_RETURN_FALSE(out_data_format);
-  vector<char> ret;
-  vector<char> full_data;
-  {
-    // First, see the full length:
-    TEST_AND_RETURN_FALSE(utils::ReadFile(new_dir + "/" + file_name,
-                                          &full_data));
-    vector<char> gz_data;
-    if (!full_data.empty()) {
-      TEST_AND_RETURN_FALSE(GzipCompress(full_data, &gz_data));
-    }
-
-    if (gz_data.size() < full_data.size()) {
-      *out_data_format = DeltaArchiveManifest_File_DataFormat_FULL_GZ;
-      ret.swap(gz_data);
-    } else {
-      *out_data_format = DeltaArchiveManifest_File_DataFormat_FULL;
-      ret = full_data;
-    }
-  }
-
-  if (avoid_diff) {
-    out->swap(ret);
-    return true;
-  }
-
-  struct stat old_stbuf;
-  if ((stat((old_dir + "/" + file_name).c_str(), &old_stbuf) < 0) ||
-      (!S_ISREG(old_stbuf.st_mode))) {
-    // stat() failed or old file is not a regular file. Just send back
-    // the full contents
-    out->swap(ret);
-    return true;
-  }
-  // We have an old file.
-  // First see if the data is _exactly_ the same
-  {
-    vector<char> original_data;
-    TEST_AND_RETURN_FALSE(utils::ReadFile(old_dir + "/" + file_name,
-                                          &original_data));
-    if (original_data == full_data) {
-      // Original data unchanged in new file.
-      *no_change = true;
-      return true;
-    }
-  }
-  
-  // Do a binary diff. For now use bsdiff.
-  const string kPatchFile = "/tmp/delta.patchXXXXXX";
-  vector<char> patch_file_path(kPatchFile.begin(), kPatchFile.end());
-  patch_file_path.push_back('\0');
-  
-  int fd = mkstemp(&patch_file_path[0]);
-  if (fd >= 0)
-    close(fd);
-  TEST_AND_RETURN_FALSE(fd != -1);
-
-  vector<string> cmd;
-  cmd.push_back(kBsdiffPath);
-  cmd.push_back(old_dir + "/" + file_name);
-  cmd.push_back(new_dir + "/" + file_name);
-  cmd.push_back(&patch_file_path[0]);
-
-  int rc = 1;
-  vector<char> patch_file;
-  TEST_AND_RETURN_FALSE(Subprocess::SynchronousExec(cmd, &rc));
-  TEST_AND_RETURN_FALSE(rc == 0);
-  TEST_AND_RETURN_FALSE(utils::ReadFile(&patch_file_path[0], &patch_file));
-  unlink(&patch_file_path[0]);
-
-  if (patch_file.size() < ret.size()) {
-    *out_data_format = DeltaArchiveManifest_File_DataFormat_BSDIFF;
-    ret.swap(patch_file);
-  }
-  out->swap(ret);
-  return true;
-}
-
-DeltaArchiveManifest* DeltaDiffGenerator::EncodeMetadataToProtoBuffer(
-    const char* new_path) {
-  Node node;
-  if (!UpdateNodeFromPath(new_path, &node))
-    return NULL;
-  int index = 0;
-  PopulateChildIndexes(&node, &index);
-  DeltaArchiveManifest *ret = new DeltaArchiveManifest;
-  map<ino_t, string> hard_links;  // inode -> first found path for inode
-  NodeToDeltaArchiveManifest(&node, ret, &hard_links, "");
-  return ret;
-}
-
-bool DeltaDiffGenerator::EncodeDataToDeltaFile(
-    DeltaArchiveManifest* archive,
-    const string& old_path,
-    const string& new_path,
-    const string& out_file,
-    const set<string>& nondiff_paths,
-    const string& force_compress_dev_path) {
-  DirectFileWriter out_writer;
-  int r = out_writer.Open(out_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
-  TEST_AND_RETURN_FALSE_ERRNO(r >= 0);
-  ScopedFileWriterCloser closer(&out_writer);
-  TEST_AND_RETURN_FALSE(out_writer.Write(DeltaDiffParser::kFileMagic,
-                                         strlen(DeltaDiffParser::kFileMagic))
-                        == static_cast<ssize_t>(
-                            strlen(DeltaDiffParser::kFileMagic)));
-  // Write 8 null bytes. This will be filled in w/ the offset of
-  // the protobuf.
-  TEST_AND_RETURN_FALSE(out_writer.Write("\0\0\0\0\0\0\0\0", 8) == 8);
-  // 8 more bytes will be filled w/ the protobuf length.
-  TEST_AND_RETURN_FALSE(out_writer.Write("\0\0\0\0\0\0\0\0", 8) == 8);
-  int out_file_length = strlen(DeltaDiffParser::kFileMagic) + 16;
-
-  TEST_AND_RETURN_FALSE(archive->files_size() > 0);
-  DeltaArchiveManifest_File* file = archive->mutable_files(0);
-
-  // nondiff_paths is passed in w/ paths relative to the installed
-  // system (e.g. /etc/fstab), but WriteFileDiffsToDeltaFile requires them
-  // to be the entire path of the new file. We create a new set
-  // here with nondiff_paths expanded.
-  set<string> always_full_target_paths;
-  for (set<string>::const_iterator it = nondiff_paths.begin();
-       it != nondiff_paths.end(); ++it) {
-    always_full_target_paths.insert(new_path + *it);
-  }
-
-  TEST_AND_RETURN_FALSE(WriteFileDiffsToDeltaFile(archive,
-                                                  file,
-                                                  "",
-                                                  old_path,
-                                                  new_path,
-                                                  &out_writer,
-                                                  &out_file_length,
-                                                  always_full_target_paths,
-                                                  force_compress_dev_path));
-
-  // Finally, write the protobuf to the end of the file
-  string encoded_archive;
-  TEST_AND_RETURN_FALSE(archive->SerializeToString(&encoded_archive));
-
-  // Compress the protobuf (which contains filenames)
-  vector<char> compressed_encoded_archive;
-  TEST_AND_RETURN_FALSE(GzipCompressString(encoded_archive,
-                                           &compressed_encoded_archive));
-
-  TEST_AND_RETURN_FALSE(out_writer.Write(compressed_encoded_archive.data(),
-                                         compressed_encoded_archive.size()) ==
-                        static_cast<ssize_t>(
-                            compressed_encoded_archive.size()));
-
-  // write offset of protobut to just after the file magic
-  int64 big_endian_protobuf_offset = htobe64(out_file_length);
-  TEST_AND_RETURN_FALSE(pwrite(out_writer.fd(),
-                               &big_endian_protobuf_offset,
-                               sizeof(big_endian_protobuf_offset),
-                               strlen(DeltaDiffParser::kFileMagic)) ==
-                        sizeof(big_endian_protobuf_offset));
-  // Write the size just after the offset
-  int64 pb_length = htobe64(compressed_encoded_archive.size());
-  TEST_AND_RETURN_FALSE(pwrite(out_writer.fd(),
-                               &pb_length,
-                               sizeof(pb_length),
-                               strlen(DeltaDiffParser::kFileMagic) +
-                               sizeof(big_endian_protobuf_offset)) ==
-                        sizeof(pb_length));
-  return true;
-}
-
-}  // namespace chromeos_update_engine
diff --git a/delta_diff_generator.h b/delta_diff_generator.h
index 5d422c3..6b232da 100644
--- a/delta_diff_generator.h
+++ b/delta_diff_generator.h
@@ -5,86 +5,12 @@
 #ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_DELTA_DIFF_GENERATOR_H__
 #define CHROMEOS_PLATFORM_UPDATE_ENGINE_DELTA_DIFF_GENERATOR_H__
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <set>
-#include <string>
-#include <vector>
 #include "base/basictypes.h"
-#include "update_engine/file_writer.h"
-#include "update_engine/update_metadata.pb.h"
 
 namespace chromeos_update_engine {
 
 class DeltaDiffGenerator {
- public:
-  // Encodes the metadata at new_path recursively into a DeltaArchiveManifest
-  // protobuf object. This will only read the filesystem. Children will
-  // be recorded recursively iff they are on the same device as their
-  // parent.
-  // This will set all fields in the DeltaArchiveManifest except for
-  // DeltaArchiveManifest_File_data_* as those are set only when writing
-  // the actual delta file to disk.
-  // Caller is responsible for freeing the returned value.
-  // Returns NULL on failure.
-  static DeltaArchiveManifest* EncodeMetadataToProtoBuffer(
-      const char* new_path);
-
-  // Takes a DeltaArchiveManifest as given from EncodeMetadataToProtoBuffer(),
-  // fill in the missing fields (DeltaArchiveManifest_File_data_*), and
-  // write the full delta out to the output file.
-  // Any paths in nondiff_paths will be included in full, rather than
-  // as a diff. This is useful for files that change during postinstall, since
-  // future updates can't depend on them having remaining unchanged.
-  // Returns true on success.
-  // If non-empty, the device at force_compress_dev_path will be compressed.
-  static bool EncodeDataToDeltaFile(
-      DeltaArchiveManifest* archive,
-      const std::string& old_path,
-      const std::string& new_path,
-      const std::string& out_file,
-      const std::set<std::string>& nondiff_paths,
-      const std::string& force_compress_dev_path);
-                                    
  private:
-  // These functions encode all the data about a file that's not already
-  // stored in the DeltaArchiveManifest message into the vector 'out'.
-  // They all return true on success.
-
-  // EncodeLink stores the path the symlink points to.
-  static bool EncodeLink(const std::string& path, std::vector<char>* out);
-  // EncodeDev stores the major and minor device numbers.
-  // Specifically it writes a LinuxDevice message.
-  static bool EncodeDev(
-      const struct stat& stbuf, std::vector<char>* out,
-      DeltaArchiveManifest_File_DataFormat* format,
-      bool force_compression);
-  // EncodeFile stores the full data, gzipped data, or a binary diff from
-  // the old data. out_data_format will be set to the method used.
-  static bool EncodeFile(const std::string& old_dir,
-                         const std::string& new_dir,
-                         const std::string& file_name,
-                         const bool avoid_diff,
-                         DeltaArchiveManifest_File_DataFormat* out_data_format,
-                         std::vector<char>* out,
-                         bool* no_change);
-
-  // nondiff_paths is passed in to EncodeDataToDeltaFile() with
-  // paths relative to the installed system (e.g. /etc/fstab), but
-  // WriteFileDiffsToDeltaFile requires always_full_target_paths to be
-  // the entire path of the new file.
-  // If non-empty, the device at force_compress_dev_path will be compressed.
-  static bool WriteFileDiffsToDeltaFile(
-      DeltaArchiveManifest* archive,
-      DeltaArchiveManifest_File* file,
-      const std::string& file_name,
-      const std::string& old_path,
-      const std::string& new_path,
-      FileWriter* out_file_writer,
-      int* out_file_length,
-      std::set<std::string> always_full_target_paths,
-      const std::string& force_compress_dev_path);
-
   // This should never be constructed
   DISALLOW_IMPLICIT_CONSTRUCTORS(DeltaDiffGenerator);
 };
diff --git a/delta_diff_generator_unittest.cc b/delta_diff_generator_unittest.cc
index f86f0e2..a5def92 100644
--- a/delta_diff_generator_unittest.cc
+++ b/delta_diff_generator_unittest.cc
@@ -23,933 +23,6 @@
 
 namespace chromeos_update_engine {
 
-using std::set;
-using std::string;
-using std::vector;
-
-class DeltaDiffGeneratorTest : public ::testing::Test {
-  virtual void TearDown() {
-    EXPECT_EQ(0, system("rm -rf diff-gen-test"));
-  }
-protected:
-  void FakerootEncodeDataToDeltaFileTest(bool test_diff_exclusion);
-};
-
-namespace {
-void DumpProto(const DeltaArchiveManifest* archive) {
-  for (int i = 0; i < archive->files_size(); i++) {
-    printf("Node %d\n", i);
-    const DeltaArchiveManifest_File& file = archive->files(i);
-    for (int j = 0; j < file.children_size(); j++) {
-      const DeltaArchiveManifest_File_Child& child = file.children(j);
-      printf("  %d %s\n", child.index(), child.name().c_str());
-    }
-  }
-}
-
-const char* const kWellCompressingFilename =
-    "this_compresses_well_xxxxxxxxxxxxxxxxx"
-    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
-    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
-    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
-    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
-// The following files are generated at the path 'base':
-// /
-//  cdev (c 2 1)
-//  dir/
-//      bdev (b 3 1)
-//      emptydir/ (owner:group = 501:503)
-//      hello ("hello")
-//      newempty ("")
-//      subdir/
-//             fifo
-//             link -> /target
-//  encoding/
-//           long_new
-//           long_small_change
-//           nochange
-//           onebyte
-//  hi ("hi")
-void GenerateFilesAtPath(const string& base) {
-  const char* base_c = base.c_str();
-  EXPECT_EQ(0, System(StringPrintf("echo hi > '%s/hi'", base_c)));
-  EXPECT_EQ(0, System(StringPrintf("mkdir -p '%s/dir'", base_c)));
-  EXPECT_EQ(0, System(StringPrintf("rm -f '%s/dir/bdev'", base_c)));
-  EXPECT_EQ(0, System(StringPrintf("mknod '%s/dir/bdev' b 3 1", base_c)));
-  EXPECT_EQ(0, System(StringPrintf("rm -f '%s/cdev'", base_c)));
-  EXPECT_EQ(0, System(StringPrintf("mknod '%s/cdev' c 2 1", base_c)));
-  EXPECT_EQ(0, System(StringPrintf("mkdir -p '%s/dir/subdir'", base_c)));
-  EXPECT_EQ(0, System(StringPrintf("mkdir -p '%s/dir/emptydir'", base_c)));
-  EXPECT_EQ(0, System(StringPrintf("chown 501:503 '%s/dir/emptydir'", base_c)));
-  EXPECT_EQ(0, System(StringPrintf("rm -f '%s/dir/subdir/fifo'", base_c)));
-  EXPECT_EQ(0, System(StringPrintf("mkfifo '%s/dir/subdir/fifo'", base_c)));
-  EXPECT_EQ(0, System(StringPrintf("ln -f -s /target '%s/dir/subdir/link'",
-                                   base_c)));
-  EXPECT_EQ(0, System(StringPrintf("rm -f '%s/hard_link'", base_c)));
-  EXPECT_EQ(0, System(StringPrintf("ln '%s/hi' '%s/hard_link'",
-                                   base_c, base_c)));
-  EXPECT_EQ(0, System(StringPrintf(
-      "ln -f -s '%s' '%s/compress_link'", kWellCompressingFilename, base_c)));
-
-  // Things that will encode differently:
-  EXPECT_EQ(0, System(StringPrintf("mkdir -p '%s/encoding'", base_c)));
-  EXPECT_EQ(0, System(StringPrintf("echo nochange > '%s/encoding/nochange'",
-                                   base_c)));
-  EXPECT_EQ(0, System(StringPrintf("echo -n > '%s/encoding/onebyte'", base_c)));
-  EXPECT_EQ(0, System(StringPrintf("echo -n > '%s/encoding/long_new'",
-                                   base_c)));
-  // Random 1 MiB byte length file
-  EXPECT_TRUE(utils::WriteFile((base +
-                                "/encoding/long_small_change").c_str(),
-                               reinterpret_cast<const char*>(kRandomString),
-                               sizeof(kRandomString)));
-}
-// base points to a folder that was passed to GenerateFilesAtPath().
-// This edits some, so that one can make a diff from the original data
-// and the edited data.
-void EditFilesAtPath(const string& base) {
-  CHECK_EQ(0, System(string("echo hello > ") + base + "/dir/hello"));
-  CHECK_EQ(0, System(string("echo -n > ") + base + "/dir/newempty"));
-  CHECK_EQ(0, System(string("echo newhi > ") + base + "/hi"));
-  CHECK_EQ(0, System(string("echo -n h >> ") + base +
-                     "/encoding/onebyte"));
-  CHECK_EQ(0, System(string("echo -n h >> ") + base +
-                     "/encoding/long_small_change"));
-  CHECK_EQ(0, System(string("echo -n This is a pice of text that should "
-                            "compress well since it is just ascii and it "
-                            "has repetition xxxxxxxxxxxxxxxxxxxxx"
-                            "xxxxxxxxxxxxxxxxxxxx > ") + base +
-                     "/encoding/long_new"));
-}
-
-}  // namespace {}
-
-TEST_F(DeltaDiffGeneratorTest, FakerootEncodeMetadataToProtoBufferTest) {
-  char cwd[1000];
-  ASSERT_EQ(cwd, getcwd(cwd, sizeof(cwd))) << "cwd buf possibly too small";
-  ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test"));
-  ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test/old"));
-  ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test/new"));
-  GenerateFilesAtPath(string(cwd) + "/diff-gen-test/old");
-  GenerateFilesAtPath(string(cwd) + "/diff-gen-test/new");
-  EditFilesAtPath(string(cwd) + "/diff-gen-test/new");
-
-  DeltaArchiveManifest* archive =
-      DeltaDiffGenerator::EncodeMetadataToProtoBuffer(
-          (string(cwd) + "/diff-gen-test/new").c_str());
-  EXPECT_TRUE(NULL != archive);
-
-  EXPECT_EQ(18, archive->files_size());
-  //DumpProto(archive);
-  const DeltaArchiveManifest_File& root = archive->files(0);
-  EXPECT_TRUE(S_ISDIR(root.mode()));
-  EXPECT_EQ(0, root.uid());
-  EXPECT_EQ(0, root.gid());
-  ASSERT_EQ(6, root.children_size());
-  EXPECT_EQ("cdev", root.children(0).name());
-  EXPECT_EQ("compress_link", root.children(1).name());
-  EXPECT_EQ("dir", root.children(2).name());
-  EXPECT_EQ("encoding", root.children(3).name());
-  EXPECT_EQ("hard_link", root.children(4).name());
-  EXPECT_EQ("hi", root.children(5).name());
-  EXPECT_FALSE(root.has_hardlink_path());
-  EXPECT_FALSE(root.has_data_format());
-  EXPECT_FALSE(root.has_data_offset());
-  EXPECT_FALSE(root.has_data_length());
-
-  const DeltaArchiveManifest_File& cdev =
-      archive->files(root.children(0).index());
-  EXPECT_EQ(0, cdev.children_size());
-  EXPECT_TRUE(S_ISCHR(cdev.mode()));
-  EXPECT_EQ(0, cdev.uid());
-  EXPECT_EQ(0, cdev.gid());
-  EXPECT_FALSE(cdev.has_hardlink_path());
-  EXPECT_FALSE(cdev.has_data_format());
-  EXPECT_FALSE(cdev.has_data_offset());
-  EXPECT_FALSE(cdev.has_data_length());
-
-  const DeltaArchiveManifest_File& compress_link =
-      archive->files(root.children(1).index());
-  EXPECT_EQ(0, compress_link.children_size());
-  EXPECT_TRUE(S_ISLNK(compress_link.mode()));
-  EXPECT_EQ(0, compress_link.uid());
-  EXPECT_EQ(0, compress_link.gid());
-  EXPECT_FALSE(compress_link.has_hardlink_path());
-  EXPECT_FALSE(compress_link.has_data_format());
-  EXPECT_FALSE(compress_link.has_data_offset());
-  EXPECT_FALSE(compress_link.has_data_length());
-
-  const DeltaArchiveManifest_File& hard_link =
-      archive->files(root.children(4).index());
-  EXPECT_EQ(0, hard_link.children_size());
-  EXPECT_TRUE(S_ISREG(hard_link.mode()));
-  EXPECT_EQ(0, hard_link.uid());
-  EXPECT_EQ(0, hard_link.gid());
-  EXPECT_FALSE(hard_link.has_hardlink_path());
-  EXPECT_FALSE(hard_link.has_data_format());
-  EXPECT_FALSE(hard_link.has_data_offset());
-  EXPECT_FALSE(hard_link.has_data_length());
-
-  const DeltaArchiveManifest_File& hi =
-      archive->files(root.children(5).index());
-  EXPECT_EQ(0, hi.children_size());
-  EXPECT_TRUE(S_ISREG(hi.mode()));
-  EXPECT_EQ(0, hi.uid());
-  EXPECT_EQ(0, hi.gid());
-  EXPECT_TRUE(hi.has_hardlink_path());
-  EXPECT_EQ("/hard_link", hi.hardlink_path());
-  EXPECT_FALSE(hi.has_data_format());
-  EXPECT_FALSE(hi.has_data_offset());
-  EXPECT_FALSE(hi.has_data_length());
-
-  const DeltaArchiveManifest_File& encoding =
-      archive->files(root.children(3).index());
-  EXPECT_TRUE(S_ISDIR(encoding.mode()));
-  EXPECT_EQ(0, encoding.uid());
-  EXPECT_EQ(0, encoding.gid());
-  EXPECT_EQ(4, encoding.children_size());
-  EXPECT_EQ("long_new", encoding.children(0).name());
-  EXPECT_EQ("long_small_change", encoding.children(1).name());
-  EXPECT_EQ("nochange", encoding.children(2).name());
-  EXPECT_EQ("onebyte", encoding.children(3).name());
-  EXPECT_FALSE(encoding.has_hardlink_path());
-  EXPECT_FALSE(encoding.has_data_format());
-  EXPECT_FALSE(encoding.has_data_offset());
-  EXPECT_FALSE(encoding.has_data_length());
-
-  const DeltaArchiveManifest_File& long_new =
-      archive->files(encoding.children(0).index());
-  EXPECT_EQ(0, long_new.children_size());
-  EXPECT_TRUE(S_ISREG(long_new.mode()));
-  EXPECT_EQ(0, long_new.uid());
-  EXPECT_EQ(0, long_new.gid());
-  EXPECT_FALSE(long_new.has_hardlink_path());
-  EXPECT_FALSE(long_new.has_data_format());
-  EXPECT_FALSE(long_new.has_data_offset());
-  EXPECT_FALSE(long_new.has_data_length());
-
-  const DeltaArchiveManifest_File& long_small_change =
-      archive->files(encoding.children(1).index());
-  EXPECT_EQ(0, long_small_change.children_size());
-  EXPECT_TRUE(S_ISREG(long_small_change.mode()));
-  EXPECT_EQ(0, long_small_change.uid());
-  EXPECT_EQ(0, long_small_change.gid());
-  EXPECT_FALSE(long_small_change.has_hardlink_path());
-  EXPECT_FALSE(long_small_change.has_data_format());
-  EXPECT_FALSE(long_small_change.has_data_offset());
-  EXPECT_FALSE(long_small_change.has_data_length());
-
-  const DeltaArchiveManifest_File& nochange =
-      archive->files(encoding.children(2).index());
-  EXPECT_EQ(0, nochange.children_size());
-  EXPECT_TRUE(S_ISREG(nochange.mode()));
-  EXPECT_EQ(0, nochange.uid());
-  EXPECT_EQ(0, nochange.gid());
-  EXPECT_FALSE(nochange.has_hardlink_path());
-  EXPECT_FALSE(nochange.has_data_format());
-  EXPECT_FALSE(nochange.has_data_offset());
-  EXPECT_FALSE(nochange.has_data_length());
-
-  const DeltaArchiveManifest_File& onebyte =
-      archive->files(encoding.children(3).index());
-  EXPECT_EQ(0, onebyte.children_size());
-  EXPECT_TRUE(S_ISREG(onebyte.mode()));
-  EXPECT_EQ(0, onebyte.uid());
-  EXPECT_EQ(0, onebyte.gid());
-  EXPECT_FALSE(onebyte.has_hardlink_path());
-  EXPECT_FALSE(onebyte.has_data_format());
-  EXPECT_FALSE(onebyte.has_data_offset());
-  EXPECT_FALSE(onebyte.has_data_length());
-
-  const DeltaArchiveManifest_File& dir =
-      archive->files(root.children(2).index());
-  EXPECT_TRUE(S_ISDIR(dir.mode()));
-  EXPECT_EQ(0, dir.uid());
-  EXPECT_EQ(0, dir.gid());
-  ASSERT_EQ(5, dir.children_size());
-  EXPECT_EQ("bdev", dir.children(0).name());
-  EXPECT_EQ("emptydir", dir.children(1).name());
-  EXPECT_EQ("hello", dir.children(2).name());
-  EXPECT_EQ("newempty", dir.children(3).name());
-  EXPECT_EQ("subdir", dir.children(4).name());
-  EXPECT_FALSE(dir.has_hardlink_path());
-  EXPECT_FALSE(dir.has_data_format());
-  EXPECT_FALSE(dir.has_data_offset());
-  EXPECT_FALSE(dir.has_data_length());
-
-  const DeltaArchiveManifest_File& bdev =
-      archive->files(dir.children(0).index());
-  EXPECT_EQ(0, bdev.children_size());
-  EXPECT_TRUE(S_ISBLK(bdev.mode()));
-  EXPECT_EQ(0, bdev.uid());
-  EXPECT_EQ(0, bdev.gid());
-  EXPECT_FALSE(bdev.has_hardlink_path());
-  EXPECT_FALSE(bdev.has_data_format());
-  EXPECT_FALSE(bdev.has_data_offset());
-  EXPECT_FALSE(bdev.has_data_length());
-
-  const DeltaArchiveManifest_File& emptydir =
-      archive->files(dir.children(1).index());
-  EXPECT_EQ(0, emptydir.children_size());
-  EXPECT_TRUE(S_ISDIR(emptydir.mode()));
-  EXPECT_EQ(501, emptydir.uid());
-  EXPECT_EQ(503, emptydir.gid());
-  EXPECT_FALSE(emptydir.has_hardlink_path());
-  EXPECT_FALSE(emptydir.has_data_format());
-  EXPECT_FALSE(emptydir.has_data_offset());
-  EXPECT_FALSE(emptydir.has_data_length());
-
-  const DeltaArchiveManifest_File& hello =
-      archive->files(dir.children(2).index());
-  EXPECT_EQ(0, hello.children_size());
-  EXPECT_TRUE(S_ISREG(hello.mode()));
-  EXPECT_EQ(0, hello.uid());
-  EXPECT_EQ(0, hello.gid());
-  EXPECT_FALSE(hello.has_hardlink_path());
-  EXPECT_FALSE(hello.has_data_format());
-  EXPECT_FALSE(hello.has_data_offset());
-  EXPECT_FALSE(hello.has_data_length());
-
-  const DeltaArchiveManifest_File& newempty =
-      archive->files(dir.children(3).index());
-  EXPECT_EQ(0, newempty.children_size());
-  EXPECT_TRUE(S_ISREG(newempty.mode()));
-  EXPECT_EQ(0, newempty.uid());
-  EXPECT_EQ(0, newempty.gid());
-  EXPECT_FALSE(newempty.has_hardlink_path());
-  EXPECT_FALSE(newempty.has_data_format());
-  EXPECT_FALSE(newempty.has_data_offset());
-  EXPECT_FALSE(newempty.has_data_length());
-
-  const DeltaArchiveManifest_File& subdir =
-      archive->files(dir.children(4).index());
-  EXPECT_EQ(2, subdir.children_size());
-  EXPECT_EQ("fifo", subdir.children(0).name());
-  EXPECT_EQ("link", subdir.children(1).name());
-  EXPECT_TRUE(S_ISDIR(subdir.mode()));
-  EXPECT_EQ(0, subdir.uid());
-  EXPECT_EQ(0, subdir.gid());
-  EXPECT_FALSE(subdir.has_hardlink_path());
-  EXPECT_FALSE(subdir.has_data_format());
-  EXPECT_FALSE(subdir.has_data_offset());
-  EXPECT_FALSE(subdir.has_data_length());
-
-  const DeltaArchiveManifest_File& fifo =
-      archive->files(subdir.children(0).index());
-  EXPECT_EQ(0, fifo.children_size());
-  EXPECT_TRUE(S_ISFIFO(fifo.mode()));
-  EXPECT_EQ(0, fifo.uid());
-  EXPECT_EQ(0, fifo.gid());
-  EXPECT_FALSE(fifo.has_hardlink_path());
-  EXPECT_FALSE(fifo.has_data_format());
-  EXPECT_FALSE(fifo.has_data_offset());
-  EXPECT_FALSE(fifo.has_data_length());
-
-  const DeltaArchiveManifest_File& link =
-      archive->files(subdir.children(1).index());
-  EXPECT_EQ(0, link.children_size());
-  EXPECT_TRUE(S_ISLNK(link.mode()));
-  EXPECT_EQ(0, link.uid());
-  EXPECT_EQ(0, link.gid());
-  EXPECT_FALSE(link.has_hardlink_path());
-  EXPECT_FALSE(link.has_data_format());
-  EXPECT_FALSE(link.has_data_offset());
-  EXPECT_FALSE(link.has_data_length());
-}
-
-TEST_F(DeltaDiffGeneratorTest, FakerootEncodeDataToDeltaFileTest) {
-  FakerootEncodeDataToDeltaFileTest(false);
-}
-TEST_F(DeltaDiffGeneratorTest, FakerootDiffExclusionsTest) {
-  FakerootEncodeDataToDeltaFileTest(true);
-}
-
-void DeltaDiffGeneratorTest::FakerootEncodeDataToDeltaFileTest(
-    bool test_diff_exclusion) {
-  char cwd[1000];
-  ASSERT_EQ(cwd, getcwd(cwd, sizeof(cwd))) << "cwd buf possibly too small";
-  ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test"));
-  ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test/old"));
-  ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test/new"));
-  GenerateFilesAtPath(string(cwd) + "/diff-gen-test/old");
-  GenerateFilesAtPath(string(cwd) + "/diff-gen-test/new");
-  EditFilesAtPath(string(cwd) + "/diff-gen-test/new");
-
-  set<string> diff_exclusions;
-  if (test_diff_exclusion) {
-    diff_exclusions.insert("/encoding/long_small_change");
-  } else {
-    diff_exclusions.insert("/hi");
-  }
-
-  DeltaArchiveManifest* archive =
-      DeltaDiffGenerator::EncodeMetadataToProtoBuffer(
-          (string(cwd) + "/diff-gen-test/new").c_str());
-  EXPECT_TRUE(NULL != archive);
-
-  EXPECT_TRUE(DeltaDiffGenerator::EncodeDataToDeltaFile(
-      archive,
-      string(cwd) + "/diff-gen-test/old",
-      string(cwd) + "/diff-gen-test/new",
-      string(cwd) + "/diff-gen-test/out.dat",
-      diff_exclusions, ""));
-
-  EXPECT_EQ(18, archive->files_size());
-
-  const DeltaArchiveManifest_File& root = archive->files(0);
-  EXPECT_TRUE(S_ISDIR(root.mode()));
-  EXPECT_EQ(0, root.uid());
-  EXPECT_EQ(0, root.gid());
-  ASSERT_EQ(6, root.children_size());
-  EXPECT_EQ("cdev", root.children(0).name());
-  EXPECT_EQ("compress_link", root.children(1).name());
-  EXPECT_EQ("dir", root.children(2).name());
-  EXPECT_EQ("encoding", root.children(3).name());
-  EXPECT_EQ("hard_link", root.children(4).name());
-  EXPECT_EQ("hi", root.children(5).name());
-  EXPECT_FALSE(root.has_hardlink_path());
-  EXPECT_FALSE(root.has_data_format());
-  EXPECT_FALSE(root.has_data_offset());
-  EXPECT_FALSE(root.has_data_length());
-
-  const DeltaArchiveManifest_File& cdev =
-      archive->files(root.children(0).index());
-  EXPECT_EQ(0, cdev.children_size());
-  EXPECT_TRUE(S_ISCHR(cdev.mode()));
-  EXPECT_EQ(0, cdev.uid());
-  EXPECT_EQ(0, cdev.gid());
-  ASSERT_TRUE(cdev.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, cdev.data_format());
-  EXPECT_TRUE(cdev.has_data_offset());
-  ASSERT_TRUE(cdev.has_data_length());
-  EXPECT_GT(cdev.data_length(), 0);
-  EXPECT_FALSE(cdev.has_hardlink_path());
-
-  const DeltaArchiveManifest_File& compress_link =
-      archive->files(root.children(1).index());
-  EXPECT_EQ(0, compress_link.children_size());
-  EXPECT_TRUE(S_ISLNK(compress_link.mode()));
-  EXPECT_EQ(0, compress_link.uid());
-  EXPECT_EQ(0, compress_link.gid());
-  ASSERT_TRUE(compress_link.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL_GZ,
-            compress_link.data_format());
-  EXPECT_TRUE(compress_link.has_data_offset());
-  ASSERT_TRUE(compress_link.has_data_length());
-  EXPECT_GT(compress_link.data_length(), 0);
-  EXPECT_FALSE(compress_link.has_hardlink_path());
-
-  const DeltaArchiveManifest_File& hard_link =
-      archive->files(root.children(4).index());
-  EXPECT_EQ(0, hard_link.children_size());
-  EXPECT_TRUE(S_ISREG(hard_link.mode()));
-  EXPECT_EQ(0, hard_link.uid());
-  EXPECT_EQ(0, hard_link.gid());
-  ASSERT_TRUE(hard_link.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, hard_link.data_format());
-  EXPECT_TRUE(hard_link.has_data_offset());
-  ASSERT_TRUE(hard_link.has_data_length());
-  EXPECT_GT(hard_link.data_length(), 0);
-  EXPECT_FALSE(hard_link.has_hardlink_path());
-
-  const DeltaArchiveManifest_File& hi =
-      archive->files(root.children(5).index());
-  EXPECT_EQ(0, hi.children_size());
-  EXPECT_TRUE(S_ISREG(hi.mode()));
-  EXPECT_EQ(0, hi.uid());
-  EXPECT_EQ(0, hi.gid());
-  EXPECT_FALSE(hi.has_data_format());
-  EXPECT_FALSE(hi.has_data_offset());
-  EXPECT_FALSE(hi.has_data_length());
-  EXPECT_TRUE(hi.has_hardlink_path());
-  EXPECT_EQ("/hard_link", hi.hardlink_path());
-
-  const DeltaArchiveManifest_File& encoding =
-      archive->files(root.children(3).index());
-  EXPECT_TRUE(S_ISDIR(encoding.mode()));
-  EXPECT_EQ(0, encoding.uid());
-  EXPECT_EQ(0, encoding.gid());
-  EXPECT_EQ(4, encoding.children_size());
-  EXPECT_EQ("long_new", encoding.children(0).name());
-  EXPECT_EQ("long_small_change", encoding.children(1).name());
-  EXPECT_EQ("nochange", encoding.children(2).name());
-  EXPECT_EQ("onebyte", encoding.children(3).name());
-  EXPECT_FALSE(encoding.has_data_format());
-  EXPECT_FALSE(encoding.has_data_offset());
-  EXPECT_FALSE(encoding.has_data_length());
-  EXPECT_FALSE(encoding.has_hardlink_path());
-
-  const DeltaArchiveManifest_File& long_new =
-      archive->files(encoding.children(0).index());
-  EXPECT_EQ(0, long_new.children_size());
-  EXPECT_TRUE(S_ISREG(long_new.mode()));
-  EXPECT_EQ(0, long_new.uid());
-  EXPECT_EQ(0, long_new.gid());
-  EXPECT_TRUE(long_new.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL_GZ,
-            long_new.data_format());
-  EXPECT_TRUE(long_new.has_data_offset());
-  EXPECT_TRUE(long_new.has_data_length());
-  EXPECT_FALSE(long_new.has_hardlink_path());
-
-  const DeltaArchiveManifest_File& long_small_change =
-      archive->files(encoding.children(1).index());
-  EXPECT_EQ(0, long_small_change.children_size());
-  EXPECT_TRUE(S_ISREG(long_small_change.mode()));
-  EXPECT_EQ(0, long_small_change.uid());
-  EXPECT_EQ(0, long_small_change.gid());
-  EXPECT_TRUE(long_small_change.has_data_format());
-  DeltaArchiveManifest_File_DataFormat expected_format =
-      DeltaArchiveManifest_File_DataFormat_BSDIFF;
-  if (test_diff_exclusion)
-    expected_format = DeltaArchiveManifest_File_DataFormat_FULL;
-  EXPECT_EQ(expected_format, long_small_change.data_format());
-  EXPECT_TRUE(long_small_change.has_data_offset());
-  EXPECT_TRUE(long_small_change.has_data_length());
-  EXPECT_FALSE(long_small_change.has_hardlink_path());
-
-  const DeltaArchiveManifest_File& nochange =
-      archive->files(encoding.children(2).index());
-  EXPECT_EQ(0, nochange.children_size());
-  EXPECT_TRUE(S_ISREG(nochange.mode()));
-  EXPECT_EQ(0, nochange.uid());
-  EXPECT_EQ(0, nochange.gid());
-  EXPECT_FALSE(nochange.has_data_format());
-  EXPECT_FALSE(nochange.has_data_offset());
-  EXPECT_FALSE(nochange.has_data_length());
-  EXPECT_FALSE(nochange.has_hardlink_path());
-
-  const DeltaArchiveManifest_File& onebyte =
-      archive->files(encoding.children(3).index());
-  EXPECT_EQ(0, onebyte.children_size());
-  EXPECT_TRUE(S_ISREG(onebyte.mode()));
-  EXPECT_EQ(0, onebyte.uid());
-  EXPECT_EQ(0, onebyte.gid());
-  EXPECT_TRUE(onebyte.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, onebyte.data_format());
-  EXPECT_TRUE(onebyte.has_data_offset());
-  EXPECT_TRUE(onebyte.has_data_length());
-  EXPECT_EQ(1, onebyte.data_length());
-  EXPECT_FALSE(onebyte.has_hardlink_path());
-
-  const DeltaArchiveManifest_File& dir =
-      archive->files(root.children(2).index());
-  EXPECT_TRUE(S_ISDIR(dir.mode()));
-  EXPECT_EQ(0, dir.uid());
-  EXPECT_EQ(0, dir.gid());
-  ASSERT_EQ(5, dir.children_size());
-  EXPECT_EQ("bdev", dir.children(0).name());
-  EXPECT_EQ("emptydir", dir.children(1).name());
-  EXPECT_EQ("hello", dir.children(2).name());
-  EXPECT_EQ("newempty", dir.children(3).name());
-  EXPECT_EQ("subdir", dir.children(4).name());
-  EXPECT_FALSE(dir.has_data_format());
-  EXPECT_FALSE(dir.has_data_offset());
-  EXPECT_FALSE(dir.has_data_length());
-  EXPECT_FALSE(dir.has_hardlink_path());
-
-  const DeltaArchiveManifest_File& bdev =
-      archive->files(dir.children(0).index());
-  EXPECT_EQ(0, bdev.children_size());
-  EXPECT_TRUE(S_ISBLK(bdev.mode()));
-  EXPECT_EQ(0, bdev.uid());
-  EXPECT_EQ(0, bdev.gid());
-  ASSERT_TRUE(bdev.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, bdev.data_format());
-  EXPECT_TRUE(bdev.has_data_offset());
-  ASSERT_TRUE(bdev.has_data_length());
-  EXPECT_GT(bdev.data_length(), 0);
-  EXPECT_FALSE(bdev.has_hardlink_path());
-
-  const DeltaArchiveManifest_File& emptydir =
-      archive->files(dir.children(1).index());
-  EXPECT_EQ(0, emptydir.children_size());
-  EXPECT_TRUE(S_ISDIR(emptydir.mode()));
-  EXPECT_EQ(501, emptydir.uid());
-  EXPECT_EQ(503, emptydir.gid());
-  EXPECT_FALSE(emptydir.has_data_format());
-  EXPECT_FALSE(emptydir.has_data_offset());
-  EXPECT_FALSE(emptydir.has_data_length());
-  EXPECT_FALSE(emptydir.has_hardlink_path());
-
-  const DeltaArchiveManifest_File& hello =
-      archive->files(dir.children(2).index());
-  EXPECT_EQ(0, hello.children_size());
-  EXPECT_TRUE(S_ISREG(hello.mode()));
-  EXPECT_EQ(0, hello.uid());
-  EXPECT_EQ(0, hello.gid());
-  ASSERT_TRUE(hello.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, hello.data_format());
-  EXPECT_TRUE(hello.has_data_offset());
-  ASSERT_TRUE(hello.has_data_length());
-  EXPECT_GT(hello.data_length(), 0);
-  EXPECT_FALSE(hello.has_hardlink_path());
-
-  const DeltaArchiveManifest_File& newempty =
-      archive->files(dir.children(3).index());
-  EXPECT_EQ(0, newempty.children_size());
-  EXPECT_TRUE(S_ISREG(newempty.mode()));
-  EXPECT_EQ(0, newempty.uid());
-  EXPECT_EQ(0, newempty.gid());
-  EXPECT_TRUE(newempty.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, newempty.data_format());
-  EXPECT_TRUE(newempty.has_data_offset());
-  EXPECT_TRUE(newempty.has_data_length());
-  EXPECT_FALSE(newempty.has_hardlink_path());
-
-  const DeltaArchiveManifest_File& subdir =
-      archive->files(dir.children(4).index());
-  EXPECT_EQ(2, subdir.children_size());
-  EXPECT_EQ("fifo", subdir.children(0).name());
-  EXPECT_EQ("link", subdir.children(1).name());
-  EXPECT_TRUE(S_ISDIR(subdir.mode()));
-  EXPECT_EQ(0, subdir.uid());
-  EXPECT_EQ(0, subdir.gid());
-  EXPECT_FALSE(subdir.has_data_format());
-  EXPECT_FALSE(subdir.has_data_offset());
-  EXPECT_FALSE(subdir.has_data_length());
-  EXPECT_FALSE(subdir.has_hardlink_path());
-
-  const DeltaArchiveManifest_File& fifo =
-      archive->files(subdir.children(0).index());
-  EXPECT_EQ(0, fifo.children_size());
-  EXPECT_TRUE(S_ISFIFO(fifo.mode()));
-  EXPECT_EQ(0, fifo.uid());
-  EXPECT_EQ(0, fifo.gid());
-  EXPECT_FALSE(fifo.has_data_format());
-  EXPECT_FALSE(fifo.has_data_offset());
-  EXPECT_FALSE(fifo.has_data_length());
-  EXPECT_FALSE(fifo.has_hardlink_path());
-
-  const DeltaArchiveManifest_File& link =
-      archive->files(subdir.children(1).index());
-  EXPECT_EQ(0, link.children_size());
-  EXPECT_TRUE(S_ISLNK(link.mode()));
-  EXPECT_EQ(0, link.uid());
-  EXPECT_EQ(0, link.gid());
-  ASSERT_TRUE(link.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, link.data_format());
-  EXPECT_TRUE(link.has_data_offset());
-  ASSERT_TRUE(link.has_data_length());
-  EXPECT_GT(link.data_length(), 0);
-  EXPECT_FALSE(link.has_hardlink_path());
-}
-
-class DeltaDiffParserTest : public ::testing::Test {
-  virtual void TearDown() {
-    EXPECT_EQ(0, system("rm -rf diff-gen-test"));
-  }
-};
-
-namespace {
-// Reads part of a file into memory
-vector<char> ReadFilePart(const string& path, off_t start, off_t size) {
-  vector<char> ret;
-  int fd = open(path.c_str(), O_RDONLY, 0);
-  if (fd < 0)
-    return ret;
-  ret.resize(size);
-  EXPECT_EQ(size, pread(fd, &ret[0], size, start));
-  close(fd);
-  return ret;
-}
-
-string ReadFilePartToString(const string& path, off_t start, off_t size) {
-  vector<char> bytes = ReadFilePart(path, start, size);
-  string ret;
-  ret.append(&bytes[0], bytes.size());
-  return ret;
-}
-
-string StringFromVectorChar(const vector<char>& in) {
-  return string(&in[0], in.size());
-}
-
-string GzipDecompressToString(const vector<char>& in) {
-  vector<char> out;
-  EXPECT_TRUE(GzipDecompress(in, &out));
-  return StringFromVectorChar(out);
-}
-
-}
-
-TEST_F(DeltaDiffParserTest, FakerootDecodeDataFromDeltaFileTest) {
-  char cwd[1000];
-  ASSERT_EQ(cwd, getcwd(cwd, sizeof(cwd))) << "cwd buf possibly too small";
-  ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test"));
-  ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test/old"));
-  ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test/new"));
-  GenerateFilesAtPath(string(cwd) + "/diff-gen-test/old");
-  GenerateFilesAtPath(string(cwd) + "/diff-gen-test/new");
-  EditFilesAtPath(string(cwd) + "/diff-gen-test/new");
-
-  DeltaArchiveManifest* archive =
-      DeltaDiffGenerator::EncodeMetadataToProtoBuffer(
-          (string(cwd) + "/diff-gen-test/new").c_str());
-  EXPECT_TRUE(NULL != archive);
-
-  EXPECT_TRUE(DeltaDiffGenerator::EncodeDataToDeltaFile(
-      archive,
-      string(cwd) + "/diff-gen-test/old",
-      string(cwd) + "/diff-gen-test/new",
-      string(cwd) + "/diff-gen-test/out.dat",
-      set<string>(), ""));
-  // parse the file
-
-  DeltaDiffParser parser(string(cwd) + "/diff-gen-test/out.dat");
-  ASSERT_TRUE(parser.valid());
-  DeltaDiffParser::Iterator it = parser.Begin();
-  string expected_paths[] = {
-    "",
-    "/cdev",
-    "/compress_link",
-    "/dir",
-    "/dir/bdev",
-    "/dir/emptydir",
-    "/dir/hello",
-    "/dir/newempty",
-    "/dir/subdir",
-    "/dir/subdir/fifo",
-    "/dir/subdir/link",
-    "/encoding",
-    "/encoding/long_new",
-    "/encoding/long_small_change",
-    "/encoding/nochange",
-    "/encoding/onebyte",
-    "/hard_link",
-    "/hi"
-  };
-  for (unsigned int i = 0;
-       i < (sizeof(expected_paths)/sizeof(expected_paths[0])); i++) {
-    ASSERT_TRUE(it != parser.End());
-    ASSERT_TRUE(parser.ContainsPath(expected_paths[i]));
-    EXPECT_EQ(expected_paths[i], it.path());
-    EXPECT_EQ(expected_paths[i].substr(expected_paths[i].find_last_of('/') + 1),
-              it.GetName());
-    DeltaArchiveManifest_File f1 = parser.GetFileAtPath(expected_paths[i]);
-    DeltaArchiveManifest_File f2 = it.GetFile();
-    EXPECT_EQ(f1.mode(), f2.mode()) << it.path();
-    EXPECT_EQ(f1.uid(), f2.uid());
-    EXPECT_EQ(f1.gid(), f2.gid());
-    EXPECT_EQ(f1.has_data_format(), f2.has_data_format());
-    if (f1.has_data_format()) {
-      EXPECT_EQ(f1.data_format(), f2.data_format());
-      EXPECT_TRUE(f1.has_data_offset());
-      EXPECT_TRUE(f2.has_data_offset());
-      EXPECT_EQ(f1.data_offset(), f2.data_offset());
-    } else {
-      EXPECT_FALSE(f2.has_data_format());
-      EXPECT_FALSE(f1.has_data_offset());
-      EXPECT_FALSE(f2.has_data_offset());
-    }
-    EXPECT_EQ(f1.children_size(), f2.children_size());
-    for (int j = 0; j < f1.children_size(); j++) {
-      EXPECT_EQ(f1.children(j).name(), f2.children(j).name());
-      EXPECT_EQ(f1.children(j).index(), f2.children(j).index());
-    }
-    it.Increment();
-  }
-  EXPECT_TRUE(it == parser.End());
-  EXPECT_FALSE(parser.ContainsPath("/cdew"));
-  EXPECT_FALSE(parser.ContainsPath("/hi/hi"));
-  EXPECT_FALSE(parser.ContainsPath("/dir/newempty/hi"));
-  EXPECT_TRUE(parser.ContainsPath("/dir/"));
-
-  // Check the data
-  // root
-  DeltaArchiveManifest_File file = parser.GetFileAtPath("");
-  EXPECT_TRUE(S_ISDIR(file.mode()));
-  EXPECT_FALSE(file.has_data_format());
-
-  // cdev
-  file = parser.GetFileAtPath("/cdev");
-  EXPECT_TRUE(S_ISCHR(file.mode()));
-  EXPECT_TRUE(file.has_data_format());
-  vector<char> data = ReadFilePart(string(cwd) + "/diff-gen-test/out.dat",
-                                   file.data_offset(), file.data_length());
-  LinuxDevice linux_device;
-  linux_device.ParseFromArray(&data[0], data.size());
-  EXPECT_EQ(linux_device.major(), 2);
-  EXPECT_EQ(linux_device.minor(), 1);
-
-  // compress_link
-  file = parser.GetFileAtPath("/compress_link");
-  EXPECT_TRUE(S_ISLNK(file.mode()));
-  EXPECT_TRUE(file.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL_GZ, file.data_format());
-  EXPECT_EQ(kWellCompressingFilename,
-            GzipDecompressToString(ReadFilePart(string(cwd) +
-                                                "/diff-gen-test/out.dat",
-                                                file.data_offset(),
-                                                file.data_length())));
-  // dir
-  file = parser.GetFileAtPath("/dir");
-  EXPECT_TRUE(S_ISDIR(file.mode()));
-  EXPECT_FALSE(file.has_data_format());
-
-  // bdev
-  file = parser.GetFileAtPath("/dir/bdev");
-  EXPECT_TRUE(S_ISBLK(file.mode()));
-  EXPECT_TRUE(file.has_data_format());
-  data = ReadFilePart(string(cwd) + "/diff-gen-test/out.dat",
-                      file.data_offset(), file.data_length());
-  linux_device.ParseFromArray(&data[0], data.size());
-  EXPECT_EQ(linux_device.major(), 3);
-  EXPECT_EQ(linux_device.minor(), 1);
-
-  // emptydir
-  file = parser.GetFileAtPath("/dir/emptydir");
-  EXPECT_TRUE(S_ISDIR(file.mode()));
-  EXPECT_FALSE(file.has_data_format());
-
-  // hello
-  file = parser.GetFileAtPath("/dir/hello");
-  EXPECT_TRUE(S_ISREG(file.mode()));
-  EXPECT_TRUE(file.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, file.data_format());
-  EXPECT_EQ("hello\n", ReadFilePartToString(string(cwd) +
-                                            "/diff-gen-test/out.dat",
-                                            file.data_offset(),
-                                            file.data_length()));
-
-  // newempty
-  file = parser.GetFileAtPath("/dir/newempty");
-  EXPECT_TRUE(S_ISREG(file.mode()));
-  EXPECT_TRUE(file.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, file.data_format());
-
-  // subdir
-  file = parser.GetFileAtPath("/dir/subdir");
-  EXPECT_TRUE(S_ISDIR(file.mode()));
-  EXPECT_FALSE(file.has_data_format());
-
-  // fifo
-  file = parser.GetFileAtPath("/dir/subdir/fifo");
-  EXPECT_TRUE(S_ISFIFO(file.mode()));
-  EXPECT_FALSE(file.has_data_format());
-
-  // link
-  file = parser.GetFileAtPath("/dir/subdir/link");
-  EXPECT_TRUE(S_ISLNK(file.mode()));
-  EXPECT_TRUE(file.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, file.data_format());
-  EXPECT_EQ("/target", ReadFilePartToString(string(cwd) +
-                                            "/diff-gen-test/out.dat",
-                                            file.data_offset(),
-                                            file.data_length()));
-
-  // encoding
-  file = parser.GetFileAtPath("/encoding");
-  EXPECT_TRUE(S_ISDIR(file.mode()));
-  EXPECT_FALSE(file.has_data_format());
-
-  // long_new
-  file = parser.GetFileAtPath("/encoding/long_new");
-  EXPECT_TRUE(S_ISREG(file.mode()));
-  EXPECT_TRUE(file.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL_GZ, file.data_format());
-  EXPECT_EQ("This is a pice of text that should "
-            "compress well since it is just ascii and it "
-            "has repetition xxxxxxxxxxxxxxxxxxxxx"
-            "xxxxxxxxxxxxxxxxxxxx",
-            GzipDecompressToString(ReadFilePart(string(cwd) +
-                                                "/diff-gen-test/out.dat",
-                                                file.data_offset(),
-                                                file.data_length())));
-
-  // long_small_change
-  file = parser.GetFileAtPath("/encoding/long_small_change");
-  EXPECT_TRUE(S_ISREG(file.mode()));
-  EXPECT_TRUE(file.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_BSDIFF, file.data_format());
-  data = ReadFilePart(string(cwd) + "/diff-gen-test/out.dat",
-                      file.data_offset(), file.data_length());
-  WriteFileVector(string(cwd) + "/diff-gen-test/patch", data);
-  int rc = 1;
-  vector<string> cmd;
-  cmd.push_back("/usr/bin/bspatch");
-  cmd.push_back(string(cwd) + "/diff-gen-test/old/encoding/long_small_change");
-  cmd.push_back(string(cwd) + "/diff-gen-test/patch_result");
-  cmd.push_back(string(cwd) + "/diff-gen-test/patch");
-  Subprocess::SynchronousExec(cmd, &rc);
-  ASSERT_EQ(0, rc);
-  vector<char> patch_result;
-  EXPECT_TRUE(utils::ReadFile(string(cwd) + "/diff-gen-test/patch_result",
-                              &patch_result));
-  vector<char> expected_data(sizeof(kRandomString) + 1);
-  memcpy(&expected_data[0], kRandomString, sizeof(kRandomString));
-  expected_data[expected_data.size() - 1] = 'h';
-  ExpectVectorsEq(expected_data, patch_result);
-
-  // nochange
-  file = parser.GetFileAtPath("/encoding/nochange");
-  EXPECT_TRUE(S_ISREG(file.mode()));
-  EXPECT_FALSE(file.has_data_format());
-  EXPECT_FALSE(file.has_data_offset());
-  EXPECT_FALSE(file.has_data_length());
-
-  // onebyte
-  file = parser.GetFileAtPath("/encoding/onebyte");
-  EXPECT_TRUE(S_ISREG(file.mode()));
-  EXPECT_TRUE(file.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, file.data_format());
-  EXPECT_EQ("h", ReadFilePartToString(string(cwd) +
-                                      "/diff-gen-test/out.dat",
-                                      file.data_offset(),
-                                      file.data_length()));
-
-  // hard_link
-  file = parser.GetFileAtPath("/hard_link");
-  EXPECT_TRUE(S_ISREG(file.mode()));
-  EXPECT_TRUE(file.has_data_format());
-  EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, file.data_format());
-  EXPECT_EQ("newhi\n", ReadFilePartToString(string(cwd) +
-                                            "/diff-gen-test/out.dat",
-                                            file.data_offset(),
-                                            file.data_length()));
-
-  // hi
-  file = parser.GetFileAtPath("/hi");
-  EXPECT_TRUE(S_ISREG(file.mode()));
-  EXPECT_FALSE(file.has_data_format());
-  EXPECT_TRUE(file.has_hardlink_path());
-  EXPECT_EQ("/hard_link", file.hardlink_path());
-}
-
-TEST_F(DeltaDiffParserTest, FakerootInvalidTest) {
-  ASSERT_EQ(0, mkdir("diff-gen-test", 0777));
-  {
-    DeltaDiffParser parser("/no/such/file");
-    EXPECT_FALSE(parser.valid());
-  }
-  {
-    vector<char> data(3);
-    memcpy(&data[0], "CrA", 3);
-    WriteFileVector("diff-gen-test/baddelta", data);
-    DeltaDiffParser parser("diff-gen-test/baddelta");
-    EXPECT_FALSE(parser.valid());
-  }
-  {
-    vector<char> data(5);
-    memcpy(&data[0], "CrAPx", 5);
-    WriteFileVector("diff-gen-test/baddelta", data);
-    DeltaDiffParser parser("diff-gen-test/baddelta");
-    EXPECT_FALSE(parser.valid());
-  }
-  {
-    vector<char> data(5);
-    memcpy(&data[0], "CrAU\0", 5);
-    WriteFileVector("diff-gen-test/baddelta", data);
-    DeltaDiffParser parser("diff-gen-test/baddelta");
-    EXPECT_FALSE(parser.valid());
-  }
-  {
-    vector<char> data(14);
-    memcpy(&data[0], "CrAU\0\0\0\0\0\0\0\x0cxx", 12);
-    WriteFileVector("diff-gen-test/baddelta", data);
-    DeltaDiffParser parser("diff-gen-test/baddelta");
-    EXPECT_FALSE(parser.valid());
-  }
-}
+class DeltaDiffGeneratorTest : public ::testing::Test {};
 
 }  // namespace chromeos_update_engine
diff --git a/delta_diff_parser.cc b/delta_diff_parser.cc
index 47c763f..fe7c974 100644
--- a/delta_diff_parser.cc
+++ b/delta_diff_parser.cc
@@ -3,270 +3,7 @@
 // found in the LICENSE file.
 
 #include "update_engine/delta_diff_parser.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <endian.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <algorithm>
-#include <string>
-#include <vector>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
-#include "base/scoped_ptr.h"
-#include "update_engine/decompressing_file_writer.h"
-#include "update_engine/gzip.h"
-#include "update_engine/utils.h"
-
-using std::min;
-using std::string;
-using std::vector;
 
 namespace chromeos_update_engine {
 
-namespace {
-const int kCopyFileBufferSize = 4096;
-}
-
-const char* const DeltaDiffParser::kFileMagic("CrAU");
-
-// The iterator returns a directory before returning its children.
-// Steps taken in Increment():
-//   - See if the current item has children. If so, the child becomes
-//     the new current item and we return.
-//   - If current item has no children, we loop. Each loop iteration
-//     considers an item (first the current item, then its parent,
-//     then grand parent, and so on). Each loop iteration, we see if there
-//     are any siblings we haven't iterated on yet. If so, we're done.
-//     If not, keep looping to parents.
-void DeltaDiffParserIterator::Increment() {
-  // See if we have any children.
-  const DeltaArchiveManifest_File& file = GetFile();
-  if (file.children_size() > 0) {
-    path_indices_.push_back(file.children(0).index());
-    path_ += "/";
-    path_ += file.children(0).name();
-    child_indices_.push_back(0);
-    return;
-  }
-  // Look in my parent for the next child, then try grandparent, etc.
-
-  path_indices_.pop_back();
-  path_.resize(path_.rfind('/'));
-
-  while (!child_indices_.empty()) {
-    // Try to bump the last entry
-    CHECK_EQ(path_indices_.size(), child_indices_.size());
-    child_indices_.back()++;
-    const DeltaArchiveManifest_File& parent =
-        archive_->files(path_indices_.back());
-    if (parent.children_size() > child_indices_.back()) {
-      // we found a new child!
-      path_indices_.push_back(parent.children(child_indices_.back()).index());
-      path_ += "/";
-      path_ += parent.children(child_indices_.back()).name();
-      return;
-    }
-    path_indices_.pop_back();
-    child_indices_.pop_back();
-    if (!path_.empty())
-      path_.resize(path_.rfind('/'));
-  }
-}
-
-const string DeltaDiffParserIterator::GetName() const {
-  if (path_.empty())
-    return "";
-  CHECK_NE(path_.rfind('/'), string::npos);
-  return string(path_, path_.rfind('/') + 1);
-}
-
-const DeltaArchiveManifest_File& DeltaDiffParserIterator::GetFile() const {
-  CHECK(!path_indices_.empty());
-  return archive_->files(path_indices_.back());
-}
-
-
-DeltaDiffParser::DeltaDiffParser(const string& delta_file)
-    : fd_(-1),
-      valid_(false) {
-  fd_ = open(delta_file.c_str(), O_RDONLY, 0);
-  if (fd_ < 0) {
-    LOG(ERROR) << "Unable to open delta file: " << delta_file;
-    return;
-  }
-  ScopedFdCloser fd_closer(&fd_);
-  scoped_array<char> magic(new char[strlen(kFileMagic)]);
-  if (strlen(kFileMagic) != read(fd_, magic.get(), strlen(kFileMagic))) {
-    LOG(ERROR) << "delta file too short";
-    return;
-  }
-  if (strncmp(magic.get(), kFileMagic, strlen(kFileMagic))) {
-    LOG(ERROR) << "Incorrect magic at beginning of delta file";
-    return;
-  }
-
-  int64 proto_offset = 0;
-  COMPILE_ASSERT(sizeof(proto_offset) == sizeof(off_t), off_t_wrong_size);
-  if (sizeof(proto_offset) != read(fd_, &proto_offset, sizeof(proto_offset))) {
-    LOG(ERROR) << "delta file too short";
-    return;
-  }
-  proto_offset = be64toh(proto_offset);  // switch from big-endian to host
-
-  int64 proto_length = 0;
-  if (sizeof(proto_length) != read(fd_, &proto_length, sizeof(proto_length))) {
-    LOG(ERROR) << "delta file too short";
-    return;
-  }
-  proto_length = be64toh(proto_length);  // switch from big-endian to host
-
-  vector<char> proto(proto_length);
-  size_t bytes_read = 0;
-  while (bytes_read < proto_length) {
-    ssize_t r = pread(fd_, &proto[bytes_read], proto_length - bytes_read,
-                      proto_offset + bytes_read);
-    TEST_AND_RETURN(r >= 0);
-    bytes_read += r;
-  }
-  {
-    vector<char> decompressed_proto;
-    TEST_AND_RETURN(GzipDecompress(proto, &decompressed_proto));
-    proto.swap(decompressed_proto);
-  }
-
-  valid_ = archive_.ParseFromArray(&proto[0], proto.size());
-  if (valid_) {
-    fd_closer.set_should_close(false);
-  } else {
-    LOG(ERROR) << "load from file failed";
-  }
-}
-
-DeltaDiffParser::~DeltaDiffParser() {
-  if (fd_ >= 0) {
-    close(fd_);
-    fd_ = -1;
-  }
-}
-
-bool DeltaDiffParser::ContainsPath(const string& path) const {
-  return GetIndexForPath(path) >= 0;
-}
-
-const DeltaArchiveManifest_File& DeltaDiffParser::GetFileAtPath(
-    const string& path) const {
-  int idx = GetIndexForPath(path);
-  CHECK_GE(idx, 0) << path;
-  return archive_.files(idx);
-}
-
-// Returns -1 if not found.
-int DeltaDiffParser::GetIndexOfFileChild(
-    const DeltaArchiveManifest_File& file, const string& child_name) const {
-  if (file.children_size() == 0)
-    return -1;
-  int begin = 0;
-  int end = file.children_size();
-  while (begin < end) {
-    int middle = (begin + end) / 2;
-    const string& middle_name = file.children(middle).name();
-    int cmp_result = strcmp(middle_name.c_str(), child_name.c_str());
-    if (cmp_result == 0)
-      return file.children(middle).index();
-    if (cmp_result < 0)
-      begin = middle + 1;
-    else
-      end = middle;
-  }
-  return -1;
-}
-
-// Converts a path to an index in archive_. It does this by separating
-// the path components and going from root to leaf, finding the
-// File message for each component. Index values for children are
-// stored in File messages.
-int DeltaDiffParser::GetIndexForPath(const string& path) const {
-  string cleaned_path = utils::NormalizePath(path, true);
-  // strip leading slash
-  if (cleaned_path[0] == '/')
-    cleaned_path = cleaned_path.c_str() + 1;
-  if (cleaned_path.empty())
-    return 0;
-  string::size_type begin = 0;
-  string::size_type end = cleaned_path.find_first_of('/', begin + 1);
-  const DeltaArchiveManifest_File* file = &archive_.files(0);
-  int file_idx = -1;
-  for (;;) {
-    string component = cleaned_path.substr(begin, end - begin);
-    if (component.empty())
-      break;
-    // search for component in 'file'
-    file_idx = GetIndexOfFileChild(*file, component);
-    if (file_idx < 0)
-      return file_idx;
-    file = &archive_.files(file_idx);
-    if (end == string::npos)
-      break;
-    begin = end + 1;
-    end = cleaned_path.find_first_of('/', begin + 1);
-  }
-  return file_idx;
-}
-
-bool DeltaDiffParser::ReadDataVector(off_t offset, off_t length,
-                                     std::vector<char>* out) const {
-  out->resize(static_cast<vector<char>::size_type>(length));
-  int r = pread(fd_, &((*out)[0]), length, offset);
-  TEST_AND_RETURN_FALSE_ERRNO(r >= 0);
-  return true;
-}
-
-bool DeltaDiffParser::CopyDataToFile(off_t offset, off_t length,
-                                     bool should_decompress,
-                                     const std::string& path) const {
-  DirectFileWriter direct_writer;
-  GzipDecompressingFileWriter decompressing_writer(&direct_writer);
-  FileWriter* writer = NULL;  // will point to one of the two writers above
-
-  writer = (should_decompress ?
-            static_cast<FileWriter*>(&decompressing_writer) :
-            static_cast<FileWriter*>(&direct_writer));
-  ScopedFileWriterCloser closer(writer);
-
-  int r = writer->Open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0644);
-  TEST_AND_RETURN_FALSE(r == 0);
-
-  off_t bytes_transferred = 0;
-
-  while (bytes_transferred < length) {
-    char buf[kCopyFileBufferSize];
-    size_t bytes_to_read = min(length - bytes_transferred,
-                               static_cast<off_t>(sizeof(buf)));
-    ssize_t bytes_read = pread(fd_, buf, bytes_to_read,
-                               offset + bytes_transferred);
-    if (bytes_read == 0)
-      break;  // EOF
-    TEST_AND_RETURN_FALSE_ERRNO(bytes_read > 0);
-    int bytes_written = writer->Write(buf, bytes_read);
-    TEST_AND_RETURN_FALSE(bytes_written == bytes_read);
-    bytes_transferred += bytes_written;
-  }
-  TEST_AND_RETURN_FALSE(bytes_transferred == length);
-  LOG_IF(ERROR, bytes_transferred > length) << "Wrote too many bytes(?)";
-  return true;
-}
-
-
-const DeltaDiffParser::Iterator DeltaDiffParser::Begin() {
-  DeltaDiffParserIterator ret(&archive_);
-  ret.path_indices_.push_back(0);
-  return ret;
-}
-
-const DeltaDiffParser::Iterator DeltaDiffParser::End() {
-  return DeltaDiffParserIterator(&archive_);
-}
-
 }  // namespace chromeos_update_engine
diff --git a/delta_diff_parser.h b/delta_diff_parser.h
index 5c6d664..e6d0b1a 100644
--- a/delta_diff_parser.h
+++ b/delta_diff_parser.h
@@ -5,128 +5,10 @@
 #ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_DELTA_DIFF_PARSER_H__
 #define CHROMEOS_PLATFORM_UPDATE_ENGINE_DELTA_DIFF_PARSER_H__
 
-#include <string>
-#include <vector>
-#include "chromeos/obsolete_logging.h"
 #include "base/basictypes.h"
-#include "update_engine/update_metadata.pb.h"
-
-// The DeltaDiffParser class is used to parse a delta file on disk. It will
-// copy the metadata into memory, but not the file data. This class can
-// also be used to copy file data out to disk.
-
-// The DeltaDiffParserIterator class is used to iterate through the
-// metadata of a delta file. It will return directories before their
-// children.
 
 namespace chromeos_update_engine {
 
-class DeltaDiffParser;
-
-class DeltaDiffParserIterator {
-  friend class DeltaDiffParser;
- public:
-  void Increment();
-
-  // Returns the full path for the current file, e.g. "/bin/bash".
-  // Returns empty string for root.
-  const std::string& path() const {
-    return path_;
-  }
-
-  // Returns the basename for the current file. If path() returns
-  // "/bin/bash", then GetName() returns "bash".
-  // Returns empty string for root
-  const std::string GetName() const;
-
-  const DeltaArchiveManifest_File& GetFile() const;
-  bool operator==(const DeltaDiffParserIterator& that) const {
-    return path_indices_ == that.path_indices_ &&
-        child_indices_ == that.child_indices_ &&
-        path_ == that.path_ &&
-        archive_ == that.archive_;
-  }
-  bool operator!=(const DeltaDiffParserIterator& that) const {
-    return !(*this == that);
-  }
- private:
-  // Container of all the File messages. Each File message has an index
-  // in archive_. The root directory is always stored at index 0.
-  const DeltaArchiveManifest* archive_;
-  
-  // These variables are used to implement the common recursive depth-first
-  // search algorithm (which we can't use here, since we need to walk the
-  // tree incrementally).
-  
-  // Indices into 'archive_' of the current path components.  For example, if
-  // the current path is "/bin/bash", 'path_stack_' will contain the archive
-  // indices for "/", "/bin", and "/bin/bash", in that order.  This is
-  // analogous to the call stack of the recursive algorithm.
-  std::vector<int> path_indices_;
-
-  // For each component in 'path_stack_', the currently-selected child in its
-  // child vector.  In the previous example, if "/" has "abc" and "bin"
-  // subdirectories and "/bin" contains only "bash", this will contain
-  // [0, 1, 0], since we are using the 0th child at the root directory level
-  // (there's only one child there), the first of the root dir's children
-  // ("bin"), and the 0th child of /bin ("bash").  This is analogous to the
-  // state of each function (in terms of which child it's currently
-  // handling) in the call stack of the recursive algorithm.
-  std::vector<int> child_indices_;
-
-  std::string path_;
-  // Instantiated by friend class DeltaDiffParser
-  explicit DeltaDiffParserIterator(const DeltaArchiveManifest* archive)
-      : archive_(archive) {}
-  DeltaDiffParserIterator() {
-    CHECK(false);  // Should never be called.
-  }
-};
-
-class DeltaDiffParser {
- public:
-  DeltaDiffParser(const std::string& delta_file);
-  ~DeltaDiffParser();
-  bool valid() const { return valid_; }
-  bool ContainsPath(const std::string& path) const;
-  const DeltaArchiveManifest_File& GetFileAtPath(const std::string& path) const;
-
-  // Reads length bytes at offset of the delta file into the out string
-  // or vector. Be careful not to call this with large length values,
-  // since that much memory will have to be allocated to store the output.
-  // Returns true on success.
-  bool ReadDataVector(off_t offset, off_t length, std::vector<char>* out) const;
-
-  // Copies length bytes of data from offset into a new file at path specified.
-  // If should_decompress is true, will gzip decompress while writing to the
-  // file. Returns true on success.
-  bool CopyDataToFile(off_t offset, off_t length, bool should_decompress,
-                      const std::string& path) const;
-
-  typedef DeltaDiffParserIterator Iterator;
-  const Iterator Begin();
-  const Iterator End();
-
-  // The identifier we expect at the beginning of a delta file.
-  static const char* const kFileMagic;
-
- private:
-  // (Binary) Searches the children of 'file' for one named child_name.
-  // If found, returns the index into the archive. If not found, returns -1.
-  int GetIndexOfFileChild(const DeltaArchiveManifest_File& file,
-                            const std::string& child_name) const;
-
-  // Returns -1 if not found, 0 for root
-  int GetIndexForPath(const std::string& path) const;
-
-  // We keep a filedescriptor open to the delta file.
-  int fd_;
-
-  DeltaArchiveManifest archive_;
-  bool valid_;
-  DISALLOW_COPY_AND_ASSIGN(DeltaDiffParser);
-};
-
 };  // namespace chromeos_update_engine
 
 #endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_DELTA_DIFF_PARSER_H__
diff --git a/download_action.cc b/download_action.cc
index 833f806..6da6719 100644
--- a/download_action.cc
+++ b/download_action.cc
@@ -31,7 +31,7 @@
 
   should_decompress_ = install_plan.is_full_update;
   url_ = install_plan.download_url;
-  output_path_ = install_plan.download_path;
+  output_path_ = install_plan.install_path;
   hash_ = install_plan.download_hash;
   install_plan.Dump();
 
@@ -39,7 +39,6 @@
     decompressing_file_writer_.reset(
         new GzipDecompressingFileWriter(direct_file_writer_.get()));
     writer_ = decompressing_file_writer_.get();
-    output_path_ = install_plan.install_path;
   } else {
     writer_ = direct_file_writer_.get();
   }
diff --git a/download_action_unittest.cc b/download_action_unittest.cc
index 57e8d7e..014d3b7 100644
--- a/download_action_unittest.cc
+++ b/download_action_unittest.cc
@@ -80,7 +80,7 @@
   // takes ownership of passed in HttpFetcher
   InstallPlan install_plan(compress, "",
                            OmahaHashCalculator::OmahaHashOfData(use_data),
-                           compress ? "" : path, compress ? path : "");
+                           path);
   ObjectFeederAction<InstallPlan> feeder_action;
   feeder_action.set_obj(install_plan);
   DownloadAction download_action(new MockHttpFetcher(&use_data[0],
@@ -157,7 +157,7 @@
   {
     // takes ownership of passed in HttpFetcher
     ObjectFeederAction<InstallPlan> feeder_action;
-    InstallPlan install_plan(false, "", "", path, "");
+    InstallPlan install_plan(false, "", "", path);
     feeder_action.set_obj(install_plan);
     DownloadAction download_action(new MockHttpFetcher(&data[0], data.size()));
     TerminateEarlyTestProcessorDelegate delegate;
@@ -231,12 +231,10 @@
 TEST(DownloadActionTest, PassObjectOutTest) {
   GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
 
-  const string path("/tmp/DownloadActionTest");
-
   // takes ownership of passed in HttpFetcher
   InstallPlan install_plan(false, "",
-                           OmahaHashCalculator::OmahaHashOfString("x"), path,
-                           "");
+                           OmahaHashCalculator::OmahaHashOfString("x"),
+                           "/dev/null");
   ObjectFeederAction<InstallPlan> feeder_action;
   feeder_action.set_obj(install_plan);
   DownloadAction download_action(new MockHttpFetcher("x", 1));
@@ -267,7 +265,7 @@
   const string path("/fake/path/that/cant/be/created/because/of/missing/dirs");
 
   // takes ownership of passed in HttpFetcher
-  InstallPlan install_plan(false, "", "", path, "");
+  InstallPlan install_plan(false, "", "", path);
   ObjectFeederAction<InstallPlan> feeder_action;
   feeder_action.set_obj(install_plan);
   DownloadAction download_action(new MockHttpFetcher("x", 1));
diff --git a/filesystem_copier_action_unittest.cc b/filesystem_copier_action_unittest.cc
index 6d6f0ad..1e024f1 100644
--- a/filesystem_copier_action_unittest.cc
+++ b/filesystem_copier_action_unittest.cc
@@ -222,7 +222,7 @@
   processor.set_delegate(&delegate);
 
   ObjectFeederAction<InstallPlan> feeder_action;
-  InstallPlan install_plan(true, "", "", "", "");
+  InstallPlan install_plan(true, "", "", "");
   feeder_action.set_obj(install_plan);
   FilesystemCopierAction copier_action;
   ObjectCollectorAction<InstallPlan> collector_action;
@@ -246,7 +246,7 @@
   processor.set_delegate(&delegate);
 
   ObjectFeederAction<InstallPlan> feeder_action;
-  InstallPlan install_plan(false, "", "", "", "/some/missing/file/path");
+  InstallPlan install_plan(false, "", "", "/some/missing/file/path");
   feeder_action.set_obj(install_plan);
   FilesystemCopierAction copier_action;
   ObjectCollectorAction<InstallPlan> collector_action;
diff --git a/generate_delta_main.cc b/generate_delta_main.cc
index b64533b..551c6ef 100644
--- a/generate_delta_main.cc
+++ b/generate_delta_main.cc
@@ -25,11 +25,6 @@
 namespace chromeos_update_engine {
 
 namespace {
-// These paths should never be delta diffed. They should always be transmitted
-// in full in the update.
-const char* kNonDiffPaths[] = {
-  "/boot/extlinux.conf"
-};
 
 void usage(const char* argv0) {
   printf("usage: %s old_dir new_dir out_file\n", argv0);
@@ -58,19 +53,8 @@
     usage(argv[0]);
   }
   
-  set<string> non_diff_paths;
-  for (size_t i = 0; i < arraysize(kNonDiffPaths); i++)
-    non_diff_paths.insert(kNonDiffPaths[i]);
-  
-  DeltaArchiveManifest* manifest =
-      DeltaDiffGenerator::EncodeMetadataToProtoBuffer(new_dir);
-  CHECK(manifest);
-  CHECK(DeltaDiffGenerator::EncodeDataToDeltaFile(manifest,
-                                                  old_dir,
-                                                  new_dir,
-                                                  argv[3],
-                                                  non_diff_paths,
-                                                  ""));
+  // TODO(adlr): generate delta file
+
   return 0;
 }
 
diff --git a/install_action.cc b/install_action.cc
deleted file mode 100644
index d144b7b..0000000
--- a/install_action.cc
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "update_engine/install_action.h"
-#include <errno.h>
-#include <string>
-#include <vector>
-#include <gflags/gflags.h>
-#include "update_engine/filesystem_iterator.h"
-#include "update_engine/gzip.h"
-#include "update_engine/subprocess.h"
-#include "update_engine/utils.h"
-
-DEFINE_string(mount_install_path, "",
-              "If set, the path to use when mounting the "
-              "destination device during install");
-
-using std::string;
-using std::vector;
-
-namespace chromeos_update_engine {
-
-namespace {
-const string kBspatchPath = "/usr/bin/bspatch";
-}
-
-void InstallAction::PerformAction() {
-  ScopedActionCompleter completer(processor_, this);
-  // For now, do nothing other than pass what we need to to the output pipe
-  CHECK(HasInputObject());
-  const InstallPlan install_plan = GetInputObject();
-  if (HasOutputPipe())
-    SetOutputObject(install_plan.install_path);
-  if (install_plan.is_full_update) {
-    // No need to perform an install
-    completer.set_success(true);
-    return;
-  }
-  // We have a delta update.
-
-  // Open delta file
-  DeltaDiffParser parser(install_plan.download_path);
-  if (!parser.valid()) {
-    LOG(ERROR) << "Unable to open delta file";
-    return;
-  }
-
-  // Mount install fs
-  string mountpoint = FLAGS_mount_install_path;
-  if (mountpoint.empty()) {
-    // Set up dest_path_
-    char *mountpoint_temp = strdup("/tmp/install_mnt.XXXXXX");
-    CHECK(mountpoint_temp);
-    CHECK_EQ(mountpoint_temp, mkdtemp(mountpoint_temp));
-    CHECK_NE('\0', mountpoint_temp[0]);
-    mountpoint = mountpoint_temp;
-    free(mountpoint_temp);
-  }
-
-  TEST_AND_RETURN(utils::MountFilesystem(install_plan.install_path,
-                                         mountpoint));
-
-  // Automatically unmount the fs when this goes out of scope:
-  ScopedFilesystemUnmounter filesystem_unmounter(mountpoint);
-
-  {
-    // Iterate through existing fs, deleting unneeded files
-    // Delete files that don't exist in the update, or exist but are
-    // hard links.
-    FilesystemIterator iter(mountpoint,
-                            utils::SetWithValue<string>("/lost+found"));
-    for (; !iter.IsEnd(); iter.Increment()) {
-      if (!parser.ContainsPath(iter.GetPartialPath()) ||
-          parser.GetFileAtPath(iter.GetPartialPath()).has_hardlink_path()) {
-        VLOG(1) << "install removing local path: " << iter.GetFullPath();
-        TEST_AND_RETURN(utils::RecursiveUnlinkDir(iter.GetFullPath()));
-      }
-    }
-    TEST_AND_RETURN(!iter.IsErr());
-  }
-
-  // iterate through delta metadata, writing files
-  DeltaDiffParserIterator iter = parser.Begin();
-  for (; iter != parser.End(); iter.Increment()) {
-    const DeltaArchiveManifest_File& file = iter.GetFile();
-    VLOG(1) << "Installing file: " << iter.path();
-    TEST_AND_RETURN(InstallFile(mountpoint, file, iter.path(), parser));
-  }
-
-  completer.set_success(true);
-}
-
-bool InstallAction::InstallFile(const std::string& mountpoint,
-                                const DeltaArchiveManifest_File& file,
-                                const std::string& path,
-                                const DeltaDiffParser& parser) const {
-  // See what's already there
-  struct stat existing_stbuf;
-  int result = lstat((mountpoint + path).c_str(), &existing_stbuf);
-  TEST_AND_RETURN_FALSE_ERRNO((result == 0) || (errno == ENOENT));
-  bool exists = (result == 0);
-  // Create the proper file
-  if (file.has_hardlink_path()) {
-    TEST_AND_RETURN_FALSE(file.has_hardlink_path());
-    TEST_AND_RETURN_FALSE_ERRNO(link(
-        (mountpoint + file.hardlink_path()).c_str(),
-        (mountpoint + path).c_str()) == 0);
-  } else if (S_ISDIR(file.mode())) {
-    if (!exists) {
-      TEST_AND_RETURN_FALSE_ERRNO(
-          (mkdir((mountpoint + path).c_str(), file.mode())) == 0);
-    }
-  } else if (S_ISLNK(file.mode())) {
-    InstallFileSymlink(mountpoint, file, path, parser, exists);
-  } else if (S_ISCHR(file.mode()) ||
-             S_ISBLK(file.mode()) ||
-             S_ISFIFO(file.mode()) ||
-             S_ISSOCK(file.mode())) {
-    InstallFileSpecialFile(mountpoint, file, path, parser, exists);
-  } else if (S_ISREG(file.mode())) {
-    InstallFileRegularFile(mountpoint, file, path, parser, exists);
-  } else {
-    // unknown mode type
-    TEST_AND_RETURN_FALSE(false);
-  }
-
-  // chmod/chown new file
-  TEST_AND_RETURN_FALSE(file.has_uid() && file.has_gid());
-  TEST_AND_RETURN_FALSE_ERRNO(lchown((mountpoint + path).c_str(),
-                                     file.uid(), file.gid()) == 0);
-  if (!S_ISLNK(file.mode()))
-    TEST_AND_RETURN_FALSE_ERRNO(chmod((mountpoint + path).c_str(), file.mode())
-                                == 0);
-  return true;
-}
-
-bool InstallAction::InstallFileRegularFile(
-    const std::string& mountpoint,
-    const DeltaArchiveManifest_File& file,
-    const std::string& path,
-    const DeltaDiffParser& parser,
-    const bool exists) const {
-  if (!file.has_data_format())
-    return true;
-  TEST_AND_RETURN_FALSE(file.has_data_offset() && file.has_data_length());
-  if (file.data_format() == DeltaArchiveManifest_File_DataFormat_BSDIFF) {
-    // Expand with bspatch
-    string patch_path = utils::TempFilename(mountpoint + path + ".XXXXXX");
-    TEST_AND_RETURN_FALSE(file.has_data_length());
-    TEST_AND_RETURN_FALSE(parser.CopyDataToFile(
-        file.data_offset(),
-        static_cast<off_t>(file.data_length()), false,
-        patch_path));
-    string output_path = utils::TempFilename(mountpoint + path + ".XXXXXX");
-    int rc = 1;
-    vector<string> cmd;
-    cmd.push_back(kBspatchPath);
-    cmd.push_back(mountpoint + path);
-    cmd.push_back(output_path);
-    cmd.push_back(patch_path);
-    TEST_AND_RETURN_FALSE(Subprocess::SynchronousExec(cmd, &rc));
-    TEST_AND_RETURN_FALSE(rc == 0);
-    TEST_AND_RETURN_FALSE_ERRNO(rename(output_path.c_str(),
-                                       (mountpoint + path).c_str()) == 0);
-    TEST_AND_RETURN_FALSE_ERRNO(unlink(patch_path.c_str()) == 0);
-  } else {
-    // Expand full data, decompressing if necessary
-    TEST_AND_RETURN_FALSE((file.data_format() ==
-                           DeltaArchiveManifest_File_DataFormat_FULL) ||
-                          (file.data_format() ==
-                           DeltaArchiveManifest_File_DataFormat_FULL_GZ));
-    if (exists)
-      TEST_AND_RETURN_FALSE_ERRNO(unlink((mountpoint + path).c_str()) == 0);
-    TEST_AND_RETURN_FALSE(file.has_data_length());
-    const bool gzipped = file.data_format() ==
-        DeltaArchiveManifest_File_DataFormat_FULL_GZ;
-    bool success =
-        parser.CopyDataToFile(file.data_offset(), file.data_length(),
-                              gzipped,
-                              mountpoint + path);
-    TEST_AND_RETURN_FALSE(success);
-  }
-  return true;
-}
-
-// char/block devices, fifos, and sockets:
-bool InstallAction::InstallFileSpecialFile(
-    const std::string& mountpoint,
-    const DeltaArchiveManifest_File& file,
-    const std::string& path,
-    const DeltaDiffParser& parser,
-    const bool exists) const {
-  if (exists)
-    TEST_AND_RETURN_FALSE(unlink((mountpoint + path).c_str()) == 0);
-  dev_t dev = 0;
-  if (S_ISCHR(file.mode()) || S_ISBLK(file.mode())) {
-    vector<char> dev_proto;
-    TEST_AND_RETURN_FALSE(file.has_data_format());
-    TEST_AND_RETURN_FALSE(parser.ReadDataVector(file.data_offset(),
-                                                file.data_length(),
-                                                &dev_proto));
-    if (file.data_format() == DeltaArchiveManifest_File_DataFormat_FULL_GZ) {
-      TEST_AND_RETURN_FALSE(file.has_data_length());
-      {
-        vector<char> decompressed_dev_proto;
-        TEST_AND_RETURN_FALSE(GzipDecompress(dev_proto,
-                                             &decompressed_dev_proto));
-        dev_proto = decompressed_dev_proto;
-      }
-    } else {
-      TEST_AND_RETURN_FALSE(file.data_format() ==
-                            DeltaArchiveManifest_File_DataFormat_FULL);
-    }
-    LinuxDevice linux_device;
-    utils::HexDumpVector(dev_proto);
-    TEST_AND_RETURN_FALSE(linux_device.ParseFromArray(&dev_proto[0],
-                                                      dev_proto.size()));
-    dev = makedev(linux_device.major(), linux_device.minor());
-  }
-  TEST_AND_RETURN_FALSE_ERRNO(mknod((mountpoint + path).c_str(),
-                                    file.mode(), dev) == 0);
-  return true;
-}
-// symlinks:
-bool InstallAction::InstallFileSymlink(const std::string& mountpoint,
-                                       const DeltaArchiveManifest_File& file,
-                                       const std::string& path,
-                                       const DeltaDiffParser& parser,
-                                       const bool exists) const {
-  // If there's no data, we leave the symlink as is
-  if (!file.has_data_format())
-    return true;  // No changes needed
-  TEST_AND_RETURN_FALSE((file.data_format() ==
-                         DeltaArchiveManifest_File_DataFormat_FULL) ||
-                        (file.data_format() ==
-                         DeltaArchiveManifest_File_DataFormat_FULL_GZ));
-  TEST_AND_RETURN_FALSE(file.has_data_offset() && file.has_data_length());
-  // We have data, and thus use it to create a symlink.
-  // First delete any existing symlink:
-  if (exists)
-    TEST_AND_RETURN_FALSE_ERRNO(unlink((mountpoint + path).c_str()) == 0);
-  vector<char> symlink_data;
-  TEST_AND_RETURN_FALSE(parser.ReadDataVector(file.data_offset(),
-                                              file.data_length(),
-                                              &symlink_data));
-  if (file.data_format() == DeltaArchiveManifest_File_DataFormat_FULL_GZ) {
-    vector<char> decompressed_symlink_data;
-    TEST_AND_RETURN_FALSE(GzipDecompress(symlink_data,
-                                         &decompressed_symlink_data));
-    symlink_data = decompressed_symlink_data;
-  }
-  symlink_data.push_back('\0');
-  TEST_AND_RETURN_FALSE_ERRNO(symlink(&symlink_data[0],
-                                      (mountpoint + path).c_str()) == 0);
-  return true;
-}
-
-
-}  //   namespace chromeos_update_engine
diff --git a/install_action.h b/install_action.h
deleted file mode 100644
index 8bed632..0000000
--- a/install_action.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_INSTALL_ACTION_H__
-#define CHROMEOS_PLATFORM_UPDATE_ENGINE_INSTALL_ACTION_H__
-
-#include "base/scoped_ptr.h"
-#include "update_engine/action.h"
-#include "update_engine/delta_diff_parser.h"
-#include "update_engine/install_plan.h"
-#include "update_engine/update_metadata.pb.h"
-
-// The Install Action is responsible for ensuring the update that's been
-// downloaded has been installed. This may be a no-op in the case of a full
-// update, since those will be downloaded directly into the destination
-// partition. However, for a delta update some work is required.
-
-// An InstallPlan struct must be passed to this action before PerformAction()
-// is called so that this action knows if it's a delta update, and if so,
-// what the paths are.
-
-// TODO(adlr): At the moment, InstallAction is synchronous. It should be
-// updated to be asynchronous at some point.
-
-namespace chromeos_update_engine {
-
-class InstallAction;
-class NoneType;
-
-template<>
-class ActionTraits<InstallAction> {
- public:
-  // Takes the InstallPlan for input
-  typedef InstallPlan InputObjectType;
-  // On success, puts the output device path on output
-  typedef std::string OutputObjectType;
-};
-
-class InstallAction : public Action<InstallAction> {
- public:
-  InstallAction() {}
-  typedef ActionTraits<InstallAction>::InputObjectType InputObjectType;
-  typedef ActionTraits<InstallAction>::OutputObjectType OutputObjectType;
-  void PerformAction();
-
-  // This action is synchronous for now.
-  void TerminateProcessing() { CHECK(false); }
-
-  // Debugging/logging
-  static std::string StaticType() { return "InstallAction"; }
-  std::string Type() const { return StaticType(); }
-
- private:
-  // Installs 'file' into mountpoint. 'path' is the path that 'file'
-  // should have when we reboot and mountpoint is root.
-  bool InstallFile(const std::string& mountpoint,
-                   const DeltaArchiveManifest_File& file,
-                   const std::string& path,
-                   const DeltaDiffParser& parser) const;
-  // These are helpers for InstallFile. They focus on specific file types:
-  // Regular data files:
-  bool InstallFileRegularFile(const std::string& mountpoint,
-                              const DeltaArchiveManifest_File& file,
-                              const std::string& path,
-                              const DeltaDiffParser& parser,
-                              const bool exists) const;
-  // char/block devices, fifos, and sockets:
-  bool InstallFileSpecialFile(const std::string& mountpoint,
-                              const DeltaArchiveManifest_File& file,
-                              const std::string& path,
-                              const DeltaDiffParser& parser,
-                              const bool exists) const;
-  // symlinks:
-  bool InstallFileSymlink(const std::string& mountpoint,
-                          const DeltaArchiveManifest_File& file,
-                          const std::string& path,
-                          const DeltaDiffParser& parser,
-                          const bool exists) const;
-
-  DISALLOW_COPY_AND_ASSIGN(InstallAction);
-};
-
-}  // namespace chromeos_update_engine
-
-#endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_INSTALL_ACTION_H__
diff --git a/install_action_unittest.cc b/install_action_unittest.cc
deleted file mode 100644
index 3fd42d4..0000000
--- a/install_action_unittest.cc
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <utime.h>
-#include <set>
-#include <string>
-#include <vector>
-#include "base/string_util.h"
-#include <gtest/gtest.h>
-#include "update_engine/delta_diff_generator.h"
-#include "update_engine/filesystem_iterator.h"
-#include "update_engine/install_action.h"
-#include "update_engine/test_utils.h"
-#include "update_engine/utils.h"
-
-using chromeos_update_engine::DeltaDiffGenerator;
-using chromeos_update_engine::kRandomString;
-using chromeos_update_engine::System;
-using chromeos_update_engine::utils::WriteFile;
-using std::set;
-using std::string;
-using std::vector;
-
-namespace {
-void GenerateFilesAtPath(const string& base) {
-  EXPECT_EQ(0, System(StringPrintf("echo hi > %s/hi", base.c_str())));
-  EXPECT_EQ(0, System(StringPrintf("ln %s/hi %s/hard_link", base.c_str(),
-                                   base.c_str())));
-  EXPECT_EQ(0, System(StringPrintf("mkdir -p %s/dir", base.c_str())));
-  EXPECT_EQ(0, System(StringPrintf("echo hello > %s/dir/hello", base.c_str())));
-  EXPECT_EQ(0, System(StringPrintf("echo -n > %s/dir/newempty", base.c_str())));
-  EXPECT_EQ(0, System(StringPrintf("rm -f %s/dir/bdev", base.c_str())));
-  EXPECT_EQ(0, System(StringPrintf("mknod %s/dir/bdev b 3 1", base.c_str())));
-  EXPECT_EQ(0, System(StringPrintf("rm -f %s/cdev", base.c_str())));
-  EXPECT_EQ(0, System(StringPrintf("mknod %s/cdev c 2 1", base.c_str())));
-  EXPECT_EQ(0, System(StringPrintf("mkdir -p %s/dir/subdir", base.c_str())));
-  EXPECT_EQ(0, System(StringPrintf("mkdir -p %s/dir/emptydir", base.c_str())));
-  EXPECT_EQ(0, System(StringPrintf("echo -n foo > %s/dir/bigfile",
-                                   base.c_str())));
-  EXPECT_EQ(0, System(StringPrintf("chown 501:503 %s/dir/emptydir",
-                                   base.c_str())));
-  EXPECT_EQ(0, System(StringPrintf("rm -f %s/dir/subdir/fifo", base.c_str())));
-  EXPECT_EQ(0, System(StringPrintf("mkfifo %s/dir/subdir/fifo", base.c_str())));
-  EXPECT_EQ(0, System(StringPrintf("ln -f -s /target %s/dir/subdir/link",
-                                   base.c_str())));
-  EXPECT_TRUE(WriteFile((base + "/big_file").c_str(),
-                        reinterpret_cast<const char*>(kRandomString),
-                        sizeof(kRandomString)));
-}
-
-// Returns true if files at paths a, b are equal and there are no errors.
-bool FilesEqual(const string& a, const string& b) {
-  struct stat a_stbuf;
-  struct stat b_stbuf;
-
-  int r = lstat(a.c_str(), &a_stbuf);
-  TEST_AND_RETURN_FALSE_ERRNO(r == 0);
-  r = lstat(b.c_str(), &b_stbuf);
-  TEST_AND_RETURN_FALSE_ERRNO(r == 0);
-
-  TEST_AND_RETURN_FALSE(a_stbuf.st_mode == b_stbuf.st_mode);
-  if (S_ISBLK(a_stbuf.st_mode) || S_ISCHR(a_stbuf.st_mode))
-    TEST_AND_RETURN_FALSE(a_stbuf.st_rdev == b_stbuf.st_rdev);
-  if (!S_ISDIR(a_stbuf.st_mode))
-    TEST_AND_RETURN_FALSE(a_stbuf.st_nlink == b_stbuf.st_nlink);
-  if (!S_ISREG(a_stbuf.st_mode)) {
-    return true;
-  }
-  // Compare files
-  TEST_AND_RETURN_FALSE(a_stbuf.st_size == b_stbuf.st_size);
-  vector<char> a_data;
-  TEST_AND_RETURN_FALSE(chromeos_update_engine::utils::ReadFile(a, &a_data));
-  vector<char> b_data;
-  TEST_AND_RETURN_FALSE(chromeos_update_engine::utils::ReadFile(b, &b_data));
-  TEST_AND_RETURN_FALSE(a_data == b_data);
-  return true;
-}
-
-class ScopedLoopDevUnmapper {
- public:
-  explicit ScopedLoopDevUnmapper(const string& dev) : dev_(dev) {}
-  ~ScopedLoopDevUnmapper() {
-    EXPECT_EQ(0, System(string("losetup -d ") + dev_));
-  }
- private:
-  string dev_;
-};
-
-}
-
-namespace chromeos_update_engine {
-
-class InstallActionTest : public ::testing::Test { };
-
-TEST(InstallActionTest, RunAsRootDiffTest) {
-  ASSERT_EQ(0, getuid());
-  string loop_dev = GetUnusedLoopDevice();
-  ScopedLoopDevUnmapper loop_dev_unmapper(loop_dev);
-  LOG(INFO) << "Using loop device: " << loop_dev;
-  const string original_image("orig.image");
-  const string original_dir("orig");
-  const string new_dir("new");
-
-  ASSERT_EQ(0, System(string("dd if=/dev/zero of=") + original_image +
-                      " bs=5M count=1"));
-  ASSERT_EQ(0, System(string("mkfs.ext3 -F ") + original_image));
-  ASSERT_EQ(0, System(string("losetup ") + loop_dev + " " + original_image));
-  ASSERT_EQ(0, System(string("mkdir ") + original_dir));
-  ASSERT_EQ(0, System(string("mount ") + loop_dev + " " + original_dir));
-  ASSERT_EQ(0, System(string("mkdir ") + new_dir));
-
-  GenerateFilesAtPath(original_dir);
-  GenerateFilesAtPath(new_dir);
-
-  {
-    // Fill bigfile w/ some data in the new folder
-    vector<char> buf(100 * 1024);
-    for (unsigned int i = 0; i < buf.size(); i++) {
-      buf[i] = static_cast<char>(i);
-    }
-    EXPECT_TRUE(WriteFileVector(new_dir + "/dir/bigfile", buf));
-  }
-  const char* const new_dir_cstr = new_dir.c_str();
-  EXPECT_EQ(0, System(StringPrintf("mkdir -p '%s/newdir'", new_dir_cstr)));
-  EXPECT_EQ(0, System(StringPrintf("chmod 03755 '%s/newdir'", new_dir_cstr)));
-  EXPECT_EQ(0, System(StringPrintf("mkdir -p '%s/newdir/x'", new_dir_cstr)));
-  EXPECT_EQ(0, System(StringPrintf("echo -n foo > '%s/newdir/x/file'",
-                                   new_dir_cstr)));
-  EXPECT_EQ(0, System(StringPrintf("touch '%s/new_empty'", new_dir_cstr)));
-  EXPECT_EQ(0, System(StringPrintf("chmod 04644 '%s/new_empty'",
-                                   new_dir_cstr)));
-  EXPECT_EQ(0, System(StringPrintf("echo -n x >> '%s/big_file'",
-                                   new_dir_cstr)));
-  EXPECT_EQ(0, System(StringPrintf("chmod 02644 '%s/big_file'", new_dir_cstr)));
-  // Make a symlink that compresses well:
-  EXPECT_EQ(0, System(StringPrintf(
-      "ln -s "
-      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
-      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
-      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx "
-      "'%s/compress_sym'", new_dir_cstr)));
-
-  // Make a device that will compress
-  EXPECT_EQ(0, mknod((new_dir + "/bdev_gz").c_str(), S_IFCHR | 0644, 0));
-
-  // Make a diff
-  DeltaArchiveManifest* delta =
-      DeltaDiffGenerator::EncodeMetadataToProtoBuffer(new_dir.c_str());
-  EXPECT_TRUE(NULL != delta);
-  EXPECT_TRUE(DeltaDiffGenerator::EncodeDataToDeltaFile(delta,
-                                                        original_dir,
-                                                        new_dir,
-                                                        "delta",
-                                                        set<string>(),
-                                                        new_dir + "/bdev_gz"));
-
-  ASSERT_EQ(0, System(string("umount ") + original_dir));
-
-  ObjectFeederAction<InstallPlan> feeder_action;
-  InstallAction install_action;
-  ObjectCollectorAction<string> collector_action;
-
-  BondActions(&feeder_action, &install_action);
-  BondActions(&install_action, &collector_action);
-
-  ActionProcessor processor;
-  processor.EnqueueAction(&feeder_action);
-  processor.EnqueueAction(&install_action);
-  processor.EnqueueAction(&collector_action);
-
-  InstallPlan install_plan(false, "", "", "delta", loop_dev);
-  feeder_action.set_obj(install_plan);
-
-  processor.StartProcessing();
-  EXPECT_FALSE(processor.IsRunning()) << "Update to handle async actions";
-
-  EXPECT_EQ(loop_dev, collector_action.object());
-
-  ASSERT_EQ(0, System(string("mount ") + loop_dev + " " + original_dir));
-
-  // Check that original_dir and new_dir are equal
-  int original_count = 0;
-  LOG(INFO) << "checking old";
-  {
-    FilesystemIterator iter(original_dir,
-                            utils::SetWithValue<string>("/lost+found"));
-    for (; !iter.IsEnd(); iter.Increment()) {
-      original_count++;
-      LOG(INFO) << "checking path: " << iter.GetPartialPath();
-      EXPECT_TRUE(FilesEqual(original_dir + iter.GetPartialPath(),
-                             new_dir + iter.GetPartialPath()));
-    }
-    EXPECT_FALSE(iter.IsErr());
-  }
-  LOG(INFO) << "checking new";
-  int new_count = 0;
-  {
-    FilesystemIterator iter(new_dir, set<string>());
-    for (; !iter.IsEnd(); iter.Increment()) {
-      new_count++;
-      LOG(INFO) << "checking path: " << iter.GetPartialPath();
-      EXPECT_TRUE(FilesEqual(original_dir + iter.GetPartialPath(),
-                             new_dir + iter.GetPartialPath()));
-    }
-    EXPECT_FALSE(iter.IsErr());
-  }
-  LOG(INFO) << "new_count = " << new_count;
-  EXPECT_EQ(new_count, original_count);
-  EXPECT_EQ(20, original_count);
-
-  // Make sure hard-link installed properly
-  {
-    struct stat hard_link_stbuf;
-    struct stat hi_stbuf;
-    EXPECT_EQ(0, lstat((string(new_dir) + "/hard_link").c_str(),
-                       &hard_link_stbuf));
-    EXPECT_EQ(0, lstat((string(new_dir) + "/hi").c_str(), &hi_stbuf));
-    EXPECT_EQ(hard_link_stbuf.st_mode, hi_stbuf.st_mode);
-    EXPECT_EQ(2, hard_link_stbuf.st_nlink);
-    EXPECT_EQ(2, hi_stbuf.st_nlink);
-    EXPECT_EQ(hi_stbuf.st_ino, hard_link_stbuf.st_ino);
-  }
-
-  EXPECT_EQ(0, System(string("umount ") + original_dir));
-
-  // Cleanup generated files
-  EXPECT_EQ(0, System(string("rm -rf ") + original_dir));
-  EXPECT_EQ(0, System(string("rm -rf ") + new_dir));
-  EXPECT_EQ(0, System(string("rm -f ") + original_image));
-  EXPECT_EQ(0, system("rm -f delta"));
-}
-
-TEST(InstallActionTest, FullUpdateTest) {
-  ObjectFeederAction<InstallPlan> feeder_action;
-  InstallAction install_action;
-  ObjectCollectorAction<string> collector_action;
-
-  BondActions(&feeder_action, &install_action);
-  BondActions(&install_action, &collector_action);
-
-  ActionProcessor processor;
-  processor.EnqueueAction(&feeder_action);
-  processor.EnqueueAction(&install_action);
-  processor.EnqueueAction(&collector_action);
-
-  InstallPlan install_plan(true, "", "", "delta", "install_path");
-  feeder_action.set_obj(install_plan);
-
-  processor.StartProcessing();
-  EXPECT_FALSE(processor.IsRunning()) << "Update to handle async actions";
-  EXPECT_EQ("install_path", collector_action.object());
-}
-
-TEST(InstallActionTest, InvalidDeltaFileTest) {
-  ObjectFeederAction<InstallPlan> feeder_action;
-  InstallAction install_action;
-  ObjectCollectorAction<string> collector_action;
-
-  BondActions(&feeder_action, &install_action);
-  BondActions(&install_action, &collector_action);
-
-  ActionProcessor processor;
-  processor.EnqueueAction(&feeder_action);
-  processor.EnqueueAction(&install_action);
-  processor.EnqueueAction(&collector_action);
-
-  InstallPlan install_plan(false, "", "", "no_such_file", "install_path");
-  feeder_action.set_obj(install_plan);
-
-  processor.StartProcessing();
-  EXPECT_FALSE(processor.IsRunning()) << "Update to handle async actions";
-  EXPECT_TRUE(collector_action.object().empty());
-}
-
-}  // namespace chromeos_update_engine
diff --git a/install_plan.h b/install_plan.h
index 81893d8..9151e1b 100644
--- a/install_plan.h
+++ b/install_plan.h
@@ -17,26 +17,22 @@
   InstallPlan(bool is_full,
               const std::string& url,
               const std::string& hash,
-              const std::string& d_path,
-              const std::string& i_path)
+              const std::string& install_path)
       : is_full_update(is_full),
         download_url(url),
         download_hash(hash),
-        download_path(d_path),
-        install_path(i_path) {}
+        install_path(install_path) {}
   InstallPlan() : is_full_update(false) {}
 
   bool is_full_update;
   std::string download_url;  // url to download from
   std::string download_hash;  // hash of the data at the url
-  std::string download_path;  // path to downloaded file from Omaha
   std::string install_path;  // path to install device
 
   bool operator==(const InstallPlan& that) const {
     return (is_full_update == that.is_full_update) &&
            (download_url == that.download_url) &&
            (download_hash == that.download_hash) &&
-           (download_path == that.download_path) &&
            (install_path == that.install_path);
   }
   bool operator!=(const InstallPlan& that) const {
@@ -46,7 +42,6 @@
     LOG(INFO) << "InstallPlan: "
               << (is_full_update ? "full_update" : "delta_update")
               << ", url: " << download_url << ", hash: " << download_hash
-              << ", path: " << download_path
               << ", install_path: " << install_path;
   }
 };
diff --git a/main.cc b/main.cc
index bbd9927..cbd6e44 100644
--- a/main.cc
+++ b/main.cc
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(adlr): get rid of commented out lines or comment them back in.
+// Look for "// re-add" next to those comments.
+
 #include <string>
 #include <tr1/memory>
 #include <vector>
@@ -11,7 +14,7 @@
 #include "update_engine/action_processor.h"
 #include "update_engine/download_action.h"
 #include "update_engine/filesystem_copier_action.h"
-#include "update_engine/install_action.h"
+// #include "update_engine/install_action.h"  // re-add
 #include "update_engine/libcurl_http_fetcher.h"
 #include "update_engine/omaha_request_prep_action.h"
 #include "update_engine/omaha_response_handler_action.h"
@@ -64,8 +67,8 @@
       new FilesystemCopierAction);
   shared_ptr<DownloadAction> download_action(
       new DownloadAction(new LibcurlHttpFetcher));
-  shared_ptr<InstallAction> install_action(
-      new InstallAction);
+  // shared_ptr<InstallAction> install_action(  // re-add
+  //     new InstallAction);
   shared_ptr<PostinstallRunnerAction> postinstall_runner_action(
       new PostinstallRunnerAction);
   shared_ptr<SetBootableFlagAction> set_bootable_flag_action(
@@ -78,7 +81,7 @@
   actions_.push_back(shared_ptr<AbstractAction>(response_handler_action));
   actions_.push_back(shared_ptr<AbstractAction>(filesystem_copier_action));
   actions_.push_back(shared_ptr<AbstractAction>(download_action));
-  actions_.push_back(shared_ptr<AbstractAction>(install_action));
+  // actions_.push_back(shared_ptr<AbstractAction>(install_action));  // re-add
   actions_.push_back(shared_ptr<AbstractAction>(postinstall_runner_action));
   actions_.push_back(shared_ptr<AbstractAction>(set_bootable_flag_action));
   
@@ -94,8 +97,8 @@
   BondActions(update_check_action.get(), response_handler_action.get());
   BondActions(response_handler_action.get(), filesystem_copier_action.get());
   BondActions(filesystem_copier_action.get(), download_action.get());
-  BondActions(download_action.get(), install_action.get());
-  BondActions(install_action.get(), postinstall_runner_action.get());
+  // BondActions(download_action.get(), install_action.get());  // re-add
+  // BondActions(install_action.get(), postinstall_runner_action.get());
   BondActions(postinstall_runner_action.get(), set_bootable_flag_action.get());
 
   processor_.StartProcessing();
diff --git a/omaha_response_handler_action.cc b/omaha_response_handler_action.cc
index 0a0a660..4bdef7d 100644
--- a/omaha_response_handler_action.cc
+++ b/omaha_response_handler_action.cc
@@ -47,9 +47,6 @@
     // Very long name. Let's shorten it
     filename.resize(255);
   }
-  // TODO(adlr): come up with a better place to download to:
-  install_plan.download_path = string(utils::kStatefulPartition) + "/" +
-      filename;
   if (HasOutputPipe())
     SetOutputObject(install_plan);
   LOG(INFO) << "Using this install plan:";
diff --git a/omaha_response_handler_action_unittest.cc b/omaha_response_handler_action_unittest.cc
index a76838a..4464332 100644
--- a/omaha_response_handler_action_unittest.cc
+++ b/omaha_response_handler_action_unittest.cc
@@ -93,9 +93,6 @@
     EXPECT_TRUE(install_plan.is_full_update);
     EXPECT_EQ(in.codebase, install_plan.download_url);
     EXPECT_EQ(in.hash, install_plan.download_hash);
-    EXPECT_EQ(string(utils::kStatefulPartition) +
-              "/the_update_a.b.c.d_FULL_.tgz",
-              install_plan.download_path);
     EXPECT_EQ("/dev/sda2", install_plan.install_path);
   }
   {
@@ -113,9 +110,6 @@
     EXPECT_FALSE(install_plan.is_full_update);
     EXPECT_EQ(in.codebase, install_plan.download_url);
     EXPECT_EQ(in.hash, install_plan.download_hash);
-    EXPECT_EQ(string(utils::kStatefulPartition) +
-              "/the_update_a.b.c.d_DELTA_.tgz",
-              install_plan.download_path);
     EXPECT_EQ("/dev/sda3", install_plan.install_path);
   }
   {
@@ -133,9 +127,6 @@
     EXPECT_FALSE(install_plan.is_full_update);
     EXPECT_EQ(in.codebase, install_plan.download_url);
     EXPECT_EQ(in.hash, install_plan.download_hash);
-    EXPECT_EQ(string(utils::kStatefulPartition) + "/" +
-              kLongName.substr(0, 255),
-              install_plan.download_path);
     EXPECT_EQ("/dev/sda3", install_plan.install_path);
   }
 }
@@ -148,7 +139,6 @@
   EXPECT_FALSE(install_plan.is_full_update);
   EXPECT_EQ("", install_plan.download_url);
   EXPECT_EQ("", install_plan.download_hash);
-  EXPECT_EQ("", install_plan.download_path);
   EXPECT_EQ("", install_plan.install_path);
 }
 
diff --git a/test_installer_main.cc b/test_installer_main.cc
index 96e257d..435f5d4 100644
--- a/test_installer_main.cc
+++ b/test_installer_main.cc
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(adlr): get rid of commented out lines or comment them back in.
+// Look for "// re-add" next to those comments.
+
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -17,7 +20,7 @@
 #include "update_engine/delta_diff_generator.h"
 #include "update_engine/delta_diff_parser.h"
 #include "update_engine/filesystem_copier_action.h"
-#include "update_engine/install_action.h"
+// #include "update_engine/install_action.h"  // re-add
 #include "update_engine/install_plan.h"
 #include "update_engine/test_utils.h"
 #include "update_engine/update_metadata.pb.h"
@@ -46,7 +49,6 @@
                 const string& install_path)
       : loop_(loop),
         sys_root_(sys_root),
-        delta_path_(delta_path),
         install_path_(install_path) {}
   void Update();
 
@@ -57,7 +59,6 @@
   ActionProcessor processor_;
   GMainLoop *loop_;
   string sys_root_;
-  string delta_path_;
   string install_path_;
 };
 
@@ -73,12 +74,12 @@
       new ObjectFeederAction<InstallPlan>);
   shared_ptr<FilesystemCopierAction> filesystem_copier_action(
       new FilesystemCopierAction);
-  shared_ptr<InstallAction> install_action(
-      new InstallAction);
+  // shared_ptr<InstallAction> install_action(  // re-add
+  //     new InstallAction);
 
   actions_.push_back(object_feeder_action);
   actions_.push_back(filesystem_copier_action);
-  actions_.push_back(install_action);
+  // actions_.push_back(install_action);  // re-add
 
   // Enqueue the actions
   for (vector<shared_ptr<AbstractAction> >::iterator it = actions_.begin();
@@ -89,12 +90,12 @@
   // Bond them together. We have to use the leaf-types when calling
   // BondActions().
   BondActions(object_feeder_action.get(), filesystem_copier_action.get());
-  BondActions(filesystem_copier_action.get(), install_action.get());
+  // re-add
+  // BondActions(filesystem_copier_action.get(), install_action.get());
   
   InstallPlan install_plan(false,
                            "",
                            "",
-                           delta_path_,
                            install_path_);
   filesystem_copier_action->set_copy_source(sys_root_);
   object_feeder_action->set_obj(install_plan);
@@ -131,50 +132,6 @@
 
   LOG(INFO) << "starting";
   
-  if (!FLAGS_dump_delta.empty()) {
-    CHECK(FLAGS_delta.empty());
-    CHECK(FLAGS_root.empty());
-    CHECK(FLAGS_output_dev.empty());
-    
-    DeltaDiffParser parser(FLAGS_dump_delta);
-    for (DeltaDiffParser::Iterator it = parser.Begin();
-         it != parser.End(); it.Increment()) {
-      DeltaArchiveManifest_File file = it.GetFile();
-      const char* format = "---";
-      ssize_t offset = -1;
-      ssize_t length = -1;
-      if (file.has_data_format()) {
-        switch (file.data_format()) {
-          case DeltaArchiveManifest_File_DataFormat_FULL:
-          format = "FULL";
-          break;
-          case DeltaArchiveManifest_File_DataFormat_FULL_GZ:
-          format = "FULL_GZ";
-          break;
-          case DeltaArchiveManifest_File_DataFormat_BSDIFF:
-          format = "BSDIFF";
-          break;
-          case DeltaArchiveManifest_File_DataFormat_COURGETTE:
-          format = "COURGETTE";
-          break;
-          default:
-            format = "???";
-        }
-        if (file.has_data_offset())
-          offset = file.data_offset();
-        if (file.has_data_length())
-          length = file.data_length();
-      }
-      printf("%s %o %s %d %d\n", it.path().c_str(), file.mode(), format, offset,
-             length);
-    }
-    exit(0);
-  }
-
-  CHECK(!FLAGS_delta.empty());
-  CHECK(!FLAGS_root.empty());
-  CHECK(!FLAGS_output_dev.empty());
-
   // Create the single GMainLoop
   GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
 
diff --git a/update_metadata.proto b/update_metadata.proto
index 42880da..115d513 100644
--- a/update_metadata.proto
+++ b/update_metadata.proto
@@ -7,8 +7,10 @@
 // version. The update format is represented by this struct pseudocode:
 // struct delta_update_file {
 //   char magic[4] = "CrAU";
-//   uint64 bom_offset;  // Offset of protobuf DeltaArchiveManifest
-//   uint64 bom_size;  // Sise of protobuf DeltaArchiveManifest
+//   uint32 file_format_version = 1;
+//   uint64 manifest_size;  // Size of protobuf DeltaArchiveManifest
+//   // The Bzip2 compressed DeltaArchiveManifest
+//   char manifest[];
 //
 //   // Data blobs for files, no specific format. The specific offset
 //   // and length of each data blob is recorded in the DeltaArchiveManifest.
@@ -16,121 +18,82 @@
 //     char data[];
 //   } blobs[];
 //
-//   // The Gzip compressed DeltaArchiveManifest
-//   char bom[];
 // };
 
-// The DeltaArchiveManifest protobuf is an ordered list of File objects.
-// These File objects are stored in a linear array in the
-// DeltaArchiveManifest, each with a specific index. Each File object
-// can contain children in its children list. Each child in the list
-// has a name and an index. The index refers to the index within
-// DeltaArchiveManifest.files. Thus, the DeltaArchiveManifest.files
-// can be seen as a tree structure that mimicks the filesystem.
-// The root object (the object an index 0) has no name, since names
-// for children are stored in the parent.
+// The DeltaArchiveManifest protobuf is an ordered list of InstallOperation
+// objects. These objects are stored in a linear array in the
+// DeltaArchiveManifest. Each operation is applied in order by the client.
 
-// The DeltaArchiveManifest will contain one File entry for each
-// file that will be on the resultant filesystem. Because we have
-// a tree structure, and children are ordered alphabetically within
-// a parent, we can do log-time˜path lookup on a DeltaArchiveManifest
-// object. We can also iterate through a DeltaArchiveManifest object
-// using a preorder tree traversal to see each file in the
-// DeltaArchiveManifest, seeing each directory before any of its children;
-// this takes linear time.
+// The DeltaArchiveManifest also contains the initial and final
+// checksums for the device.
 
-// Here's an example from Dan Erat showing DeltaArchiveManifest
-// for a filesystem with files /bin/cat and /bin/ls.:
-
-// files[0] {  // "/" directory
-//   children[0] {
-//     name "bin"
-//     index 1
-//   }
-// }
-// files[1] {  // "/bin" directory
-//   children[0] {
-//     name "cat"
-//     index 2
-//   }
-//   children[1] {
-//     name "ls"
-//     index 3
-//   }
-// }
-// files[2] {  // "/bin/cat"
-// }
-// files[3] {  // "/bin/ls"
-// }
-
-// If a file has a data_format set, it should also have data_offset and
-// data_length set. data_offset and data_length refer to a range of bytes
-// in the delta update file itself which have the format specified by
-// data_format. FULL and FULL_GZ mean the entire file is present (FULL_GZ,
-// gzip compressed). BSDIFF means the old file with the same path should be
-// patched with 'bspatch' to produce the desired output file. COURGETTE
-// is not yet used, but it will be another binary diff format.
-
-// Directories should not have any data.
-
-// There are other types of files, too: symlinks, block and character devices,
-// fifos, and sockets. Fifos and sockets contain no data. Block and
-// character devices have data. It must be the format FULL or FULL_GZ, and
-// the contents are a serialized LinuxDevice protobuf. Symlinks must either
-// be FULL, FULL_GZ, or have no data. A symlink with no data is unchanged,
-// and with data it's set to that data.
-
-// TODO(adlr): Add support for hard links; CL is prepared already.
-// Extended attributes are unsupported at this time.
+// The client will perform each InstallOperation in order, beginning even
+// before the entire delta file is downloaded (but after at least the
+// protobuf is downloaded). The types of operations are explained:
+// - REPLACE: Replace the dst_extents on the drive with the attached data,
+//   zero padding out to block size.
+// - REPLACE_BZ: bzip2-uncompress the attached data and write it into
+//   dst_extents on the drive, zero padding to block size.
+// - MOVE: Copy the data in src_extents to dst_extents. Extents may overlap,
+//   so it may be desirable to read all src_extents data into memory before
+//   writing it out.
+// - BSDIFF: Read src_length bytes from src_extents into memory, perform
+//   bspatch with attached data, write new data to dst_extents, zero padding
+//   to block size.
 
 package chromeos_update_engine;
 
-message DeltaArchiveManifest {
-  message File {
-    // This is st_mode from struct stat. It includes file type and permission
-    // bits.
-    optional uint32 mode = 1;
-    optional uint32 uid = 2;
-    optional uint32 gid = 3;
+// Data is packed into blocks on disk, always starting from the beginning
+// of the block. If a file's data is too large for one block, it overflows
+// into another block, which may or may not be the following block on the
+// physical partition. An ordered list of extents is another
+// representation of an ordered list of blocks. For example, a file stored
+// in blocks 9, 10, 11, 2, 18, 12 (in that order) would be stored in
+// extents { {9, 3}, {2, 1}, {18, 1}, {12, 1} } (in that order).
+// In general, files are stored sequentially on disk, so it's more efficient
+// to use extents to encode the block lists (this is effectively
+// run-length encoding).
+// A sentinel value (kuint64max) as the start block denotes a sparse-hole
+// in a file whose block-length is specified by num_blocks.
 
-    // File Data, not for directories
-    enum DataFormat {
-      FULL = 0;  // The data is the complete file
-      FULL_GZ = 1;  // The data is the complete file gzipped
-      BSDIFF = 2;  // The data is a bsdiff binary diff
-      COURGETTE = 3;  // The data is a courgette binary diff
-    }
-    // If present, there is data associated with this File object and
-    // data_offset and data_size must be set.
-    // If a file object doesn't have this set, it means the data is
-    // unchanged from the old version of the file.
-    optional DataFormat data_format = 4;
-    // The offset into the delta file where the data (if any) is stored
-    optional uint32 data_offset = 5;
-    // The length of the data in the delta file
-    optional uint32 data_length = 6;
-    
-    // When a file is a hard link, hardlink_path exists and
-    // is the path within the DeltaArchiveManifest to the "original" file.
-    // When iterating through a DeltaArchiveManifest,  you will be guaranteed
-    // to hit a hardlink only after you've hit the path to the first file.
-    // Directories can't be hardlinked.
-    optional string hardlink_path = 8;
-
-    message Child {
-      // A File that's a directory (and only those types of File objects)
-      // will have exactly one Child submessage per child.
-      required string name = 1;  // File name of child
-
-      // Index into DeltaArchiveManifest.files for the File object of the child.
-      required uint32 index = 2;
-    }
-    repeated Child children = 9;
-  }
-  repeated File files = 1;
+message Extent {
+  optional uint64 start_block = 1;
+  optional uint64 num_blocks = 2;
 }
 
-message LinuxDevice {
-  required int32 major = 1;
-  required int32 minor = 2;
-}
\ No newline at end of file
+message DeltaArchiveManifest {
+  message InstallOperation {
+    enum Type {
+      REPLACE = 0;  // Replace destination extents w/ attached data
+      REPLACE_BZ = 1;  // Replace destination extents w/ attached bzipped data
+      MOVE = 2;  // Move source extents to destination extents
+      BSDIFF = 3;  // The data is a bsdiff binary diff
+    }
+    required Type type = 1;
+    // The offset into the delta file (after the protobuf)
+    // where the data (if any) is stored
+    optional uint32 data_offset = 2;
+    // The length of the data in the delta file
+    optional uint32 data_length = 3;
+
+    // Ordered list of extents that are read from (if any) and written to.
+    repeated Extent src_extents = 4;
+    // Byte length of src, not necessarily block aligned. It's only used for
+    // BSDIFF, because we need to pass that external program the number
+    // of bytes to read from the blocks we pass it.
+    optional uint64 src_length = 5;
+
+    repeated Extent dst_extents = 6;
+    // byte length of dst, not necessarily block aligned. It's only used for
+    // BSDIFF, because we need to fill in the rest of the last block
+    // that bsdiff writes with '\0' bytes.
+    optional uint64 dst_length = 7;
+  }
+  repeated InstallOperation install_operations = 1;
+  // The checksums of the install device before and after the install process.
+  optional string src_checksum = 2;
+  optional string dst_checksum = 3;
+
+  // (At time of writing) usually 4096
+  optional uint32 block_size = 5 [default = 4096];
+}