Merge pie-platform-release to aosp-master - DO NOT MERGE

Change-Id: Id26ee533663ca94626093fc264a51340f3fd2d34
diff --git a/.clang-format b/.clang-format
index 3f19e61..5f6e882 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1 +1,3 @@
 BasedOnStyle: Chromium
+
+AllowAllParametersOfDeclarationOnNextLine: true
diff --git a/Android.bp b/Android.bp
index 5d99dcb..79d124a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -14,10 +14,10 @@
     cflags: [
         "-DUSE_BRILLO=1",
         "-D_FILE_OFFSET_BITS=64",
-        "-DZLIB_CONST",
         "-Wall",
         "-Werror",
         "-Wextra",
+        "-Wimplicit-fallthrough",
     ],
     target: {
         darwin: {
@@ -62,7 +62,6 @@
     static_libs: [
         "libbsdiff",
         "libpuffpatch",
-        "libz",
     ],
 }
 
@@ -80,7 +79,6 @@
         "libdivsufsort64",
         "libpuffdiff",
         "libpuffpatch",
-        "libz",
     ],
 }
 
@@ -95,15 +93,11 @@
         "src/patching_unittest.cc",
         "src/puff_io_unittest.cc",
         "src/puffin_unittest.cc",
-        "src/sample_generator.cc",
         "src/stream_unittest.cc",
         "src/testrunner.cc",
         "src/unittest_common.cc",
         "src/utils_unittest.cc",
     ],
-    shared_libs: [
-        "libz",
-    ],
     static_libs: [
         "libbsdiff",
         "libbspatch",
diff --git a/BUILD.gn b/BUILD.gn
new file mode 100644
index 0000000..f6df14b
--- /dev/null
+++ b/BUILD.gn
@@ -0,0 +1,146 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//common-mk/pkg_config.gni")
+import("//common-mk/proto_library.gni")
+
+group("all") {
+  deps = [
+    ":libpuffin-proto",
+    ":libpuffdiff",
+    ":libpuffpatch",
+    ":puffin",
+  ]
+  if (use.test) {
+    deps += [ ":puffin_test" ]
+  }
+  if (use.fuzzer) {
+    deps += [ ":puffin_fuzzer" ]
+  }
+}
+
+pkg_config("target_defaults") {
+  pkg_deps = [
+    "libchrome-${libbase_ver}",
+    "libbrillo-${libbase_ver}",
+    "protobuf-lite",
+  ]
+  cflags = [ "-Wextra" ]
+  cflags_cc = [ "-Wnon-virtual-dtor" ]
+  include_dirs = [ "src/include" ]
+  defines = [
+    "USE_BRILLO",
+    "_FILE_OFFSET_BITS=64",
+  ]
+}
+
+proto_library("libpuffin-proto") {
+  proto_in_dir = "src"
+  proto_out_dir = "include/puffin/src"
+  sources = [
+    "src/puffin.proto",
+  ]
+}
+
+pkg_config("libpuffpatch_config") {
+  pkg_deps = [
+    "libbspatch",
+  ]
+}
+
+static_library("libpuffpatch") {
+  configs += [
+    "//common-mk:nouse_thin_archive",
+    ":target_defaults",
+    ":libpuffpatch_config",
+  ]
+  configs -= [ "//common-mk:use_thin_archive" ]
+  complete_static_lib = true
+  deps = [ ":libpuffin-proto" ]
+  sources = [
+    "src/bit_reader.cc",
+    "src/bit_writer.cc",
+    "src/huffer.cc",
+    "src/huffman_table.cc",
+    "src/puff_reader.cc",
+    "src/puff_writer.cc",
+    "src/puffer.cc",
+    "src/puffin_stream.cc",
+    "src/puffpatch.cc",
+  ]
+}
+
+pkg_config("libpuffdiff_config") {
+  pkg_deps = [
+    "libbsdiff",
+  ]
+}
+static_library("libpuffdiff") {
+  configs += [
+    "//common-mk:nouse_thin_archive",
+    ":target_defaults",
+    ":libpuffdiff_config",
+  ]
+  configs -= [ "//common-mk:use_thin_archive" ]
+  deps = [
+    ":libpuffpatch",
+  ]
+  sources = [
+    "src/file_stream.cc",
+    "src/memory_stream.cc",
+    "src/puffdiff.cc",
+    "src/utils.cc",
+  ]
+}
+
+executable("puffin") {
+  configs += [
+    ":target_defaults",
+  ]
+  deps = [
+    ":libpuffdiff",
+  ]
+  sources = [
+    "src/extent_stream.cc",
+    "src/main.cc",
+  ]
+}
+
+if (use.test) {
+  executable("puffin_test") {
+    configs += [
+      "//common-mk:test",
+      ":target_defaults",
+    ]
+    sources = [
+      "src/bit_io_unittest.cc",
+      "src/extent_stream.cc",
+      "src/patching_unittest.cc",
+      "src/puff_io_unittest.cc",
+      "src/puffin_unittest.cc",
+      "src/stream_unittest.cc",
+      "src/unittest_common.cc",
+      "src/utils_unittest.cc",
+    ]
+    deps = [
+      "//common-mk/testrunner",
+      ":libpuffdiff",
+    ]
+  }
+}
+
+if (use.fuzzer) {
+  executable("puffin_fuzzer") {
+    configs += [
+      "//common-mk/common_fuzzer",
+      ":target_defaults",
+    ]
+    deps = [
+      ":libpuffdiff",
+    ]
+    sources = [
+      "src/fuzzer.cc",
+    ]
+  }
+}
diff --git a/PRESUBMIT.cfg b/PRESUBMIT.cfg
index c1cb0d7..254479a 100644
--- a/PRESUBMIT.cfg
+++ b/PRESUBMIT.cfg
@@ -1,3 +1,6 @@
 [Hook Scripts]
 hook0=../../../../chromite/bin/cros lint ${PRESUBMIT_FILES}
 hook1=../../../platform2/common-mk/gyplint.py ${PRESUBMIT_FILES}
+
+[Hook Overrides]
+clang_format_check: true
diff --git a/README.version b/README.version
new file mode 100644
index 0000000..387bfbf
--- /dev/null
+++ b/README.version
@@ -0,0 +1,2 @@
+Homepage: https://android.googlesource.com/platform/external/puffin/
+Version: 1.0.0
diff --git a/libpuffdiff.pc b/libpuffdiff.pc
index 50c8ca2..f75de07 100644
--- a/libpuffdiff.pc
+++ b/libpuffdiff.pc
@@ -2,5 +2,8 @@
 
 Name: libpuffdiff
 Description: Puffin library for generating delta patches
-Version: 0.0.1
-Libs: -lpuffdiff
\ No newline at end of file
+Version: 1.0.0
+# libpuffdiff library is static lib ATM, so we don't use private versions of
+# Libs and Requires fields.
+Libs: -lpuffdiff
+Requires: libpuffpatch libbsdiff
diff --git a/libpuffpatch.pc b/libpuffpatch.pc
index 2c578a1..dbb7d74 100644
--- a/libpuffpatch.pc
+++ b/libpuffpatch.pc
@@ -2,5 +2,8 @@
 
 Name: libpuffpatch
 Description: Puffin library for applying delta patches
-Version: 0.0.1
-Libs: -lpuffpatch
\ No newline at end of file
+Version: 1.0.0
+# libpuffpatch library is static lib ATM, so we don't use private versions of
+# Libs and Requires fields.
+Libs: -lpuffpatch
+Requires: libbspatch
diff --git a/puffin.gyp b/puffin.gyp
deleted file mode 100644
index 4903e00..0000000
--- a/puffin.gyp
+++ /dev/null
@@ -1,199 +0,0 @@
-# Copyright 2017 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
-  'target_defaults': {
-    'variables': {
-      'deps': [
-        'libbrillo-<(libbase_ver)',
-        'libchrome-<(libbase_ver)',
-      ],
-    },
-    'cflags': [
-      '-Wextra',
-    ],
-    'cflags_cc': [
-      '-Wnon-virtual-dtor',
-    ],
-    'include_dirs': [
-      'src/include',
-    ],
-    'defines': [
-      'USE_BRILLO=1',
-      '_FILE_OFFSET_BITS=64',
-      'ZLIB_CONST',
-    ],
-  },
-  'targets': [
-    # libpuffin-proto library
-    {
-      'target_name': 'libpuffin-proto',
-      'type': 'static_library',
-      'variables': {
-        'proto_in_dir': 'src',
-        'proto_out_dir': 'include/puffin/src',
-      },
-      'cflags!': ['-fPIE'],
-      'cflags': ['-fPIC'],
-      'all_dependent_settings': {
-        'variables': {
-          'deps': [
-            'protobuf-lite',
-          ],
-        },
-      },
-      'sources': [
-        '<(proto_in_dir)/puffin.proto',
-      ],
-      'includes': ['../../platform2/common-mk/protoc.gypi'],
-    },
-    # puffpatch static library. The reason to do one static and one shared is to
-    # be able to run the unittest.
-    {
-      'target_name': 'libpuffpatch-static',
-      'type': 'static_library',
-      'cflags!': ['-fPIE'],
-      'cflags': ['-fPIC'],
-      'sources': [
-        'src/bit_reader.cc',
-        'src/bit_writer.cc',
-        'src/huffer.cc',
-        'src/huffman_table.cc',
-        'src/puff_reader.cc',
-        'src/puff_writer.cc',
-        'src/puffer.cc',
-        'src/puffin_stream.cc',
-        'src/puffpatch.cc',
-      ],
-      'dependencies': [
-        'libpuffin-proto',
-      ],
-      'all_dependent_settings': {
-        'link_settings': {
-          'libraries': [
-            '-lbspatch',
-          ],
-        },
-      },
-    },
-    # puffdiff static library.
-    {
-      'target_name': 'libpuffdiff-static',
-      'type': 'static_library',
-      'cflags!': ['-fPIE'],
-      'cflags': ['-fPIC'],
-      'sources': [
-        'src/file_stream.cc',
-        'src/memory_stream.cc',
-        'src/puffdiff.cc',
-        'src/utils.cc',
-      ],
-      'dependencies': [
-        'libpuffpatch-static',
-      ],
-      'all_dependent_settings': {
-        'variables': {
-          'deps': [
-            'zlib',
-          ],
-        },
-        'link_settings': {
-          'libraries': [
-            '-lbsdiff',
-          ],
-        },
-      },
-    },
-    # puffpatch shared library.
-    {
-      'target_name': 'libpuffpatch',
-      'type': 'shared_library',
-      'dependencies': [
-        'libpuffpatch-static',
-      ],
-    },
-    # puffdiff shared library.
-    {
-      'target_name': 'libpuffdiff',
-      'type': 'shared_library',
-      'dependencies': [
-        'libpuffdiff-static',
-      ],
-    },
-    # Puffin executable. We don't use the shared libraries because then we have
-    # to export symbols that shouldn't be exported otherwise.
-    {
-      'target_name': 'puffin',
-      'type': 'executable',
-      'dependencies': [
-        'libpuffdiff-static',
-      ],
-      'sources': [
-        'src/extent_stream.cc',
-        'src/main.cc',
-      ],
-    },
-  ],
-  # unit tests.
-  'conditions': [
-    ['USE_test == 1', {
-      'targets': [
-        # Samples generator.
-        {
-          'target_name': 'libsample_generator',
-          'type': 'static_library',
-          'sources': [
-            'src/sample_generator.cc',
-          ],
-          'all_dependent_settings': {
-            'variables': {
-              'deps': [
-                'zlib',
-              ],
-            },
-          },
-        },
-        # Unit tests.
-        {
-          'target_name': 'puffin_unittest',
-          'type': 'executable',
-          'dependencies': [
-            'libpuffdiff-static',
-            'libsample_generator',
-            '../../platform2/common-mk/testrunner.gyp:testrunner',
-          ],
-          'includes': ['../../platform2/common-mk/common_test.gypi'],
-          'sources': [
-            'src/bit_io_unittest.cc',
-            'src/extent_stream.cc',
-            'src/patching_unittest.cc',
-            'src/puff_io_unittest.cc',
-            'src/puffin_unittest.cc',
-            'src/stream_unittest.cc',
-            'src/unittest_common.cc',
-            'src/utils_unittest.cc',
-          ],
-        },
-      ],
-    }],
-    # fuzzer target
-    ['USE_fuzzer == 1', {
-      'targets': [
-        {
-          'target_name': 'puffin_fuzzer',
-          'type': 'executable',
-          'dependencies': [
-            'libpuffin-proto',
-            'libpuffdiff-static',
-            'libpuffpatch-static',
-          ],
-          'includes': ['../../platform2/common-mk/common_fuzzer.gypi'],
-          'sources': [
-            'src/fuzzer.cc',
-          ],
-        },
-      ],
-    }],
-  ],
-}
diff --git a/scripts/measure_patch_size.py b/scripts/measure_patch_size.py
new file mode 100755
index 0000000..252217b
--- /dev/null
+++ b/scripts/measure_patch_size.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python3
+#
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+
+"""A tool for running diffing tools and measuring patch sizes."""
+
+import argparse
+import logging
+import os
+import subprocess
+import sys
+import tempfile
+
+
+class Error(Exception):
+  """Puffin general processing error."""
+
+
+def ParseArguments(argv):
+  """Parses and Validates command line arguments.
+
+  Args:
+    argv: command line arguments to parse.
+
+  Returns:
+    The arguments list.
+  """
+  parser = argparse.ArgumentParser()
+
+  parser.add_argument('--src-corpus', metavar='DIR',
+                      help='The source corpus directory with compressed files.')
+  parser.add_argument('--tgt-corpus', metavar='DIR',
+                      help='The target corpus directory with compressed files.')
+  parser.add_argument('--debug', action='store_true',
+                      help='Turns on verbosity.')
+
+  # Parse command-line arguments.
+  args = parser.parse_args(argv)
+
+  for corpus in (args.src_corpus, args.tgt_corpus):
+    if not corpus or not os.path.isdir(corpus):
+      raise Error('Corpus directory {} is non-existent or inaccesible'
+                  .format(corpus))
+  return args
+
+
+def main(argv):
+  """The main function."""
+  args = ParseArguments(argv[1:])
+
+  if args.debug:
+    logging.getLogger().setLevel(logging.DEBUG)
+
+  # Construct list of appropriate files.
+  src_files = list(filter(os.path.isfile,
+                          [os.path.join(args.src_corpus, f)
+                           for f in os.listdir(args.src_corpus)]))
+  tgt_files = list(filter(os.path.isfile,
+                          [os.path.join(args.tgt_corpus, f)
+                           for f in os.listdir(args.tgt_corpus)]))
+
+  # Check if all files in src_files have a target file in tgt_files.
+  files_mismatch = (set(map(os.path.basename, src_files)) -
+                    set(map(os.path.basename, tgt_files)))
+  if files_mismatch:
+    raise Error('Target files {} do not exist in corpus: {}'
+                .format(files_mismatch, args.tgt_corpus))
+
+  for src in src_files:
+    with tempfile.NamedTemporaryFile() as puffdiff_patch, \
+         tempfile.NamedTemporaryFile() as bsdiff_patch:
+
+      tgt = os.path.join(args.tgt_corpus, os.path.basename(src))
+
+      operation = 'puffdiff'
+      cmd = ['puffin',
+             '--operation={}'.format(operation),
+             '--src_file={}'.format(src),
+             '--dst_file={}'.format(tgt),
+             '--patch_file={}'.format(puffdiff_patch.name)]
+      # Running the puffdiff operation
+      if subprocess.call(cmd) != 0:
+        raise Error('Puffin failed to do {} command: {}'
+                    .format(operation, cmd))
+
+      operation = 'bsdiff'
+      cmd = ['bsdiff', '--type', 'bz2', src, tgt, bsdiff_patch.name]
+      # Running the bsdiff operation
+      if subprocess.call(cmd) != 0:
+        raise Error('Failed to do {} command: {}'
+                    .format(operation, cmd))
+
+      logging.debug('%s(%d -> %d) : bsdiff(%d), puffdiff(%d)',
+                    os.path.basename(src),
+                    os.stat(src).st_size, os.stat(tgt).st_size,
+                    os.stat(bsdiff_patch.name).st_size,
+                    os.stat(puffdiff_patch.name).st_size)
+
+  return 0
+
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))
diff --git a/src/bit_io_unittest.cc b/src/bit_io_unittest.cc
index e929841..87fc3f1 100644
--- a/src/bit_io_unittest.cc
+++ b/src/bit_io_unittest.cc
@@ -8,7 +8,7 @@
 
 #include "puffin/src/bit_reader.h"
 #include "puffin/src/bit_writer.h"
-#include "puffin/src/set_errors.h"
+#include "puffin/src/logging.h"
 #include "puffin/src/unittest_common.h"
 
 namespace puffin {
diff --git a/src/bit_reader.cc b/src/bit_reader.cc
index d6f6abb..27f1d8d 100644
--- a/src/bit_reader.cc
+++ b/src/bit_reader.cc
@@ -4,7 +4,7 @@
 
 #include "puffin/src/bit_reader.h"
 
-#include "puffin/src/set_errors.h"
+#include "puffin/src/logging.h"
 
 namespace puffin {
 
diff --git a/src/bit_writer.cc b/src/bit_writer.cc
index 5f4fdea..66d46f2 100644
--- a/src/bit_writer.cc
+++ b/src/bit_writer.cc
@@ -6,7 +6,7 @@
 
 #include <algorithm>
 
-#include "puffin/src/set_errors.h"
+#include "puffin/src/logging.h"
 
 namespace puffin {
 
diff --git a/src/extent_stream.cc b/src/extent_stream.cc
index d6d6060..3622125 100644
--- a/src/extent_stream.cc
+++ b/src/extent_stream.cc
@@ -7,12 +7,12 @@
 #include <algorithm>
 #include <utility>
 
-#include "puffin/src/set_errors.h"
-
-namespace puffin {
+#include "puffin/src/logging.h"
 
 using std::vector;
 
+namespace puffin {
+
 UniqueStreamPtr ExtentStream::CreateForWrite(
     UniqueStreamPtr stream, const vector<ByteExtent>& extents) {
   return UniqueStreamPtr(new ExtentStream(std::move(stream), extents, true));
diff --git a/src/file_stream.cc b/src/file_stream.cc
index 2089078..0abde31 100644
--- a/src/file_stream.cc
+++ b/src/file_stream.cc
@@ -11,12 +11,12 @@
 #include <utility>
 
 #include "puffin/src/include/puffin/common.h"
-#include "puffin/src/set_errors.h"
-
-namespace puffin {
+#include "puffin/src/logging.h"
 
 using std::string;
 
+namespace puffin {
+
 UniqueStreamPtr FileStream::Open(const string& path, bool read, bool write) {
   TEST_AND_RETURN_VALUE(read || write, nullptr);
   int flags = O_CLOEXEC;
diff --git a/src/fuzzer.cc b/src/fuzzer.cc
index 10cf7c2..b870ac4 100644
--- a/src/fuzzer.cc
+++ b/src/fuzzer.cc
@@ -17,18 +17,32 @@
 #include "puffin/src/puff_reader.h"
 #include "puffin/src/puff_writer.h"
 
-using std::vector;
-
 using puffin::BitExtent;
 using puffin::Buffer;
 using puffin::BufferBitReader;
 using puffin::BufferBitWriter;
 using puffin::BufferPuffReader;
 using puffin::BufferPuffWriter;
-using puffin::Error;
+using puffin::ByteExtent;
 using puffin::Huffer;
 using puffin::MemoryStream;
 using puffin::Puffer;
+using puffin::UniqueStreamPtr;
+using std::vector;
+
+namespace puffin {
+// From puffpatch.cc
+bool DecodePatch(const uint8_t* patch,
+                 size_t patch_length,
+                 size_t* bsdiff_patch_offset,
+                 size_t* bsdiff_patch_size,
+                 vector<BitExtent>* src_deflates,
+                 vector<BitExtent>* dst_deflates,
+                 vector<ByteExtent>* src_puffs,
+                 vector<ByteExtent>* dst_puffs,
+                 uint64_t* src_puff_size,
+                 uint64_t* dst_puff_size);
+}  // namespace puffin
 
 namespace {
 void FuzzPuff(const uint8_t* data, size_t size) {
@@ -36,27 +50,68 @@
   Buffer puff_buffer(size * 2);
   BufferPuffWriter puff_writer(puff_buffer.data(), puff_buffer.size());
   vector<BitExtent> bit_extents;
-  Error error;
   Puffer puffer;
-  puffer.PuffDeflate(&bit_reader, &puff_writer, &bit_extents, &error);
+  puffer.PuffDeflate(&bit_reader, &puff_writer, &bit_extents);
 }
 
 void FuzzHuff(const uint8_t* data, size_t size) {
   BufferPuffReader puff_reader(data, size);
   Buffer deflate_buffer(size);
   BufferBitWriter bit_writer(deflate_buffer.data(), deflate_buffer.size());
-  Error error;
   Huffer huffer;
-  huffer.HuffDeflate(&puff_reader, &bit_writer, &error);
+  huffer.HuffDeflate(&puff_reader, &bit_writer);
+}
+
+template <typename T>
+bool TestExtentsArrayForFuzzer(const vector<T>& extents) {
+  const size_t kMaxArraySize = 100;
+  if (extents.size() > kMaxArraySize) {
+    return false;
+  }
+
+  const size_t kMaxBufferSize = 1024;  // 1Kb
+  for (const auto& ext : extents) {
+    if (ext.length > kMaxBufferSize) {
+      return false;
+    }
+  }
+  return true;
 }
 
 void FuzzPuffPatch(const uint8_t* data, size_t size) {
-  const size_t kBufferSize = 1000;
-  Buffer src_buffer(kBufferSize);
-  Buffer dst_buffer(kBufferSize);
-  auto src = MemoryStream::CreateForRead(src_buffer);
-  auto dst = MemoryStream::CreateForWrite(&dst_buffer);
-  puffin::PuffPatch(std::move(src), std::move(dst), data, size, kBufferSize);
+  // First decode the header and make sure the deflate and puff buffer sizes do
+  // not excede some limits. This is to prevent the fuzzer complain with
+  // out-of-memory errors when the fuzz data is in such a way that causes a huge
+  // random size memory be allocated.
+
+  size_t bsdiff_patch_offset;
+  size_t bsdiff_patch_size = 0;
+  vector<BitExtent> src_deflates, dst_deflates;
+  vector<ByteExtent> src_puffs, dst_puffs;
+  uint64_t src_puff_size, dst_puff_size;
+  if (DecodePatch(data, size, &bsdiff_patch_offset, &bsdiff_patch_size,
+                  &src_deflates, &dst_deflates, &src_puffs, &dst_puffs,
+                  &src_puff_size, &dst_puff_size) &&
+      TestExtentsArrayForFuzzer(src_deflates) &&
+      TestExtentsArrayForFuzzer(dst_deflates) &&
+      TestExtentsArrayForFuzzer(src_puffs) &&
+      TestExtentsArrayForFuzzer(dst_puffs)) {
+    const size_t kBufferSize = 1000;
+    if ((!src_deflates.empty() &&
+         kBufferSize <
+             src_deflates.back().offset + src_deflates.back().length) ||
+        (!dst_deflates.empty() &&
+         kBufferSize <
+             dst_deflates.back().offset + dst_deflates.back().length)) {
+      return;
+    }
+
+    Buffer src_buffer(kBufferSize);
+    Buffer dst_buffer(kBufferSize);
+    auto src = MemoryStream::CreateForRead(src_buffer);
+    auto dst = MemoryStream::CreateForWrite(&dst_buffer);
+    puffin::PuffPatch(std::move(src), std::move(dst), data, size, kBufferSize);
+  }
 }
 
 struct Environment {
diff --git a/src/huffer.cc b/src/huffer.cc
index 622c2ac..6119205 100644
--- a/src/huffer.cc
+++ b/src/huffer.cc
@@ -13,31 +13,28 @@
 #include "puffin/src/huffman_table.h"
 #include "puffin/src/include/puffin/common.h"
 #include "puffin/src/include/puffin/stream.h"
+#include "puffin/src/logging.h"
 #include "puffin/src/puff_data.h"
 #include "puffin/src/puff_reader.h"
-#include "puffin/src/set_errors.h"
-
-namespace puffin {
 
 using std::string;
 
+namespace puffin {
+
 Huffer::Huffer() : dyn_ht_(new HuffmanTable()), fix_ht_(new HuffmanTable()) {}
 
 Huffer::~Huffer() {}
 
 bool Huffer::HuffDeflate(PuffReaderInterface* pr,
-                         BitWriterInterface* bw,
-                         Error* error) const {
-  *error = Error::kSuccess;
+                         BitWriterInterface* bw) const {
   PuffData pd;
   HuffmanTable* cur_ht = nullptr;
   // If no bytes left for PuffReader to read, bail out.
   while (pr->BytesLeft() != 0) {
-    TEST_AND_RETURN_FALSE(pr->GetNext(&pd, error));
+    TEST_AND_RETURN_FALSE(pr->GetNext(&pd));
 
     // The first data should be a metadata.
-    TEST_AND_RETURN_FALSE_SET_ERROR(pd.type == PuffData::Type::kBlockMetadata,
-                                    Error::kInvalidInput);
+    TEST_AND_RETURN_FALSE(pd.type == PuffData::Type::kBlockMetadata);
     auto header = pd.block_metadata[0];
     auto final_bit = (header & 0x80) >> 7;
     auto type = (header & 0x60) >> 5;
@@ -45,36 +42,26 @@
     DVLOG(2) << "Write block type: "
              << BlockTypeToString(static_cast<BlockType>(type));
 
-    TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(1, final_bit),
-                                    Error::kInsufficientInput);
-    TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(2, type),
-                                    Error::kInsufficientInput);
+    TEST_AND_RETURN_FALSE(bw->WriteBits(1, final_bit));
+    TEST_AND_RETURN_FALSE(bw->WriteBits(2, type));
     switch (static_cast<BlockType>(type)) {
       case BlockType::kUncompressed:
         bw->WriteBoundaryBits(skipped_bits);
-        TEST_AND_RETURN_FALSE(pr->GetNext(&pd, error));
-        TEST_AND_RETURN_FALSE_SET_ERROR(pd.type != PuffData::Type::kLiteral,
-                                        Error::kInvalidInput);
+        TEST_AND_RETURN_FALSE(pr->GetNext(&pd));
+        TEST_AND_RETURN_FALSE(pd.type != PuffData::Type::kLiteral);
 
         if (pd.type == PuffData::Type::kLiterals) {
-          TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(16, pd.length),
-                                          Error::kInsufficientOutput);
-          TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(16, ~pd.length),
-                                          Error::kInsufficientOutput);
-          TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBytes(pd.length, pd.read_fn),
-                                          Error::kInsufficientOutput);
+          TEST_AND_RETURN_FALSE(bw->WriteBits(16, pd.length));
+          TEST_AND_RETURN_FALSE(bw->WriteBits(16, ~pd.length));
+          TEST_AND_RETURN_FALSE(bw->WriteBytes(pd.length, pd.read_fn));
           // Reading end of block, but don't write anything.
-          TEST_AND_RETURN_FALSE(pr->GetNext(&pd, error));
-          TEST_AND_RETURN_FALSE_SET_ERROR(
-              pd.type == PuffData::Type::kEndOfBlock, Error::kInvalidInput);
+          TEST_AND_RETURN_FALSE(pr->GetNext(&pd));
+          TEST_AND_RETURN_FALSE(pd.type == PuffData::Type::kEndOfBlock);
         } else if (pd.type == PuffData::Type::kEndOfBlock) {
-          TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(16, 0),
-                                          Error::kInsufficientOutput);
-          TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(16, ~0),
-                                          Error::kInsufficientOutput);
+          TEST_AND_RETURN_FALSE(bw->WriteBits(16, 0));
+          TEST_AND_RETURN_FALSE(bw->WriteBits(16, ~0));
         } else {
           LOG(ERROR) << "Uncompressed block did not end properly!";
-          *error = Error::kInvalidInput;
           return false;
         }
         // We have to read a new block.
@@ -88,13 +75,12 @@
       case BlockType::kDynamic:
         cur_ht = dyn_ht_.get();
         TEST_AND_RETURN_FALSE(dyn_ht_->BuildDynamicHuffmanTable(
-            &pd.block_metadata[1], pd.length - 1, bw, error));
+            &pd.block_metadata[1], pd.length - 1, bw));
         break;
 
       default:
         LOG(ERROR) << "Invalid block compression type: "
                    << static_cast<int>(type);
-        *error = Error::kInvalidInput;
         return false;
     }
 
@@ -102,19 +88,16 @@
     // stream is reached.
     bool block_ended = false;
     while (!block_ended) {
-      TEST_AND_RETURN_FALSE(pr->GetNext(&pd, error));
+      TEST_AND_RETURN_FALSE(pr->GetNext(&pd));
       switch (pd.type) {
         case PuffData::Type::kLiteral:
         case PuffData::Type::kLiterals: {
-          auto write_literal = [&cur_ht, &bw, &error](uint8_t literal) {
+          auto write_literal = [&cur_ht, &bw](uint8_t literal) {
             uint16_t literal_huffman;
             size_t nbits;
-            TEST_AND_RETURN_FALSE_SET_ERROR(
-                cur_ht->LitLenHuffman(literal, &literal_huffman, &nbits),
-                Error::kInvalidInput);
-            TEST_AND_RETURN_FALSE_SET_ERROR(
-                bw->WriteBits(nbits, literal_huffman),
-                Error::kInsufficientOutput);
+            TEST_AND_RETURN_FALSE(
+                cur_ht->LitLenHuffman(literal, &literal_huffman, &nbits));
+            TEST_AND_RETURN_FALSE(bw->WriteBits(nbits, literal_huffman));
             return true;
           };
 
@@ -133,8 +116,7 @@
         case PuffData::Type::kLenDist: {
           auto len = pd.length;
           auto dist = pd.distance;
-          TEST_AND_RETURN_FALSE_SET_ERROR(len >= 3 && len <= 258,
-                                          Error::kInvalidInput);
+          TEST_AND_RETURN_FALSE(len >= 3 && len <= 258);
 
           // Using a binary search here instead of the linear search may be (but
           // not necessarily) faster. Needs experiment to validate.
@@ -148,17 +130,14 @@
           auto extra_bits_len = kLengthExtraBits[index];
           uint16_t length_huffman;
           size_t nbits;
-          TEST_AND_RETURN_FALSE_SET_ERROR(
-              cur_ht->LitLenHuffman(index + 257, &length_huffman, &nbits),
-              Error::kInvalidInput);
+          TEST_AND_RETURN_FALSE(
+              cur_ht->LitLenHuffman(index + 257, &length_huffman, &nbits));
 
-          TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(nbits, length_huffman),
-                                          Error::kInsufficientInput);
+          TEST_AND_RETURN_FALSE(bw->WriteBits(nbits, length_huffman));
 
           if (extra_bits_len > 0) {
-            TEST_AND_RETURN_FALSE_SET_ERROR(
-                bw->WriteBits(extra_bits_len, len - kLengthBases[index]),
-                Error::kInsufficientInput);
+            TEST_AND_RETURN_FALSE(
+                bw->WriteBits(extra_bits_len, len - kLengthBases[index]));
           }
 
           // Same as above (binary search).
@@ -171,17 +150,13 @@
           }
           extra_bits_len = kDistanceExtraBits[index];
           uint16_t distance_huffman;
-          TEST_AND_RETURN_FALSE_SET_ERROR(
-              cur_ht->DistanceHuffman(index, &distance_huffman, &nbits),
-              Error::kInvalidInput);
+          TEST_AND_RETURN_FALSE(
+              cur_ht->DistanceHuffman(index, &distance_huffman, &nbits));
 
-          TEST_AND_RETURN_FALSE_SET_ERROR(
-              bw->WriteBits(nbits, distance_huffman),
-              Error::kInsufficientInput);
+          TEST_AND_RETURN_FALSE(bw->WriteBits(nbits, distance_huffman));
           if (extra_bits_len > 0) {
-            TEST_AND_RETURN_FALSE_SET_ERROR(
-                bw->WriteBits(extra_bits_len, dist - kDistanceBases[index]),
-                Error::kInsufficientInput);
+            TEST_AND_RETURN_FALSE(
+                bw->WriteBits(extra_bits_len, dist - kDistanceBases[index]));
           }
           break;
         }
@@ -189,28 +164,24 @@
         case PuffData::Type::kEndOfBlock: {
           uint16_t eos_huffman;
           size_t nbits;
-          TEST_AND_RETURN_FALSE_SET_ERROR(
-              cur_ht->LitLenHuffman(256, &eos_huffman, &nbits),
-              Error::kInvalidInput);
-          TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(nbits, eos_huffman),
-                                          Error::kInsufficientInput);
+          TEST_AND_RETURN_FALSE(
+              cur_ht->LitLenHuffman(256, &eos_huffman, &nbits));
+          TEST_AND_RETURN_FALSE(bw->WriteBits(nbits, eos_huffman));
           block_ended = true;
           break;
         }
         case PuffData::Type::kBlockMetadata:
           LOG(ERROR) << "Not expecing a metadata!";
-          *error = Error::kInvalidInput;
           return false;
 
         default:
           LOG(ERROR) << "Invalid block data type!";
-          *error = Error::kInvalidInput;
           return false;
       }
     }
   }
 
-  TEST_AND_RETURN_FALSE_SET_ERROR(bw->Flush(), Error::kInsufficientOutput);
+  TEST_AND_RETURN_FALSE(bw->Flush());
   return true;
 }
 
diff --git a/src/huffman_table.cc b/src/huffman_table.cc
index 6e711c6..1aeaa45 100644
--- a/src/huffman_table.cc
+++ b/src/huffman_table.cc
@@ -7,40 +7,38 @@
 #include <algorithm>
 #include <vector>
 
-#include "puffin/src/include/puffin/errors.h"
-#include "puffin/src/set_errors.h"
+#include "puffin/src/logging.h"
 
 namespace puffin {
 
-// clang-format off
 // Permutations of input Huffman code lengths (used only to read code lengths
 // necessary for reading Huffman table.)
-const uint8_t kPermutations[19] = {
-  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+const uint8_t kPermutations[19] = {16, 17, 18, 0, 8,  7, 9,  6, 10, 5,
+                                   11, 4,  12, 3, 13, 2, 14, 1, 15};
 
 // The bases of each alphabet which is added to the integer value of extra
 // bits that comes after the Huffman code in the input to create the given
 // length value. The last element is a guard.
 const uint16_t kLengthBases[30] = {
-  3,  4,  5,  6,  7,  8,  9,  10, 11,  13,  15,  17,  19,  23,  27, 31, 35, 43,
-  51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0xFFFF};
+    3,  4,  5,  6,  7,  8,  9,  10, 11,  13,  15,  17,  19,  23,  27,
+    31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0xFFFF};
 
 // Number of extra bits that comes after the associating Huffman code.
-const uint8_t kLengthExtraBits[29] = {
-  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5,
-  5, 5, 0};
+const uint8_t kLengthExtraBits[29] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+                                      1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+                                      4, 4, 4, 4, 5, 5, 5, 5, 0};
 
 // Same as |kLengthBases| but for the distances instead of lengths. The last
 // element is a guard.
 const uint16_t kDistanceBases[31] = {
-  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769,
-  1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0xFFFF};
+    1,    2,    3,    4,    5,    7,     9,     13,    17,    25,   33,
+    49,   65,   97,   129,  193,  257,   385,   513,   769,   1025, 1537,
+    2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0xFFFF};
 
 // Same as |kLengthExtraBits| but for distances instead of lengths.
-const uint8_t kDistanceExtraBits[30] = {
-  0, 0, 0,  0,  1,  1,  2,  2,  3,  3,  4, 4, 5,  5,  6,  6,  7,  7,  8,  8, 9,
-  9, 10, 10, 11, 11, 12, 12, 13, 13};
-// clang-format on
+const uint8_t kDistanceExtraBits[30] = {0, 0, 0,  0,  1,  1,  2,  2,  3,  3,
+                                        4, 4, 5,  5,  6,  6,  7,  7,  8,  8,
+                                        9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
 
 // 288 is the maximum number of needed huffman codes for an alphabet. Fixed
 // huffman table needs 288 and dynamic huffman table needs maximum 286.
@@ -111,8 +109,7 @@
                                      size_t* max_bits) {
   TEST_AND_RETURN_FALSE(InitHuffmanCodes(lens, max_bits));
   // Sort descending based on the bit-length of the code.
-  std::sort(codeindexpairs_.begin(),
-            codeindexpairs_.end(),
+  std::sort(codeindexpairs_.begin(), codeindexpairs_.end(),
             [&lens](const CodeIndexPair& a, const CodeIndexPair& b) {
               return lens[a.index] > lens[b.index];
             });
@@ -139,8 +136,7 @@
                                             size_t* max_bits) {
   TEST_AND_RETURN_FALSE(InitHuffmanCodes(lens, max_bits));
   // Sort ascending based on the index.
-  std::sort(codeindexpairs_.begin(),
-            codeindexpairs_.end(),
+  std::sort(codeindexpairs_.begin(), codeindexpairs_.end(),
             [](const CodeIndexPair& a, const CodeIndexPair& b) -> bool {
               return a.index < b.index;
             });
@@ -193,8 +189,8 @@
     TEST_AND_RETURN_FALSE(
         BuildHuffmanCodes(lit_len_lens_, &lit_len_hcodes_, &lit_len_max_bits_));
 
-    TEST_AND_RETURN_FALSE(BuildHuffmanCodes(
-        distance_lens_, &distance_hcodes_, &distance_max_bits_));
+    TEST_AND_RETURN_FALSE(BuildHuffmanCodes(distance_lens_, &distance_hcodes_,
+                                            &distance_max_bits_));
 
     TEST_AND_RETURN_FALSE(BuildHuffmanReverseCodes(
         lit_len_lens_, &lit_len_rcodes_, &lit_len_max_bits_));
@@ -209,8 +205,7 @@
 
 bool HuffmanTable::BuildDynamicHuffmanTable(BitReaderInterface* br,
                                             uint8_t* buffer,
-                                            size_t* length,
-                                            Error* error) {
+                                            size_t* length) {
   // Initilize only once and reuse.
   if (!initialized_) {
     // Only resizing the arrays needed.
@@ -240,9 +235,9 @@
   // |dynamic_lit_len_lens_| and |dynamic_distance_lens_|. Then it follows by
   // reading |dynamic_code_lens_|.
 
-  TEST_AND_RETURN_FALSE_SET_ERROR(*length >= 3, Error::kInsufficientOutput);
+  TEST_AND_RETURN_FALSE(*length >= 3);
   size_t index = 0;
-  TEST_AND_RETURN_FALSE_SET_ERROR(br->CacheBits(14), Error::kInsufficientInput);
+  TEST_AND_RETURN_FALSE(br->CacheBits(14));
   buffer[index++] = br->ReadBits(5);  // HLIST
   auto num_lit_len = br->ReadBits(5) + 257;
   br->DropBits(5);
@@ -255,18 +250,15 @@
   auto num_codes = br->ReadBits(4) + 4;
   br->DropBits(4);
 
-  TEST_AND_RETURN_FALSE_SET_ERROR(
-      CheckHuffmanArrayLengths(num_lit_len, num_distance, num_codes),
-      Error::kInvalidInput);
+  TEST_AND_RETURN_FALSE(
+      CheckHuffmanArrayLengths(num_lit_len, num_distance, num_codes));
 
   bool checked = false;
   size_t idx = 0;
-  TEST_AND_RETURN_FALSE_SET_ERROR(*length - index >= (num_codes + 1) / 2,
-                                  Error::kInsufficientOutput);
+  TEST_AND_RETURN_FALSE(*length - index >= (num_codes + 1) / 2);
   // Two codes per byte
   for (; idx < num_codes; idx++) {
-    TEST_AND_RETURN_FALSE_SET_ERROR(br->CacheBits(3),
-                                    Error::kInsufficientInput);
+    TEST_AND_RETURN_FALSE(br->CacheBits(3));
     code_lens_[kPermutations[idx]] = br->ReadBits(3);
     if (checked) {
       buffer[index++] |= br->ReadBits(3);
@@ -284,16 +276,15 @@
     code_lens_[kPermutations[idx]] = 0;
   }
 
-  TEST_AND_RETURN_FALSE_SET_ERROR(
-      BuildHuffmanCodes(code_lens_, &code_hcodes_, &code_max_bits_),
-      Error::kInvalidInput);
+  TEST_AND_RETURN_FALSE(
+      BuildHuffmanCodes(code_lens_, &code_hcodes_, &code_max_bits_));
 
   // Build literals/lengths and distance Huffman code length arrays.
   auto bytes_available = (*length - index);
   tmp_lens_.clear();
   TEST_AND_RETURN_FALSE(BuildHuffmanCodeLengths(
       br, buffer + index, &bytes_available, code_max_bits_,
-      num_lit_len + num_distance, &tmp_lens_, error));
+      num_lit_len + num_distance, &tmp_lens_));
   index += bytes_available;
 
   // TODO(ahassani): Optimize this so the memcpy is not needed anymore.
@@ -305,14 +296,12 @@
   distance_lens_.insert(distance_lens_.begin(), tmp_lens_.begin() + num_lit_len,
                         tmp_lens_.end());
 
-  TEST_AND_RETURN_FALSE_SET_ERROR(
-      BuildHuffmanCodes(lit_len_lens_, &lit_len_hcodes_, &lit_len_max_bits_),
-      Error::kInvalidInput);
+  TEST_AND_RETURN_FALSE(
+      BuildHuffmanCodes(lit_len_lens_, &lit_len_hcodes_, &lit_len_max_bits_));
 
   // Build distance Huffman codes.
-  TEST_AND_RETURN_FALSE_SET_ERROR(
-      BuildHuffmanCodes(distance_lens_, &distance_hcodes_, &distance_max_bits_),
-      Error::kInvalidInput);
+  TEST_AND_RETURN_FALSE(BuildHuffmanCodes(distance_lens_, &distance_hcodes_,
+                                          &distance_max_bits_));
 
   *length = index;
   return true;
@@ -323,34 +312,29 @@
                                            size_t* length,
                                            size_t max_bits,
                                            size_t num_codes,
-                                           Buffer* lens,
-                                           Error* error) {
+                                           Buffer* lens) {
   size_t index = 0;
   lens->clear();
   for (size_t idx = 0; idx < num_codes;) {
-    TEST_AND_RETURN_FALSE_SET_ERROR(br->CacheBits(max_bits),
-                                    Error::kInsufficientInput);
+    TEST_AND_RETURN_FALSE(br->CacheBits(max_bits));
     auto bits = br->ReadBits(max_bits);
     uint16_t code;
     size_t nbits;
-    TEST_AND_RETURN_FALSE_SET_ERROR(CodeAlphabet(bits, &code, &nbits),
-                                    Error::kInvalidInput);
-    TEST_AND_RETURN_FALSE_SET_ERROR(index < *length,
-                                    Error::kInsufficientOutput);
+    TEST_AND_RETURN_FALSE(CodeAlphabet(bits, &code, &nbits));
+    TEST_AND_RETURN_FALSE(index < *length);
     br->DropBits(nbits);
     if (code < 16) {
       buffer[index++] = code;
       lens->push_back(code);
       idx++;
     } else {
-      TEST_AND_RETURN_FALSE_SET_ERROR(code < 19, Error::kInvalidInput);
+      TEST_AND_RETURN_FALSE(code < 19);
       size_t copy_num = 0;
       uint8_t copy_val;
       switch (code) {
         case 16:
-          TEST_AND_RETURN_FALSE_SET_ERROR(idx != 0, Error::kInvalidInput);
-          TEST_AND_RETURN_FALSE_SET_ERROR(br->CacheBits(2),
-                                          Error::kInsufficientInput);
+          TEST_AND_RETURN_FALSE(idx != 0);
+          TEST_AND_RETURN_FALSE(br->CacheBits(2));
           copy_num = 3 + br->ReadBits(2);
           buffer[index++] = 16 + br->ReadBits(2);  // 3 - 6 times
           copy_val = (*lens)[idx - 1];
@@ -358,8 +342,7 @@
           break;
 
         case 17:
-          TEST_AND_RETURN_FALSE_SET_ERROR(br->CacheBits(3),
-                                          Error::kInsufficientInput);
+          TEST_AND_RETURN_FALSE(br->CacheBits(3));
           copy_num = 3 + br->ReadBits(3);
           buffer[index++] = 20 + br->ReadBits(3);  // 3 - 10 times
           copy_val = 0;
@@ -367,8 +350,7 @@
           break;
 
         case 18:
-          TEST_AND_RETURN_FALSE_SET_ERROR(br->CacheBits(7),
-                                          Error::kInsufficientInput);
+          TEST_AND_RETURN_FALSE(br->CacheBits(7));
           copy_num = 11 + br->ReadBits(7);
           buffer[index++] = 28 + br->ReadBits(7);  // 11 - 138 times
           copy_val = 0;
@@ -377,9 +359,7 @@
 
         default:
           LOG(ERROR) << "Invalid code!";
-          *error = Error::kInvalidInput;
           return false;
-          break;
       }
       idx += copy_num;
       while (copy_num--) {
@@ -394,8 +374,7 @@
 
 bool HuffmanTable::BuildDynamicHuffmanTable(const uint8_t* buffer,
                                             size_t length,
-                                            BitWriterInterface* bw,
-                                            Error* error) {
+                                            BitWriterInterface* bw) {
   if (!initialized_) {
     // Only resizing the arrays needed.
     code_lens_.resize(19);
@@ -412,27 +391,22 @@
     initialized_ = true;
   }
 
-  TEST_AND_RETURN_FALSE_SET_ERROR(length >= 3, Error::kInsufficientInput);
+  TEST_AND_RETURN_FALSE(length >= 3);
   size_t index = 0;
   // Write the header.
   size_t num_lit_len = buffer[index] + 257;
-  TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(5, buffer[index++]),
-                                  Error::kInsufficientOutput);
+  TEST_AND_RETURN_FALSE(bw->WriteBits(5, buffer[index++]));
 
   size_t num_distance = buffer[index] + 1;
-  TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(5, buffer[index++]),
-                                  Error::kInsufficientOutput);
+  TEST_AND_RETURN_FALSE(bw->WriteBits(5, buffer[index++]));
 
   size_t num_codes = buffer[index] + 4;
-  TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(4, buffer[index++]),
-                                  Error::kInsufficientOutput);
+  TEST_AND_RETURN_FALSE(bw->WriteBits(4, buffer[index++]));
 
-  TEST_AND_RETURN_FALSE_SET_ERROR(
-      CheckHuffmanArrayLengths(num_lit_len, num_distance, num_codes),
-      Error::kInvalidInput);
+  TEST_AND_RETURN_FALSE(
+      CheckHuffmanArrayLengths(num_lit_len, num_distance, num_codes));
 
-  TEST_AND_RETURN_FALSE_SET_ERROR(length - index >= (num_codes + 1) / 2,
-                                  Error::kInsufficientInput);
+  TEST_AND_RETURN_FALSE(length - index >= (num_codes + 1) / 2);
   bool checked = false;
   size_t idx = 0;
   for (; idx < num_codes; idx++) {
@@ -444,8 +418,7 @@
     }
     checked = !checked;
     code_lens_[kPermutations[idx]] = len;
-    TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(3, len),
-                                    Error::kInsufficientOutput);
+    TEST_AND_RETURN_FALSE(bw->WriteBits(3, len));
   }
   if (checked) {
     index++;
@@ -454,15 +427,14 @@
     code_lens_[kPermutations[idx]] = 0;
   }
 
-  TEST_AND_RETURN_FALSE_SET_ERROR(
-      BuildHuffmanReverseCodes(code_lens_, &code_rcodes_, &code_max_bits_),
-      Error::kInvalidInput);
+  TEST_AND_RETURN_FALSE(
+      BuildHuffmanReverseCodes(code_lens_, &code_rcodes_, &code_max_bits_));
 
   // Build literal/lengths and distance Huffman code length arrays.
   auto bytes_available = length - index;
   TEST_AND_RETURN_FALSE(
       BuildHuffmanCodeLengths(buffer + index, &bytes_available, bw,
-                              num_lit_len + num_distance, &tmp_lens_, error));
+                              num_lit_len + num_distance, &tmp_lens_));
   index += bytes_available;
 
   lit_len_lens_.clear();
@@ -474,18 +446,14 @@
                         tmp_lens_.end());
 
   // Build literal/lengths Huffman reverse codes.
-  TEST_AND_RETURN_FALSE_SET_ERROR(
-      BuildHuffmanReverseCodes(
-          lit_len_lens_, &lit_len_rcodes_, &lit_len_max_bits_),
-      Error::kInvalidInput);
+  TEST_AND_RETURN_FALSE(BuildHuffmanReverseCodes(
+      lit_len_lens_, &lit_len_rcodes_, &lit_len_max_bits_));
 
   // Build distance Huffman reverse codes.
-  TEST_AND_RETURN_FALSE_SET_ERROR(
-      BuildHuffmanReverseCodes(
-          distance_lens_, &distance_rcodes_, &distance_max_bits_),
-      Error::kInvalidInput);
+  TEST_AND_RETURN_FALSE(BuildHuffmanReverseCodes(
+      distance_lens_, &distance_rcodes_, &distance_max_bits_));
 
-  TEST_AND_RETURN_FALSE_SET_ERROR(length == index, Error::kInvalidInput);
+  TEST_AND_RETURN_FALSE(length == index);
 
   return true;
 }
@@ -494,22 +462,19 @@
                                            size_t* length,
                                            BitWriterInterface* bw,
                                            size_t num_codes,
-                                           Buffer* lens,
-                                           Error* error) {
+                                           Buffer* lens) {
   lens->clear();
   uint16_t hcode;
   size_t nbits;
   size_t index = 0;
   for (size_t idx = 0; idx < num_codes;) {
-    TEST_AND_RETURN_FALSE_SET_ERROR(index < *length, Error::kInsufficientInput);
+    TEST_AND_RETURN_FALSE(index < *length);
     auto pcode = buffer[index++];
-    TEST_AND_RETURN_FALSE_SET_ERROR(pcode <= 155, Error::kInvalidInput);
+    TEST_AND_RETURN_FALSE(pcode <= 155);
 
     auto code = pcode < 16 ? pcode : pcode < 20 ? 16 : pcode < 28 ? 17 : 18;
-    TEST_AND_RETURN_FALSE_SET_ERROR(CodeHuffman(code, &hcode, &nbits),
-                                    Error::kInvalidInput);
-    TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(nbits, hcode),
-                                    Error::kInsufficientOutput);
+    TEST_AND_RETURN_FALSE(CodeHuffman(code, &hcode, &nbits));
+    TEST_AND_RETURN_FALSE(bw->WriteBits(nbits, hcode));
     if (code < 16) {
       lens->push_back(code);
       idx++;
@@ -519,23 +484,20 @@
       switch (code) {
         case 16:
           // Cannot repeat a non-existent last code if idx == 0.
-          TEST_AND_RETURN_FALSE_SET_ERROR(idx != 0, Error::kInvalidInput);
-          TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(2, pcode - 16),
-                                          Error::kInsufficientOutput);
+          TEST_AND_RETURN_FALSE(idx != 0);
+          TEST_AND_RETURN_FALSE(bw->WriteBits(2, pcode - 16));
           copy_num = 3 + pcode - 16;
           copy_val = (*lens)[idx - 1];
           break;
 
         case 17:
-          TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(3, pcode - 20),
-                                          Error::kInsufficientOutput);
+          TEST_AND_RETURN_FALSE(bw->WriteBits(3, pcode - 20));
           copy_num = 3 + pcode - 20;
           copy_val = 0;
           break;
 
         case 18:
-          TEST_AND_RETURN_FALSE_SET_ERROR(bw->WriteBits(7, pcode - 28),
-                                          Error::kInsufficientOutput);
+          TEST_AND_RETURN_FALSE(bw->WriteBits(7, pcode - 28));
           copy_num = 11 + pcode - 28;
           copy_val = 0;
           break;
diff --git a/src/huffman_table.h b/src/huffman_table.h
index b12e88b..e47f8cc 100644
--- a/src/huffman_table.h
+++ b/src/huffman_table.h
@@ -13,8 +13,7 @@
 #include "puffin/src/bit_reader.h"
 #include "puffin/src/bit_writer.h"
 #include "puffin/src/include/puffin/common.h"
-#include "puffin/src/include/puffin/errors.h"
-#include "puffin/src/set_errors.h"
+#include "puffin/src/logging.h"
 
 namespace puffin {
 
@@ -183,8 +182,7 @@
   //                   the |buffer|.
   bool BuildDynamicHuffmanTable(BitReaderInterface* br,
                                 uint8_t* buffer,
-                                size_t* length,
-                                Error* error);
+                                size_t* length);
 
   // This functions first reads the Huffman code length arrays from the input
   // puffed |buffer|, then builds both literal/length and distance Huffman code
@@ -195,11 +193,9 @@
   // |length| IN      The length available in the |buffer|.
   // |bw|     IN/OUT  The |BitWriterInterface| for writing into the deflate
   //                  stream.
-  // |error|  OUT     The error code.
   bool BuildDynamicHuffmanTable(const uint8_t* buffer,
                                 size_t length,
-                                BitWriterInterface* bw,
-                                Error* error);
+                                BitWriterInterface* bw);
 
  protected:
   // Initializes the Huffman codes from an array of lengths.
@@ -236,14 +232,12 @@
   // |max_bits|  IN      The maximum number of bits in the Huffman codes.
   // |num_codes| IN      The size of the Huffman code length array in the input.
   // |lens|      OUT     The resulting Huffman code length array.
-  // |error|     OUT     The error code.
   bool BuildHuffmanCodeLengths(BitReaderInterface* br,
                                uint8_t* buffer,
                                size_t* length,
                                size_t max_bits,
                                size_t num_codes,
-                               Buffer* lens,
-                               Error* error);
+                               Buffer* lens);
 
   // Similar to |BuildHuffmanCodeLengths| but for reading from puffed buffer and
   // writing into deflate stream.
@@ -255,13 +249,11 @@
   // |num_codes| IN      Number of Huffman code lengths to read from the
   //                     |buffer|.
   // |lens|      OUT     The Huffman code lengths array.
-  // |error|     OUT     The error code.
   bool BuildHuffmanCodeLengths(const uint8_t* buffer,
                                size_t* length,
                                BitWriterInterface* bw,
                                size_t num_codes,
-                               Buffer* lens,
-                               Error* error);
+                               Buffer* lens);
 
  private:
   // A utility struct used to create Huffman codes.
diff --git a/src/include/puffin/common.h b/src/include/puffin/common.h
index 527686f..4ead74d 100644
--- a/src/include/puffin/common.h
+++ b/src/include/puffin/common.h
@@ -28,6 +28,14 @@
 
 #endif  // USE_BRILLO
 
+#ifndef FALLTHROUGH_INTENDED
+#ifdef __clang__
+#define FALLTHROUGH_INTENDED [[clang::fallthrough]]
+#else
+#define FALLTHROUGH_INTENDED
+#endif  // __clang__
+#endif  // FALLTHROUGH_INTENDED
+
 namespace puffin {
 
 using Buffer = std::vector<uint8_t>;
diff --git a/src/include/puffin/errors.h b/src/include/puffin/errors.h
deleted file mode 100644
index 66a312f..0000000
--- a/src/include/puffin/errors.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2017 The Chromium OS 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 SRC_INCLUDE_PUFFIN_ERRORS_H_
-#define SRC_INCLUDE_PUFFIN_ERRORS_H_
-
-namespace puffin {
-
-// The types of the errors.
-enum class Error {
-  kSuccess = 0,
-  kInvalidInput,
-  kInsufficientInput,
-  kInsufficientOutput,
-  kStreamIO,
-};
-
-}  // namespace puffin
-
-#endif  // SRC_INCLUDE_PUFFIN_ERRORS_H_
diff --git a/src/include/puffin/huffer.h b/src/include/puffin/huffer.h
index f1da650..4e6e42f 100644
--- a/src/include/puffin/huffer.h
+++ b/src/include/puffin/huffer.h
@@ -9,7 +9,6 @@
 #include <memory>
 
 #include "puffin/common.h"
-#include "puffin/errors.h"
 
 namespace puffin {
 
@@ -24,9 +23,7 @@
 
   // Creates a deflate buffer from a puffed buffer. It is the reverse of
   // |PuffDeflate|.
-  bool HuffDeflate(PuffReaderInterface* pr,
-                   BitWriterInterface* bw,
-                   Error* error) const;
+  bool HuffDeflate(PuffReaderInterface* pr, BitWriterInterface* bw) const;
 
  private:
   std::unique_ptr<HuffmanTable> dyn_ht_;
diff --git a/src/include/puffin/puffdiff.h b/src/include/puffin/puffdiff.h
index 3836d03..434dac7 100644
--- a/src/include/puffin/puffdiff.h
+++ b/src/include/puffin/puffdiff.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "bsdiff/constants.h"
+
 #include "puffin/common.h"
 #include "puffin/stream.h"
 
@@ -19,6 +21,8 @@
 // |dst|          IN   Destination deflate stream.
 // |src_deflates| IN   Deflate locations in |src|.
 // |dst_deflates| IN   Deflate locations in |dst|.
+// |compressors|  IN   Compressors to use in the underlying bsdiff, e.g. bz2,
+//                     brotli.
 // |tmp_filepath| IN   A path to a temporary file. The caller has the
 //                     responsibility of unlinking the file after the call to
 //                     |PuffDiff| finishes.
@@ -27,11 +31,22 @@
               UniqueStreamPtr dst,
               const std::vector<BitExtent>& src_deflates,
               const std::vector<BitExtent>& dst_deflates,
+              const std::vector<bsdiff::CompressorType>& compressors,
               const std::string& tmp_filepath,
               Buffer* patch);
 
 // Similar to the function above, except that it accepts raw buffer rather than
 // stream.
+bool PuffDiff(const Buffer& src,
+              const Buffer& dst,
+              const std::vector<BitExtent>& src_deflates,
+              const std::vector<BitExtent>& dst_deflates,
+              const std::vector<bsdiff::CompressorType>& compressors,
+              const std::string& tmp_filepath,
+              Buffer* patch);
+
+// The default puffdiff function that uses both bz2 and brotli to compress the
+// patch data.
 PUFFIN_EXPORT
 bool PuffDiff(const Buffer& src,
               const Buffer& dst,
diff --git a/src/include/puffin/puffer.h b/src/include/puffin/puffer.h
index 8469abc..b9ff6bc 100644
--- a/src/include/puffin/puffer.h
+++ b/src/include/puffin/puffer.h
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "puffin/common.h"
-#include "puffin/errors.h"
 #include "puffin/stream.h"
 
 namespace puffin {
@@ -23,12 +22,18 @@
   Puffer();
   ~Puffer();
 
-  // Creates a puffed buffer from a deflate buffer. If |deflates| is not null,
-  // it will be populated with the location of subblocks in the input data.
+  // Creates a puffed buffer from a deflate buffer.
+  //
+  // If |deflates| is not null, it will be populated with the location of the
+  // subblocks in the input data. In addition, the uncompressed deflate blocks
+  // will be ignored and will not be added to the |deflates|. For this case to
+  // happen correctly, the |pw| should write into an empty/null buffer,
+  // otherwise the created puff stream, will not match the deflate stream. In
+  // addition, in this case, the function will return when it reaches a final
+  // deflate subblock.
   bool PuffDeflate(BitReaderInterface* br,
                    PuffWriterInterface* pw,
-                   std::vector<BitExtent>* deflates,
-                   Error* error) const;
+                   std::vector<BitExtent>* deflates) const;
 
  private:
   std::unique_ptr<HuffmanTable> dyn_ht_;
diff --git a/src/include/puffin/utils.h b/src/include/puffin/utils.h
index 4c81996..f8eddbb 100644
--- a/src/include/puffin/utils.h
+++ b/src/include/puffin/utils.h
@@ -13,10 +13,6 @@
 
 namespace puffin {
 
-// Counts the number of bytes in a list of |ByteExtent|s.
-PUFFIN_EXPORT
-uint64_t BytesInByteExtents(const std::vector<ByteExtent>& extents);
-
 // Converts an array of |ByteExtens| or |BitExtents| to a string. Each extent
 // has format "offset:length" and are comma separated.
 template <typename T>
@@ -29,32 +25,45 @@
   return str;
 }
 
-// Locates deflate locations for a zlib buffer |data|. It locates by removing
-// header and footer bytes from the zlib stream.
-bool LocateDeflatesInZlib(const Buffer& data,
-                          std::vector<ByteExtent>* deflate_blocks);
+// Locates deflates in a deflate stream |data| with estimated minimum length of
+// |size|. The data should start with a valid deflate stream otherwise, false is
+// returned. |virtual_offset| defines the offset the |data| starts in the
+// original deflate stream. It is used to calculate the location of deflates in
+// |deflates| based on the given offset. |compressed_size| is the size of the
+// input that was determined to have valid deflate blocks (including
+// uncompressed blocks). This function does not clear the content of |deflates|
+// and will append found deflates to the end of it.
+bool LocateDeflatesInDeflateStream(const uint8_t* data,
+                                   uint64_t size,
+                                   uint64_t virtual_offset,
+                                   std::vector<BitExtent>* deflates,
+                                   uint64_t* compressed_size);
 
-// Similar to the function above, except that it accepts the file path to the
-// source and a list of zlib blocks and returns the deflate addresses in bit
-// extents.
+// Locates deflates in a zlib buffer |data| by removing header and footer bytes
+// from the zlib stream.
+bool LocateDeflatesInZlib(const Buffer& data, std::vector<BitExtent>* deflates);
+
+// Uses the function above, to locate deflates (bit addressed) in a given file
+// |file_path| using the list of zlib blocks |zlibs|.
 PUFFIN_EXPORT
 bool LocateDeflatesInZlibBlocks(const std::string& file_path,
                                 const std::vector<ByteExtent>& zlibs,
                                 std::vector<BitExtent>* deflates);
 
-// Searches for deflate locations in a gzip file. The results are
-// saved in |deflate_blocks|.
-bool LocateDeflatesInGzip(const Buffer& data,
-                          std::vector<ByteExtent>* deflate_blocks);
+// Searches for deflate locations in a gzip stream. The results are saved in
+// |deflates|.
+bool LocateDeflatesInGzip(const Buffer& data, std::vector<BitExtent>* deflates);
 
-// Search for the deflates in a zip archive, and put the result in
-// |deflate_blocks|.
-bool LocateDeflatesInZipArchive(const Buffer& data,
-                                std::vector<ByteExtent>* deflate_blocks);
-
+// Search for the deflates in a zip archive, and put the result in |deflates|.
 PUFFIN_EXPORT
+bool LocateDeflatesInZipArchive(const Buffer& data,
+                                std::vector<BitExtent>* deflates);
+
 // Create a list of deflate subblock locations from the deflate blocks in a
 // zip archive.
+// TODO(ahassani): Remove this function once update_engine starts to use
+// LocateDeflatesInZipArchive()
+PUFFIN_EXPORT
 bool LocateDeflateSubBlocksInZipArchive(const Buffer& data,
                                         std::vector<BitExtent>* deflates);
 
@@ -74,6 +83,15 @@
                        std::vector<ByteExtent>* puffs,
                        uint64_t* out_puff_size);
 
+// Removes any BitExtents from both |extents1| and |extents2| if the data it
+// points to is found in both |extents1| and |extents2|. The order of the
+// remaining BitExtents is preserved.
+PUFFIN_EXPORT
+void RemoveEqualBitExtents(const Buffer& data1,
+                           const Buffer& data2,
+                           std::vector<BitExtent>* extents1,
+                           std::vector<BitExtent>* extents2);
+
 }  // namespace puffin
 
 #endif  // SRC_INCLUDE_PUFFIN_UTILS_H_
diff --git a/src/logging.h b/src/logging.h
new file mode 100644
index 0000000..b48fcd5
--- /dev/null
+++ b/src/logging.h
@@ -0,0 +1,30 @@
+// Copyright 2017 The Chromium OS 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 SRC_LOGGING_H_
+#define SRC_LOGGING_H_
+
+#ifdef USE_BRILLO
+#include "base/logging.h"
+#else
+#include "glog/logging.h"
+#endif
+
+#define TEST_AND_RETURN_FALSE(_x)   \
+  do {                              \
+    if (!(_x)) {                    \
+      LOG(ERROR) << #_x " failed."; \
+      return false;                 \
+    }                               \
+  } while (0)
+
+#define TEST_AND_RETURN_VALUE(_x, _v) \
+  do {                                \
+    if (!(_x)) {                      \
+      LOG(ERROR) << #_x " failed.";   \
+      return (_v);                    \
+    }                                 \
+  } while (0)
+
+#endif  // SRC_LOGGING_H_
diff --git a/src/main.cc b/src/main.cc
index c610764..12f823f 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -21,14 +21,13 @@
 #include "puffin/src/include/puffin/puffer.h"
 #include "puffin/src/include/puffin/puffpatch.h"
 #include "puffin/src/include/puffin/utils.h"
+#include "puffin/src/logging.h"
 #include "puffin/src/memory_stream.h"
 #include "puffin/src/puffin_stream.h"
-#include "puffin/src/set_errors.h"
 
 using puffin::BitExtent;
 using puffin::Buffer;
 using puffin::ByteExtent;
-using puffin::Error;
 using puffin::ExtentStream;
 using puffin::FileStream;
 using puffin::Huffer;
@@ -92,7 +91,7 @@
 bool LocateDeflatesBasedOnFileType(const UniqueStreamPtr& stream,
                                    const string& file_name,
                                    const string& file_type_to_override,
-                                   vector<ByteExtent>* deflates) {
+                                   vector<BitExtent>* deflates) {
   auto file_type = FileType::kUnknown;
 
   auto last_dot = file_name.find_last_of(".");
@@ -125,15 +124,13 @@
 
   uint64_t stream_size;
   TEST_AND_RETURN_FALSE(stream->GetSize(&stream_size));
-  if (file_type == FileType::kDeflate) {
-    // Assume the whole stream is a deflate block.
-    *deflates = {ByteExtent(0, stream_size)};
-    return true;
-  }
-
   Buffer data(stream_size);
   TEST_AND_RETURN_FALSE(stream->Read(data.data(), data.size()));
   switch (file_type) {
+    case FileType::kDeflate:
+      TEST_AND_RETURN_FALSE(puffin::LocateDeflatesInDeflateStream(
+          data.data(), data.size(), 0, deflates, nullptr));
+      break;
     case FileType::kZlib:
       TEST_AND_RETURN_FALSE(puffin::LocateDeflatesInZlib(data, deflates));
       break;
@@ -199,7 +196,7 @@
 #endif
 
 // Main entry point to the application.
-int main(int argc, char** argv) {
+bool Main(int argc, char** argv) {
 #ifdef USE_BRILLO
   SETUP_FLAGS;
   brillo::FlagHelper::Init(argc, argv, "Puffin tool");
@@ -208,9 +205,9 @@
   google::ParseCommandLineFlags(&argc, &argv, true);
 #endif
 
-  TEST_AND_RETURN_VALUE(!FLAGS_operation.empty(), -1);
-  TEST_AND_RETURN_VALUE(!FLAGS_src_file.empty(), -1);
-  TEST_AND_RETURN_VALUE(!FLAGS_dst_file.empty(), -1);
+  TEST_AND_RETURN_FALSE(!FLAGS_operation.empty());
+  TEST_AND_RETURN_FALSE(!FLAGS_src_file.empty());
+  TEST_AND_RETURN_FALSE(!FLAGS_dst_file.empty());
 
   auto src_deflates_byte = StringToExtents<ByteExtent>(FLAGS_src_deflates_byte);
   auto dst_deflates_byte = StringToExtents<ByteExtent>(FLAGS_dst_deflates_byte);
@@ -222,35 +219,31 @@
   auto dst_extents = StringToExtents<ByteExtent>(FLAGS_dst_extents);
 
   auto src_stream = FileStream::Open(FLAGS_src_file, true, false);
-  TEST_AND_RETURN_VALUE(src_stream, -1);
+  TEST_AND_RETURN_FALSE(src_stream);
   if (!src_extents.empty()) {
     src_stream =
         ExtentStream::CreateForRead(std::move(src_stream), src_extents);
-    TEST_AND_RETURN_VALUE(src_stream, -1);
+    TEST_AND_RETURN_FALSE(src_stream);
   }
 
   if (FLAGS_operation == "puff" || FLAGS_operation == "puffhuff") {
-    TEST_AND_RETURN_VALUE(
-        LocateDeflatesBasedOnFileType(src_stream, FLAGS_src_file,
-                                      FLAGS_src_file_type, &src_deflates_byte),
-        -1);
+    TEST_AND_RETURN_FALSE(LocateDeflatesBasedOnFileType(
+        src_stream, FLAGS_src_file, FLAGS_src_file_type, &src_deflates_bit));
 
     if (src_deflates_bit.empty() && src_deflates_byte.empty()) {
       LOG(WARNING) << "You should pass source deflates, is this intentional?";
     }
     if (src_deflates_bit.empty()) {
-      TEST_AND_RETURN_VALUE(FindDeflateSubBlocks(src_stream, src_deflates_byte,
-                                                 &src_deflates_bit),
-                            -1);
+      TEST_AND_RETURN_FALSE(FindDeflateSubBlocks(src_stream, src_deflates_byte,
+                                                 &src_deflates_bit));
     }
-    TEST_AND_RETURN_VALUE(dst_puffs.empty(), -1);
+    TEST_AND_RETURN_FALSE(dst_puffs.empty());
     uint64_t dst_puff_size;
-    TEST_AND_RETURN_VALUE(FindPuffLocations(src_stream, src_deflates_bit,
-                                            &dst_puffs, &dst_puff_size),
-                          -1);
+    TEST_AND_RETURN_FALSE(FindPuffLocations(src_stream, src_deflates_bit,
+                                            &dst_puffs, &dst_puff_size));
 
     auto dst_stream = FileStream::Open(FLAGS_dst_file, false, true);
-    TEST_AND_RETURN_VALUE(dst_stream, -1);
+    TEST_AND_RETURN_FALSE(dst_stream);
     auto puffer = std::make_shared<Puffer>();
     auto reader =
         PuffinStream::CreateForPuff(std::move(src_stream), puffer,
@@ -266,8 +259,8 @@
     while (bytes_wrote < dst_puff_size) {
       auto write_size = std::min(static_cast<uint64_t>(buffer.size()),
                                  dst_puff_size - bytes_wrote);
-      TEST_AND_RETURN_VALUE(reader->Read(buffer.data(), write_size), -1);
-      TEST_AND_RETURN_VALUE(writer->Write(buffer.data(), write_size), -1);
+      TEST_AND_RETURN_FALSE(reader->Read(buffer.data(), write_size));
+      TEST_AND_RETURN_FALSE(writer->Write(buffer.data(), write_size));
       bytes_wrote += write_size;
     }
 
@@ -288,9 +281,8 @@
       while (bytes_read < dst_puff_size) {
         auto read_size = std::min(static_cast<uint64_t>(buffer.size()),
                                   dst_puff_size - bytes_read);
-        TEST_AND_RETURN_VALUE(read_puff_stream->Read(buffer.data(), read_size),
-                              -1);
-        TEST_AND_RETURN_VALUE(huff_writer->Write(buffer.data(), read_size), -1);
+        TEST_AND_RETURN_FALSE(read_puff_stream->Read(buffer.data(), read_size));
+        TEST_AND_RETURN_FALSE(huff_writer->Write(buffer.data(), read_size));
         bytes_read += read_size;
       }
     }
@@ -299,11 +291,11 @@
       LOG(WARNING) << "You should pass source puffs and destination deflates"
                    << ", is this intentional?";
     }
-    TEST_AND_RETURN_VALUE(src_puffs.size() == dst_deflates_bit.size(), -1);
+    TEST_AND_RETURN_FALSE(src_puffs.size() == dst_deflates_bit.size());
     uint64_t src_stream_size;
-    TEST_AND_RETURN_VALUE(src_stream->GetSize(&src_stream_size), -1);
+    TEST_AND_RETURN_FALSE(src_stream->GetSize(&src_stream_size));
     auto dst_file = FileStream::Open(FLAGS_dst_file, false, true);
-    TEST_AND_RETURN_VALUE(dst_file, -1);
+    TEST_AND_RETURN_FALSE(dst_file);
 
     auto huffer = std::make_shared<Huffer>();
     auto dst_stream = PuffinStream::CreateForHuff(std::move(dst_file), huffer,
@@ -315,22 +307,18 @@
     while (bytes_read < src_stream_size) {
       auto read_size = std::min(static_cast<uint64_t>(buffer.size()),
                                 src_stream_size - bytes_read);
-      TEST_AND_RETURN_VALUE(src_stream->Read(buffer.data(), read_size), -1);
-      TEST_AND_RETURN_VALUE(dst_stream->Write(buffer.data(), read_size), -1);
+      TEST_AND_RETURN_FALSE(src_stream->Read(buffer.data(), read_size));
+      TEST_AND_RETURN_FALSE(dst_stream->Write(buffer.data(), read_size));
       bytes_read += read_size;
     }
   } else if (FLAGS_operation == "puffdiff") {
     auto dst_stream = FileStream::Open(FLAGS_dst_file, true, false);
-    TEST_AND_RETURN_VALUE(dst_stream, -1);
+    TEST_AND_RETURN_FALSE(dst_stream);
 
-    TEST_AND_RETURN_VALUE(
-        LocateDeflatesBasedOnFileType(src_stream, FLAGS_src_file,
-                                      FLAGS_src_file_type, &src_deflates_byte),
-        -1);
-    TEST_AND_RETURN_VALUE(
-        LocateDeflatesBasedOnFileType(dst_stream, FLAGS_dst_file,
-                                      FLAGS_dst_file_type, &dst_deflates_byte),
-        -1);
+    TEST_AND_RETURN_FALSE(LocateDeflatesBasedOnFileType(
+        src_stream, FLAGS_src_file, FLAGS_src_file_type, &src_deflates_bit));
+    TEST_AND_RETURN_FALSE(LocateDeflatesBasedOnFileType(
+        dst_stream, FLAGS_dst_file, FLAGS_dst_file_type, &dst_deflates_bit));
 
     if (src_deflates_bit.empty() && src_deflates_byte.empty()) {
       LOG(WARNING) << "You should pass source deflates, is this intentional?";
@@ -341,57 +329,54 @@
     if (!dst_extents.empty()) {
       dst_stream =
           ExtentStream::CreateForWrite(std::move(dst_stream), dst_extents);
-      TEST_AND_RETURN_VALUE(dst_stream, -1);
+      TEST_AND_RETURN_FALSE(dst_stream);
     }
 
     if (src_deflates_bit.empty()) {
-      TEST_AND_RETURN_VALUE(FindDeflateSubBlocks(src_stream, src_deflates_byte,
-                                                 &src_deflates_bit),
-                            -1);
+      TEST_AND_RETURN_FALSE(FindDeflateSubBlocks(src_stream, src_deflates_byte,
+                                                 &src_deflates_bit));
     }
 
     if (dst_deflates_bit.empty()) {
-      TEST_AND_RETURN_VALUE(FindDeflateSubBlocks(dst_stream, dst_deflates_byte,
-                                                 &dst_deflates_bit),
-                            -1);
+      TEST_AND_RETURN_FALSE(FindDeflateSubBlocks(dst_stream, dst_deflates_byte,
+                                                 &dst_deflates_bit));
     }
 
+    // TODO(xunchang) add flags to select the bsdiff compressors.
     Buffer puffdiff_delta;
-    TEST_AND_RETURN_VALUE(
-        puffin::PuffDiff(std::move(src_stream), std::move(dst_stream),
-                         src_deflates_bit, dst_deflates_bit, "/tmp/patch.tmp",
-                         &puffdiff_delta),
-        -1);
+    TEST_AND_RETURN_FALSE(puffin::PuffDiff(
+        std::move(src_stream), std::move(dst_stream), src_deflates_bit,
+        dst_deflates_bit,
+        {bsdiff::CompressorType::kBZ2, bsdiff::CompressorType::kBrotli},
+        "/tmp/patch.tmp", &puffdiff_delta));
     if (FLAGS_verbose) {
       LOG(INFO) << "patch_size: " << puffdiff_delta.size();
     }
     auto patch_stream = FileStream::Open(FLAGS_patch_file, false, true);
-    TEST_AND_RETURN_VALUE(patch_stream, -1);
-    TEST_AND_RETURN_VALUE(
-        patch_stream->Write(puffdiff_delta.data(), puffdiff_delta.size()), -1);
+    TEST_AND_RETURN_FALSE(patch_stream);
+    TEST_AND_RETURN_FALSE(
+        patch_stream->Write(puffdiff_delta.data(), puffdiff_delta.size()));
   } else if (FLAGS_operation == "puffpatch") {
     auto patch_stream = FileStream::Open(FLAGS_patch_file, true, false);
-    TEST_AND_RETURN_VALUE(patch_stream, -1);
+    TEST_AND_RETURN_FALSE(patch_stream);
     uint64_t patch_size;
-    TEST_AND_RETURN_VALUE(patch_stream->GetSize(&patch_size), -1);
+    TEST_AND_RETURN_FALSE(patch_stream->GetSize(&patch_size));
 
     Buffer puffdiff_delta(patch_size);
-    TEST_AND_RETURN_VALUE(
-        patch_stream->Read(puffdiff_delta.data(), puffdiff_delta.size()), -1);
+    TEST_AND_RETURN_FALSE(
+        patch_stream->Read(puffdiff_delta.data(), puffdiff_delta.size()));
     auto dst_stream = FileStream::Open(FLAGS_dst_file, false, true);
-    TEST_AND_RETURN_VALUE(dst_stream, -1);
+    TEST_AND_RETURN_FALSE(dst_stream);
     if (!dst_extents.empty()) {
       dst_stream =
           ExtentStream::CreateForWrite(std::move(dst_stream), dst_extents);
-      TEST_AND_RETURN_VALUE(dst_stream, -1);
+      TEST_AND_RETURN_FALSE(dst_stream);
     }
     // Apply the patch. Use 50MB cache, it should be enough for most of the
     // operations.
-    TEST_AND_RETURN_VALUE(
-        puffin::PuffPatch(std::move(src_stream), std::move(dst_stream),
-                          puffdiff_delta.data(), puffdiff_delta.size(),
-                          FLAGS_cache_size),  // max_cache_size
-        -1);
+    TEST_AND_RETURN_FALSE(puffin::PuffPatch(
+        std::move(src_stream), std::move(dst_stream), puffdiff_delta.data(),
+        puffdiff_delta.size(), FLAGS_cache_size));
   }
 
   if (FLAGS_verbose) {
@@ -408,5 +393,12 @@
     LOG(INFO) << "src_extents: " << puffin::ExtentsToString(src_extents);
     LOG(INFO) << "dst_extents: " << puffin::ExtentsToString(dst_extents);
   }
+  return true;
+}
+
+int main(int argc, char** argv) {
+  if (!Main(argc, argv)) {
+    return 1;
+  }
   return 0;
 }
diff --git a/src/memory_stream.cc b/src/memory_stream.cc
index 5f32a90..706f4a3 100644
--- a/src/memory_stream.cc
+++ b/src/memory_stream.cc
@@ -11,7 +11,7 @@
 #include <utility>
 
 #include "puffin/src/include/puffin/common.h"
-#include "puffin/src/set_errors.h"
+#include "puffin/src/logging.h"
 
 namespace puffin {
 
diff --git a/src/patching_unittest.cc b/src/patching_unittest.cc
index d6327cf..134f137 100644
--- a/src/patching_unittest.cc
+++ b/src/patching_unittest.cc
@@ -11,18 +11,122 @@
 #include "puffin/src/include/puffin/puffdiff.h"
 #include "puffin/src/include/puffin/puffpatch.h"
 #include "puffin/src/include/puffin/utils.h"
+#include "puffin/src/logging.h"
 #include "puffin/src/memory_stream.h"
 #include "puffin/src/puffin_stream.h"
-#include "puffin/src/sample_generator.h"
-#include "puffin/src/set_errors.h"
 #include "puffin/src/unittest_common.h"
 
 #define PRINT_SAMPLE 0  // Set to 1 if you want to print the generated samples.
 
+using std::string;
+using std::vector;
+
 namespace puffin {
 
-using std::vector;
-using std::string;
+namespace {
+
+#if PRINT_SAMPLE
+// Print an array into hex-format to the output. This can be used to create
+// static arrays for unit testing of the puffer/huffer.
+void PrintArray(const string& name, const Buffer& array) {
+  std::cout << "const Buffer " << name << " = {" << std::endl << " ";
+  for (size_t idx = 0; idx < array.size(); idx++) {
+    std::cout << " 0x" << std::hex << std::uppercase << std::setfill('0')
+              << std::setw(2) << uint(array[idx]);
+    if (idx == array.size() - 1) {
+      std::cout << std::dec << "};" << std::endl;
+      return;
+    }
+    std::cout << ",";
+    if ((idx + 1) % 12 == 0) {
+      std::cout << std::endl << " ";
+    }
+  }
+}
+#endif
+
+const Buffer kPatch1To2 = {
+    0x50, 0x55, 0x46, 0x31, 0x00, 0x00, 0x00, 0x51, 0x08, 0x01, 0x12, 0x27,
+    0x0A, 0x04, 0x08, 0x10, 0x10, 0x32, 0x0A, 0x04, 0x08, 0x50, 0x10, 0x0A,
+    0x0A, 0x04, 0x08, 0x60, 0x10, 0x12, 0x12, 0x04, 0x08, 0x10, 0x10, 0x58,
+    0x12, 0x04, 0x08, 0x78, 0x10, 0x28, 0x12, 0x05, 0x08, 0xA8, 0x01, 0x10,
+    0x38, 0x18, 0x1F, 0x1A, 0x24, 0x0A, 0x02, 0x10, 0x32, 0x0A, 0x04, 0x08,
+    0x48, 0x10, 0x50, 0x0A, 0x05, 0x08, 0x98, 0x01, 0x10, 0x12, 0x12, 0x02,
+    0x10, 0x58, 0x12, 0x04, 0x08, 0x70, 0x10, 0x58, 0x12, 0x05, 0x08, 0xC8,
+    0x01, 0x10, 0x38, 0x18, 0x21, 0x42, 0x53, 0x44, 0x46, 0x32, 0x01, 0x01,
+    0x01, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x42, 0x5A, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xD1,
+    0x20, 0xBB, 0x7E, 0x00, 0x00, 0x03, 0x60, 0x40, 0x78, 0x0E, 0x08, 0x00,
+    0x40, 0x00, 0x20, 0x00, 0x31, 0x06, 0x4C, 0x40, 0x92, 0x8F, 0x46, 0xA7,
+    0xA8, 0xE0, 0xF3, 0xD6, 0x21, 0x12, 0xF4, 0xBC, 0x43, 0x32, 0x1F, 0x17,
+    0x72, 0x45, 0x38, 0x50, 0x90, 0xD1, 0x20, 0xBB, 0x7E, 0x42, 0x5A, 0x68,
+    0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xF1, 0x20, 0x5F, 0x0D, 0x00,
+    0x00, 0x02, 0x41, 0x15, 0x42, 0x08, 0x20, 0x00, 0x40, 0x00, 0x00, 0x02,
+    0x40, 0x00, 0x20, 0x00, 0x22, 0x3D, 0x23, 0x10, 0x86, 0x03, 0x96, 0x54,
+    0x11, 0x16, 0x5F, 0x17, 0x72, 0x45, 0x38, 0x50, 0x90, 0xF1, 0x20, 0x5F,
+    0x0D, 0x42, 0x5A, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0x07,
+    0xD4, 0xCB, 0x6E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x20, 0x00,
+    0x21, 0x18, 0x46, 0x82, 0xEE, 0x48, 0xA7, 0x0A, 0x12, 0x00, 0xFA, 0x99,
+    0x6D, 0xC0};
+
+const Buffer kPatch2To1 = {
+    0x50, 0x55, 0x46, 0x31, 0x00, 0x00, 0x00, 0x51, 0x08, 0x01, 0x12, 0x24,
+    0x0A, 0x02, 0x10, 0x32, 0x0A, 0x04, 0x08, 0x48, 0x10, 0x50, 0x0A, 0x05,
+    0x08, 0x98, 0x01, 0x10, 0x12, 0x12, 0x02, 0x10, 0x58, 0x12, 0x04, 0x08,
+    0x70, 0x10, 0x58, 0x12, 0x05, 0x08, 0xC8, 0x01, 0x10, 0x38, 0x18, 0x21,
+    0x1A, 0x27, 0x0A, 0x04, 0x08, 0x10, 0x10, 0x32, 0x0A, 0x04, 0x08, 0x50,
+    0x10, 0x0A, 0x0A, 0x04, 0x08, 0x60, 0x10, 0x12, 0x12, 0x04, 0x08, 0x10,
+    0x10, 0x58, 0x12, 0x04, 0x08, 0x78, 0x10, 0x28, 0x12, 0x05, 0x08, 0xA8,
+    0x01, 0x10, 0x38, 0x18, 0x1F, 0x42, 0x53, 0x44, 0x46, 0x32, 0x01, 0x01,
+    0x01, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x42, 0x5A, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0x3D,
+    0xBD, 0x08, 0x91, 0x00, 0x00, 0x01, 0xE0, 0x40, 0x5C, 0x0A, 0x40, 0x00,
+    0x40, 0x00, 0x20, 0x00, 0x31, 0x0C, 0x08, 0x23, 0xD2, 0x34, 0xD1, 0xB1,
+    0x73, 0x60, 0x44, 0x54, 0xE4, 0xFC, 0x5D, 0xC9, 0x14, 0xE1, 0x42, 0x40,
+    0xF6, 0xF4, 0x22, 0x44, 0x42, 0x5A, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26,
+    0x53, 0x59, 0x41, 0x62, 0x2E, 0xF0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40,
+    0x20, 0x20, 0x00, 0x21, 0x00, 0x82, 0x83, 0x17, 0x72, 0x45, 0x38, 0x50,
+    0x90, 0x41, 0x62, 0x2E, 0xF0, 0x42, 0x5A, 0x68, 0x39, 0x31, 0x41, 0x59,
+    0x26, 0x53, 0x59, 0xE0, 0x20, 0x04, 0x57, 0x00, 0x00, 0x04, 0x76, 0x50,
+    0xE0, 0x00, 0x20, 0x00, 0x10, 0x00, 0x04, 0x00, 0x02, 0x00, 0x20, 0x00,
+    0x40, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x21, 0xA1, 0xA3, 0x10, 0x83, 0x26,
+    0x21, 0x5E, 0xB2, 0x69, 0xAC, 0x70, 0x60, 0x53, 0xC5, 0xDC, 0x91, 0x4E,
+    0x14, 0x24, 0x38, 0x08, 0x01, 0x15, 0xC0};
+
+const Buffer kPatch1ToEmpty = {
+    0x50, 0x55, 0x46, 0x31, 0x00, 0x00, 0x00, 0x2D, 0x08, 0x01, 0x12, 0x27,
+    0x0A, 0x04, 0x08, 0x10, 0x10, 0x32, 0x0A, 0x04, 0x08, 0x50, 0x10, 0x0A,
+    0x0A, 0x04, 0x08, 0x60, 0x10, 0x12, 0x12, 0x04, 0x08, 0x10, 0x10, 0x58,
+    0x12, 0x04, 0x08, 0x78, 0x10, 0x28, 0x12, 0x05, 0x08, 0xA8, 0x01, 0x10,
+    0x38, 0x18, 0x1F, 0x1A, 0x00, 0x42, 0x53, 0x44, 0x46, 0x32, 0x01, 0x01,
+    0x01, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x42, 0x5A, 0x68, 0x39, 0x17, 0x72, 0x45, 0x38, 0x50, 0x90, 0x00,
+    0x00, 0x00, 0x00, 0x42, 0x5A, 0x68, 0x39, 0x17, 0x72, 0x45, 0x38, 0x50,
+    0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x5A, 0x68, 0x39, 0x17, 0x72, 0x45,
+    0x38, 0x50, 0x90, 0x00, 0x00, 0x00, 0x00};
+
+const Buffer kPatch1ToNoDeflate = {
+    0x50, 0x55, 0x46, 0x31, 0x00, 0x00, 0x00, 0x2F, 0x08, 0x01, 0x12, 0x27,
+    0x0A, 0x04, 0x08, 0x10, 0x10, 0x32, 0x0A, 0x04, 0x08, 0x50, 0x10, 0x0A,
+    0x0A, 0x04, 0x08, 0x60, 0x10, 0x12, 0x12, 0x04, 0x08, 0x10, 0x10, 0x58,
+    0x12, 0x04, 0x08, 0x78, 0x10, 0x28, 0x12, 0x05, 0x08, 0xA8, 0x01, 0x10,
+    0x38, 0x18, 0x1F, 0x1A, 0x02, 0x18, 0x04, 0x42, 0x53, 0x44, 0x46, 0x32,
+    0x01, 0x01, 0x01, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x42, 0x5A, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53,
+    0x59, 0xBA, 0x8D, 0x7F, 0x2D, 0x00, 0x00, 0x00, 0x40, 0x00, 0x44, 0x08,
+    0x20, 0x00, 0x30, 0xCC, 0x09, 0x32, 0x54, 0x65, 0x38, 0xBB, 0x92, 0x29,
+    0xC2, 0x84, 0x85, 0xD4, 0x6B, 0xF9, 0x68, 0x42, 0x5A, 0x68, 0x39, 0x17,
+    0x72, 0x45, 0x38, 0x50, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x5A, 0x68,
+    0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xE7, 0xAA, 0xF1, 0xFC, 0x00,
+    0x00, 0x00, 0x70, 0x00, 0x00, 0x08, 0x01, 0x00, 0x20, 0x04, 0x20, 0x00,
+    0x21, 0x9A, 0x68, 0x33, 0x4D, 0x13, 0x3C, 0x5D, 0xC9, 0x14, 0xE1, 0x42,
+    0x43, 0x9E, 0xAB, 0xC7, 0xF0};
+
+}  // namespace
 
 void TestPatching(const Buffer& src_buf,
                   const Buffer& dst_buf,
@@ -33,45 +137,48 @@
   string patch_path;
   ASSERT_TRUE(MakeTempFile(&patch_path, nullptr));
   ScopedPathUnlinker scoped_unlinker(patch_path);
-  ASSERT_TRUE(PuffDiff(src_buf, dst_buf, src_deflates, dst_deflates, patch_path,
-                       &patch_out));
+  ASSERT_TRUE(PuffDiff(src_buf, dst_buf, src_deflates, dst_deflates,
+                       {bsdiff::CompressorType::kBZ2}, patch_path, &patch_out));
 
 #if PRINT_SAMPLE
-  sample_generator::PrintArray("kPatchXXXXX", patch_out);
+  PrintArray("kPatchXXXXX", patch_out);
 #endif
 
   EXPECT_EQ(patch_out, patch);
 
   auto src_stream = MemoryStream::CreateForRead(src_buf);
-  Buffer dst_buf_out;
+  Buffer dst_buf_out(dst_buf.size());
   auto dst_stream = MemoryStream::CreateForWrite(&dst_buf_out);
   ASSERT_TRUE(PuffPatch(std::move(src_stream), std::move(dst_stream),
                         patch.data(), patch.size()));
   EXPECT_EQ(dst_buf_out, dst_buf);
 }
 
-TEST(PatchingTest, Patching8To9Test) {
-  TestPatching(kDeflates8, kDeflates9, kSubblockDeflateExtents8,
-               kSubblockDeflateExtents9, kPatch8To9);
+TEST(PatchingTest, Patching1To2Test) {
+  TestPatching(kDeflatesSample1, kDeflatesSample2,
+               kSubblockDeflateExtentsSample1, kSubblockDeflateExtentsSample2,
+               kPatch1To2);
 }
 
-TEST(PatchingTest, Patching9To8Test) {
-  TestPatching(kDeflates9, kDeflates8, kSubblockDeflateExtents9,
-               kSubblockDeflateExtents8, kPatch9To8);
+TEST(PatchingTest, Patching2To1Test) {
+  TestPatching(kDeflatesSample2, kDeflatesSample1,
+               kSubblockDeflateExtentsSample2, kSubblockDeflateExtentsSample1,
+               kPatch2To1);
 }
 
-TEST(PatchingTest, Patching8ToEmptyTest) {
-  TestPatching(kDeflates8, {}, kSubblockDeflateExtents8, {}, kPatch8ToEmpty);
+TEST(PatchingTest, Patching1ToEmptyTest) {
+  TestPatching(kDeflatesSample1, {}, kSubblockDeflateExtentsSample1, {},
+               kPatch1ToEmpty);
 }
 
-TEST(PatchingTest, Patching8ToNoDeflateTest) {
-  TestPatching(kDeflates8, {11, 22, 33, 44}, kSubblockDeflateExtents8, {},
-               kPatch8ToNoDeflate);
+TEST(PatchingTest, Patching1ToNoDeflateTest) {
+  TestPatching(kDeflatesSample1, {11, 22, 33, 44},
+               kSubblockDeflateExtentsSample1, {}, kPatch1ToNoDeflate);
 }
 
 // TODO(ahassani): add tests for:
-//   TestPatchingEmptyTo9
-//   TestPatchingNoDeflateTo9
+//   TestPatchingEmptyTo2
+//   TestPatchingNoDeflateTo2
 
 // TODO(ahassani): Change tests data if you decided to compress the header of
 // the patch.
diff --git a/src/puff_io_unittest.cc b/src/puff_io_unittest.cc
index 64976bd..c1178cd 100644
--- a/src/puff_io_unittest.cc
+++ b/src/puff_io_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "gtest/gtest.h"
 
-#include "puffin/src/include/puffin/errors.h"
 #include "puffin/src/puff_reader.h"
 #include "puffin/src/puff_writer.h"
 #include "puffin/src/unittest_common.h"
@@ -15,16 +14,15 @@
 void TestLiteralLength(size_t length) {
   Buffer buf(length + 10);
   PuffData pd;
-  Error error;
 
   BufferPuffWriter pw(buf.data(), buf.size());
   // We need to insert a metadata otherwise it will fail.
   pd.type = PuffData::Type::kBlockMetadata;
   pd.length = 1;
-  ASSERT_TRUE(pw.Insert(pd, &error));
+  ASSERT_TRUE(pw.Insert(pd));
 
   BufferPuffReader pr(buf.data(), buf.size());
-  ASSERT_TRUE(pr.GetNext(&pd, &error));
+  ASSERT_TRUE(pr.GetNext(&pd));
   ASSERT_EQ(pd.type, PuffData::Type::kBlockMetadata);
   ASSERT_EQ(pd.length, 1);
 
@@ -35,15 +33,15 @@
     std::fill(buffer, buffer + count, 10);
     return true;
   };
-  ASSERT_TRUE(pw.Insert(pd, &error));
-  ASSERT_TRUE(pw.Flush(&error));
+  ASSERT_TRUE(pw.Insert(pd));
+  ASSERT_TRUE(pw.Flush());
 
   pd.type = PuffData::Type::kLenDist;
   pd.distance = 1;
   pd.length = 3;
-  ASSERT_TRUE(pw.Insert(pd, &error));
+  ASSERT_TRUE(pw.Insert(pd));
 
-  ASSERT_TRUE(pr.GetNext(&pd, &error));
+  ASSERT_TRUE(pr.GetNext(&pd));
   if (length == 0) {
     // If length is zero, then nothing should've been inserted.
     ASSERT_EQ(pd.type, PuffData::Type::kLenDist);
@@ -66,7 +64,6 @@
   BufferPuffReader pr(buf.data(), buf.size());
   BufferPuffWriter pw(buf.data(), buf.size());
   BufferPuffWriter epw(nullptr, 0);
-  Error error;
   uint8_t block = 123;
 
   {
@@ -75,14 +72,14 @@
     pd.block_metadata[0] = 0xCC;  // header
     memcpy(&pd.block_metadata[1], &block, sizeof(block));
     pd.length = sizeof(block) + 1;
-    ASSERT_TRUE(pw.Insert(pd, &error));
-    ASSERT_TRUE(epw.Insert(pd, &error));
-    ASSERT_TRUE(pw.Flush(&error));
-    ASSERT_TRUE(epw.Flush(&error));
+    ASSERT_TRUE(pw.Insert(pd));
+    ASSERT_TRUE(epw.Insert(pd));
+    ASSERT_TRUE(pw.Flush());
+    ASSERT_TRUE(epw.Flush());
   }
   {
     PuffData pd;
-    ASSERT_TRUE(pr.GetNext(&pd, &error));
+    ASSERT_TRUE(pr.GetNext(&pd));
     ASSERT_EQ(pd.type, PuffData::Type::kBlockMetadata);
     ASSERT_EQ(pd.length, sizeof(block) + 1);
     ASSERT_EQ(pd.block_metadata[0], 0xCC);
@@ -93,45 +90,45 @@
     pd.type = PuffData::Type::kLenDist;
     pd.distance = 321;
     pd.length = 3;
-    ASSERT_TRUE(pw.Insert(pd, &error));
-    ASSERT_TRUE(epw.Insert(pd, &error));
+    ASSERT_TRUE(pw.Insert(pd));
+    ASSERT_TRUE(epw.Insert(pd));
     pd.length = 127;
-    ASSERT_TRUE(pw.Insert(pd, &error));
-    ASSERT_TRUE(epw.Insert(pd, &error));
+    ASSERT_TRUE(pw.Insert(pd));
+    ASSERT_TRUE(epw.Insert(pd));
     pd.length = 258;
-    ASSERT_TRUE(pw.Insert(pd, &error));
-    ASSERT_TRUE(epw.Insert(pd, &error));
-    ASSERT_TRUE(pw.Flush(&error));
-    ASSERT_TRUE(epw.Flush(&error));
+    ASSERT_TRUE(pw.Insert(pd));
+    ASSERT_TRUE(epw.Insert(pd));
+    ASSERT_TRUE(pw.Flush());
+    ASSERT_TRUE(epw.Flush());
 
     pd.length = 259;
-    ASSERT_FALSE(pw.Insert(pd, &error));
-    ASSERT_FALSE(epw.Insert(pd, &error));
+    ASSERT_FALSE(pw.Insert(pd));
+    ASSERT_FALSE(epw.Insert(pd));
   }
   {
     PuffData pd;
-    ASSERT_TRUE(pr.GetNext(&pd, &error));
+    ASSERT_TRUE(pr.GetNext(&pd));
     ASSERT_EQ(pd.type, PuffData::Type::kLenDist);
     ASSERT_EQ(pd.distance, 321);
     ASSERT_EQ(pd.length, 3);
-    ASSERT_TRUE(pr.GetNext(&pd, &error));
+    ASSERT_TRUE(pr.GetNext(&pd));
     ASSERT_EQ(pd.type, PuffData::Type::kLenDist);
     ASSERT_EQ(pd.length, 127);
-    ASSERT_TRUE(pr.GetNext(&pd, &error));
+    ASSERT_TRUE(pr.GetNext(&pd));
     ASSERT_EQ(pd.type, PuffData::Type::kLenDist);
     ASSERT_EQ(pd.length, 258);
   }
   {
     PuffData pd;
     pd.type = PuffData::Type::kEndOfBlock;
-    ASSERT_TRUE(pw.Insert(pd, &error));
-    ASSERT_TRUE(epw.Insert(pd, &error));
-    ASSERT_TRUE(pw.Flush(&error));
-    ASSERT_TRUE(epw.Flush(&error));
+    ASSERT_TRUE(pw.Insert(pd));
+    ASSERT_TRUE(epw.Insert(pd));
+    ASSERT_TRUE(pw.Flush());
+    ASSERT_TRUE(epw.Flush());
   }
   {
     PuffData pd;
-    ASSERT_TRUE(pr.GetNext(&pd, &error));
+    ASSERT_TRUE(pr.GetNext(&pd));
     ASSERT_EQ(pd.type, PuffData::Type::kEndOfBlock);
   }
   {
@@ -141,14 +138,14 @@
     pd.block_metadata[0] = 0xCC;  // header
     memcpy(&pd.block_metadata[1], &block, sizeof(block));
     pd.length = sizeof(block) + 1;
-    ASSERT_TRUE(pw.Insert(pd, &error));
-    ASSERT_TRUE(epw.Insert(pd, &error));
-    ASSERT_TRUE(pw.Flush(&error));
-    ASSERT_TRUE(epw.Flush(&error));
+    ASSERT_TRUE(pw.Insert(pd));
+    ASSERT_TRUE(epw.Insert(pd));
+    ASSERT_TRUE(pw.Flush());
+    ASSERT_TRUE(epw.Flush());
   }
   {
     PuffData pd;
-    ASSERT_TRUE(pr.GetNext(&pd, &error));
+    ASSERT_TRUE(pr.GetNext(&pd));
     ASSERT_EQ(pd.type, PuffData::Type::kBlockMetadata);
     ASSERT_EQ(pd.length, sizeof(block) + 1);
     ASSERT_EQ(pd.block_metadata[0], 0xCC);
@@ -170,27 +167,27 @@
       index += count;
       return true;
     };
-    ASSERT_TRUE(pw.Insert(pd, &error));
-    ASSERT_TRUE(pw.Flush(&error));
+    ASSERT_TRUE(pw.Insert(pd));
+    ASSERT_TRUE(pw.Flush());
     // We have to refresh the read_fn function for the second insert.
     index = 0;
-    ASSERT_TRUE(epw.Insert(pd, &error));
-    ASSERT_TRUE(epw.Flush(&error));
+    ASSERT_TRUE(epw.Insert(pd));
+    ASSERT_TRUE(epw.Flush());
   }
   {
     PuffData pd;
     pd.type = PuffData::Type::kLiteral;
     pd.byte = 10;
-    ASSERT_TRUE(pw.Insert(pd, &error));
-    ASSERT_TRUE(epw.Insert(pd, &error));
-    ASSERT_TRUE(pw.Flush(&error));
-    ASSERT_TRUE(epw.Flush(&error));
+    ASSERT_TRUE(pw.Insert(pd));
+    ASSERT_TRUE(epw.Insert(pd));
+    ASSERT_TRUE(pw.Flush());
+    ASSERT_TRUE(epw.Flush());
   }
 
   uint8_t tmp3[3];
   {
     PuffData pd;
-    ASSERT_TRUE(pr.GetNext(&pd, &error));
+    ASSERT_TRUE(pr.GetNext(&pd));
     ASSERT_EQ(pd.type, PuffData::Type::kLiterals);
     ASSERT_EQ(pd.length, 3);
     ASSERT_TRUE(pd.read_fn(tmp3, 3));
@@ -199,7 +196,7 @@
   }
   {
     PuffData pd;
-    ASSERT_TRUE(pr.GetNext(&pd, &error));
+    ASSERT_TRUE(pr.GetNext(&pd));
     ASSERT_EQ(pd.type, PuffData::Type::kLiterals);
     ASSERT_EQ(pd.length, 1);
     ASSERT_TRUE(pd.read_fn(tmp3, 1));
@@ -209,14 +206,14 @@
   {
     PuffData pd;
     pd.type = PuffData::Type::kEndOfBlock;
-    ASSERT_TRUE(pw.Insert(pd, &error));
-    ASSERT_TRUE(epw.Insert(pd, &error));
-    ASSERT_TRUE(pw.Flush(&error));
-    ASSERT_TRUE(epw.Flush(&error));
+    ASSERT_TRUE(pw.Insert(pd));
+    ASSERT_TRUE(epw.Insert(pd));
+    ASSERT_TRUE(pw.Flush());
+    ASSERT_TRUE(epw.Flush());
   }
   {
     PuffData pd;
-    ASSERT_TRUE(pr.GetNext(&pd, &error));
+    ASSERT_TRUE(pr.GetNext(&pd));
     ASSERT_EQ(pd.type, PuffData::Type::kEndOfBlock);
   }
 
@@ -227,7 +224,6 @@
 // Testing metadata boundary.
 TEST(PuffIOTest, MetadataBoundaryTest) {
   PuffData pd;
-  Error error;
   Buffer buf(3);
   BufferPuffWriter pw(buf.data(), buf.size());
 
@@ -235,21 +231,19 @@
   // bytes is left for the varied part of metadata.
   pd.type = PuffData::Type::kBlockMetadata;
   pd.length = 2;
-  ASSERT_FALSE(pw.Insert(pd, &error));
-  ASSERT_EQ(error, Error::kInsufficientOutput);
+  ASSERT_FALSE(pw.Insert(pd));
   pd.length = 0;  // length should be at least 1.
-  ASSERT_FALSE(pw.Insert(pd, &error));
+  ASSERT_FALSE(pw.Insert(pd));
   pd.length = 1;
-  ASSERT_TRUE(pw.Insert(pd, &error));
+  ASSERT_TRUE(pw.Insert(pd));
 
   Buffer puff_buffer = {0x00, 0x03, 0x02, 0x00, 0x00};
   BufferPuffReader pr(puff_buffer.data(), puff_buffer.size());
-  ASSERT_FALSE(pr.GetNext(&pd, &error));
+  ASSERT_FALSE(pr.GetNext(&pd));
 }
 
 TEST(PuffIOTest, InvalidCopyLengthsDistanceTest) {
   PuffData pd;
-  Error error;
   Buffer puff_buffer(20);
   BufferPuffWriter pw(puff_buffer.data(), puff_buffer.size());
 
@@ -257,44 +251,43 @@
   pd.type = PuffData::Type::kLenDist;
   pd.distance = 1;
   pd.length = 0;
-  EXPECT_FALSE(pw.Insert(pd, &error));
+  EXPECT_FALSE(pw.Insert(pd));
   pd.length = 1;
-  EXPECT_FALSE(pw.Insert(pd, &error));
+  EXPECT_FALSE(pw.Insert(pd));
   pd.length = 2;
-  EXPECT_FALSE(pw.Insert(pd, &error));
+  EXPECT_FALSE(pw.Insert(pd));
   pd.length = 3;
-  EXPECT_TRUE(pw.Insert(pd, &error));
+  EXPECT_TRUE(pw.Insert(pd));
   pd.length = 259;
-  EXPECT_FALSE(pw.Insert(pd, &error));
+  EXPECT_FALSE(pw.Insert(pd));
   pd.length = 258;
-  EXPECT_TRUE(pw.Insert(pd, &error));
+  EXPECT_TRUE(pw.Insert(pd));
 
   // Invalid distance values.
   pd.length = 3;
   pd.distance = 0;
-  EXPECT_FALSE(pw.Insert(pd, &error));
+  EXPECT_FALSE(pw.Insert(pd));
   pd.distance = 1;
-  EXPECT_TRUE(pw.Insert(pd, &error));
+  EXPECT_TRUE(pw.Insert(pd));
   pd.distance = 32769;
-  EXPECT_FALSE(pw.Insert(pd, &error));
+  EXPECT_FALSE(pw.Insert(pd));
   pd.distance = 32768;
-  EXPECT_TRUE(pw.Insert(pd, &error));
+  EXPECT_TRUE(pw.Insert(pd));
 
   // First three bytes header, four bytes value lit/len, and four bytes
   // invalid lit/len.
   puff_buffer = {0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00,
                  0x00, 0xFF, 0x82, 0x00, 0x00};
   BufferPuffReader pr(puff_buffer.data(), puff_buffer.size());
-  EXPECT_TRUE(pr.GetNext(&pd, &error));
+  EXPECT_TRUE(pr.GetNext(&pd));
   EXPECT_EQ(pd.type, PuffData::Type::kBlockMetadata);
-  EXPECT_TRUE(pr.GetNext(&pd, &error));
+  EXPECT_TRUE(pr.GetNext(&pd));
   EXPECT_EQ(pd.type, PuffData::Type::kLenDist);
-  EXPECT_FALSE(pr.GetNext(&pd, &error));
+  EXPECT_FALSE(pr.GetNext(&pd));
 }
 
 TEST(PuffIOTest, InvalidCopyLenghtDistanceBoundaryTest) {
   PuffData pd;
-  Error error;
   Buffer puff_buffer(5);
 
   pd.type = PuffData::Type::kLenDist;
@@ -302,21 +295,21 @@
   pd.length = 129;
   for (size_t i = 1; i < 2; i++) {
     BufferPuffWriter pw(puff_buffer.data(), i);
-    EXPECT_FALSE(pw.Insert(pd, &error));
+    EXPECT_FALSE(pw.Insert(pd));
   }
 
   pd.length = 130;
   for (size_t i = 1; i < 3; i++) {
     BufferPuffWriter pw(puff_buffer.data(), i);
-    EXPECT_FALSE(pw.Insert(pd, &error));
+    EXPECT_FALSE(pw.Insert(pd));
   }
 
   // First three bytes header, three bytes value lit/len.
   puff_buffer = {0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00};
   BufferPuffReader pr(puff_buffer.data(), puff_buffer.size());
-  EXPECT_TRUE(pr.GetNext(&pd, &error));
+  EXPECT_TRUE(pr.GetNext(&pd));
   EXPECT_EQ(pd.type, PuffData::Type::kBlockMetadata);
-  EXPECT_FALSE(pr.GetNext(&pd, &error));
+  EXPECT_FALSE(pr.GetNext(&pd));
 }
 
 TEST(PuffIOTest, LiteralsTest) {
@@ -332,13 +325,12 @@
 TEST(PuffIOTest, MaxLiteralsTest) {
   Buffer buf((1 << 16) + 127 + 20);
   PuffData pd;
-  Error error;
 
   BufferPuffWriter pw(buf.data(), buf.size());
   // We need to insert a metadata otherwise it will fail.
   pd.type = PuffData::Type::kBlockMetadata;
   pd.length = 1;
-  ASSERT_TRUE(pw.Insert(pd, &error));
+  ASSERT_TRUE(pw.Insert(pd));
 
   pd.type = PuffData::Type::kLiterals;
   pd.length = (1 << 16);
@@ -346,15 +338,15 @@
     std::fill(buffer, buffer + count, 10);
     return true;
   };
-  ASSERT_TRUE(pw.Insert(pd, &error));
-  ASSERT_TRUE(pw.Flush(&error));
+  ASSERT_TRUE(pw.Insert(pd));
+  ASSERT_TRUE(pw.Flush());
 
   BufferPuffReader pr(buf.data(), buf.size());
-  ASSERT_TRUE(pr.GetNext(&pd, &error));
+  ASSERT_TRUE(pr.GetNext(&pd));
   ASSERT_EQ(pd.type, PuffData::Type::kBlockMetadata);
   ASSERT_EQ(pd.length, 1);
 
-  ASSERT_TRUE(pr.GetNext(&pd, &error));
+  ASSERT_TRUE(pr.GetNext(&pd));
   ASSERT_EQ(pd.type, PuffData::Type::kLiterals);
   ASSERT_EQ(pd.length, 1 << 16);
   for (size_t i = 0; i < pd.length; i++) {
@@ -366,28 +358,28 @@
   BufferPuffWriter pw2(buf.data(), buf.size());
   pd.type = PuffData::Type::kBlockMetadata;
   pd.length = 1;
-  ASSERT_TRUE(pw2.Insert(pd, &error));
+  ASSERT_TRUE(pw2.Insert(pd));
 
   pd.type = PuffData::Type::kLiteral;
   pd.length = 1;
   pd.byte = 12;
   // We have to be able to fill 65663 bytes.
   for (size_t i = 0; i < ((1 << 16) + 127); i++) {
-    ASSERT_TRUE(pw2.Insert(pd, &error));
+    ASSERT_TRUE(pw2.Insert(pd));
   }
   // If we add one more, then it should have been flushed.
   pd.byte = 13;
-  ASSERT_TRUE(pw2.Insert(pd, &error));
-  ASSERT_TRUE(pw2.Flush(&error));
+  ASSERT_TRUE(pw2.Insert(pd));
+  ASSERT_TRUE(pw2.Flush());
 
   // Now read it back.
   BufferPuffReader pr2(buf.data(), buf.size());
-  ASSERT_TRUE(pr2.GetNext(&pd, &error));
+  ASSERT_TRUE(pr2.GetNext(&pd));
   ASSERT_EQ(pd.type, PuffData::Type::kBlockMetadata);
 
   // Now we should read on kLiterals with lenght 1 << 16 and just one literal
   // after that.
-  ASSERT_TRUE(pr2.GetNext(&pd, &error));
+  ASSERT_TRUE(pr2.GetNext(&pd));
   ASSERT_EQ(pd.type, PuffData::Type::kLiterals);
   ASSERT_EQ(pd.length, (1 << 16) + 127);
   for (size_t i = 0; i < pd.length; i++) {
@@ -396,7 +388,7 @@
     ASSERT_EQ(byte, 12);
   }
 
-  ASSERT_TRUE(pr2.GetNext(&pd, &error));
+  ASSERT_TRUE(pr2.GetNext(&pd));
   ASSERT_EQ(pd.type, PuffData::Type::kLiterals);
   ASSERT_EQ(pd.length, 1);
   uint8_t byte;
diff --git a/src/puff_reader.cc b/src/puff_reader.cc
index 34ef5c3..fcf68fd 100644
--- a/src/puff_reader.cc
+++ b/src/puff_reader.cc
@@ -9,7 +9,7 @@
 #include <string>
 #include <vector>
 
-#include "puffin/src/set_errors.h"
+#include "puffin/src/logging.h"
 
 namespace puffin {
 
@@ -20,21 +20,19 @@
 }
 }  // namespace
 
-bool BufferPuffReader::GetNext(PuffData* data, Error* error) {
+bool BufferPuffReader::GetNext(PuffData* data) {
   PuffData& pd = *data;
   size_t length = 0;
   if (state_ == State::kReadingLenDist) {
     // Boundary check
-    TEST_AND_RETURN_FALSE_SET_ERROR(index_ < puff_size_,
-                                    Error::kInsufficientInput);
+    TEST_AND_RETURN_FALSE(index_ < puff_size_);
     if (puff_buf_in_[index_] & 0x80) {  // Reading length/distance.
       if ((puff_buf_in_[index_] & 0x7F) < 127) {
         length = puff_buf_in_[index_] & 0x7F;
       } else {
         index_++;
         // Boundary check
-        TEST_AND_RETURN_FALSE_SET_ERROR(index_ < puff_size_,
-                                        Error::kInsufficientInput);
+        TEST_AND_RETURN_FALSE(index_ < puff_size_);
         length = puff_buf_in_[index_] + 127;
       }
       length += 3;
@@ -52,13 +50,11 @@
       }
 
       // Boundary check
-      TEST_AND_RETURN_FALSE_SET_ERROR(index_ + 1 < puff_size_,
-                                      Error::kInsufficientInput);
+      TEST_AND_RETURN_FALSE(index_ + 1 < puff_size_);
       auto distance = ReadByteArrayToUint16(&puff_buf_in_[index_]);
       // The distance in RFC is in the range [1..32768], but in the puff spec,
       // we write zero-based distance in the puff stream.
-      TEST_AND_RETURN_FALSE_SET_ERROR(distance < (1 << 15),
-                                      Error::kInsufficientInput);
+      TEST_AND_RETURN_FALSE(distance < (1 << 15));
       distance++;
       index_ += 2;
 
@@ -69,24 +65,21 @@
       return true;
     } else {  // Reading literals.
       // Boundary check
-      TEST_AND_RETURN_FALSE_SET_ERROR(index_ < puff_size_,
-                                      Error::kInsufficientInput);
+      TEST_AND_RETURN_FALSE(index_ < puff_size_);
       if ((puff_buf_in_[index_] & 0x7F) < 127) {
         length = puff_buf_in_[index_] & 0x7F;
         index_++;
       } else {
         index_++;
         // Boundary check
-        TEST_AND_RETURN_FALSE_SET_ERROR(index_ + 1 < puff_size_,
-                                        Error::kInsufficientInput);
+        TEST_AND_RETURN_FALSE(index_ + 1 < puff_size_);
         length = ReadByteArrayToUint16(&puff_buf_in_[index_]) + 127;
         index_ += 2;
       }
       length++;
       DVLOG(2) << "Read literals length: " << length;
       // Boundary check
-      TEST_AND_RETURN_FALSE_SET_ERROR(index_ + length <= puff_size_,
-                                      Error::kInsufficientInput);
+      TEST_AND_RETURN_FALSE(index_ + length <= puff_size_);
       pd.type = PuffData::Type::kLiterals;
       pd.length = length;
       pd.read_fn = [this, length](uint8_t* buffer, size_t count) mutable {
@@ -101,14 +94,12 @@
   } else {  // Block metadata
     pd.type = PuffData::Type::kBlockMetadata;
     // Boundary check
-    TEST_AND_RETURN_FALSE_SET_ERROR(index_ + 2 < puff_size_,
-                                    Error::kInsufficientInput);
+    TEST_AND_RETURN_FALSE(index_ + 2 < puff_size_);
     length = ReadByteArrayToUint16(&puff_buf_in_[index_]) + 1;
     index_ += 2;
     DVLOG(2) << "Read block metadata length: " << length;
     // Boundary check
-    TEST_AND_RETURN_FALSE_SET_ERROR(index_ + length <= puff_size_,
-                                    Error::kInsufficientInput);
+    TEST_AND_RETURN_FALSE(index_ + length <= puff_size_);
     TEST_AND_RETURN_FALSE(length <= sizeof(pd.block_metadata));
     memcpy(pd.block_metadata, &puff_buf_in_[index_], length);
     index_ += length;
diff --git a/src/puff_reader.h b/src/puff_reader.h
index 3e6c4df..40e6bfb 100644
--- a/src/puff_reader.h
+++ b/src/puff_reader.h
@@ -9,7 +9,6 @@
 #include <cstdint>
 
 #include "puffin/src/include/puffin/common.h"
-#include "puffin/src/include/puffin/errors.h"
 #include "puffin/src/puff_data.h"
 
 namespace puffin {
@@ -26,8 +25,7 @@
   // data.
   //
   // |data|  OUT  The next data available in the puffed buffer.
-  // |error| OUT  The error code.
-  virtual bool GetNext(PuffData* data, Error* error) = 0;
+  virtual bool GetNext(PuffData* data) = 0;
 
   // Returns the number of bytes left in the puff buffer.
   virtual size_t BytesLeft() const = 0;
@@ -48,7 +46,7 @@
 
   ~BufferPuffReader() override = default;
 
-  bool GetNext(PuffData* pd, Error* error) override;
+  bool GetNext(PuffData* pd) override;
   size_t BytesLeft() const override;
 
  private:
diff --git a/src/puff_writer.cc b/src/puff_writer.cc
index f39dad9..e26c3be 100644
--- a/src/puff_writer.cc
+++ b/src/puff_writer.cc
@@ -9,7 +9,7 @@
 #include <string>
 #include <vector>
 
-#include "puffin/src/set_errors.h"
+#include "puffin/src/logging.h"
 
 namespace puffin {
 
@@ -24,13 +24,13 @@
 constexpr size_t kLiteralsMaxLength = (1 << 16) + 127;  // 65663
 }  // namespace
 
-bool BufferPuffWriter::Insert(const PuffData& pd, Error* error) {
+bool BufferPuffWriter::Insert(const PuffData& pd) {
   switch (pd.type) {
     case PuffData::Type::kLiterals:
       if (pd.length == 0) {
         return true;
       }
-    // We don't break here. It will be processed in kLiteral;
+      FALLTHROUGH_INTENDED;
     case PuffData::Type::kLiteral: {
       DVLOG(2) << "Write literals length: " << pd.length;
       size_t length = pd.type == PuffData::Type::kLiteral ? 1 : pd.length;
@@ -43,8 +43,7 @@
         if ((cur_literals_length_ + length) > 127) {
           if (puff_buf_out_ != nullptr) {
             // Boundary check
-            TEST_AND_RETURN_FALSE_SET_ERROR(index_ + 2 <= puff_size_,
-                                            Error::kInsufficientOutput);
+            TEST_AND_RETURN_FALSE(index_ + 2 <= puff_size_);
 
             // Shift two bytes forward to open space for length value.
             memmove(&puff_buf_out_[len_index_ + 3],
@@ -57,18 +56,14 @@
 
       if (puff_buf_out_ != nullptr) {
         // Boundary check
-        TEST_AND_RETURN_FALSE_SET_ERROR(index_ + length <= puff_size_,
-                                        Error::kInsufficientOutput);
+        TEST_AND_RETURN_FALSE(index_ + length <= puff_size_);
         if (pd.type == PuffData::Type::kLiteral) {
           puff_buf_out_[index_] = pd.byte;
         } else {
-          TEST_AND_RETURN_FALSE_SET_ERROR(
-              pd.read_fn(&puff_buf_out_[index_], length),
-              Error::kInsufficientInput);
+          TEST_AND_RETURN_FALSE(pd.read_fn(&puff_buf_out_[index_], length));
         }
       } else if (pd.type == PuffData::Type::kLiterals) {
-        TEST_AND_RETURN_FALSE_SET_ERROR(pd.read_fn(nullptr, length),
-                                        Error::kInsufficientInput);
+        TEST_AND_RETURN_FALSE(pd.read_fn(nullptr, length));
       }
 
       index_ += length;
@@ -78,22 +73,19 @@
       // have total length of more than 65663 bytes for a series of literals. So
       // we have to cap it at 65663 and continue afterwards.
       if (cur_literals_length_ == kLiteralsMaxLength) {
-        TEST_AND_RETURN_FALSE(FlushLiterals(error));
+        TEST_AND_RETURN_FALSE(FlushLiterals());
       }
       break;
     }
     case PuffData::Type::kLenDist:
       DVLOG(2) << "Write length: " << pd.length << " distance: " << pd.distance;
-      TEST_AND_RETURN_FALSE(FlushLiterals(error));
-      TEST_AND_RETURN_FALSE_SET_ERROR(pd.length <= 258 && pd.length >= 3,
-                                      Error::kInvalidInput);
-      TEST_AND_RETURN_FALSE_SET_ERROR(pd.distance <= 32768 && pd.distance >= 1,
-                                      Error::kInvalidInput);
+      TEST_AND_RETURN_FALSE(FlushLiterals());
+      TEST_AND_RETURN_FALSE(pd.length <= 258 && pd.length >= 3);
+      TEST_AND_RETURN_FALSE(pd.distance <= 32768 && pd.distance >= 1);
       if (pd.length < 130) {
         if (puff_buf_out_ != nullptr) {
           // Boundary check
-          TEST_AND_RETURN_FALSE_SET_ERROR(index_ + 3 <= puff_size_,
-                                          Error::kInsufficientOutput);
+          TEST_AND_RETURN_FALSE(index_ + 3 <= puff_size_);
 
           puff_buf_out_[index_++] =
               kLenDistHeader | static_cast<uint8_t>(pd.length - 3);
@@ -103,8 +95,7 @@
       } else {
         if (puff_buf_out_ != nullptr) {
           // Boundary check
-          TEST_AND_RETURN_FALSE_SET_ERROR(index_ + 4 <= puff_size_,
-                                          Error::kInsufficientOutput);
+          TEST_AND_RETURN_FALSE(index_ + 4 <= puff_size_);
 
           puff_buf_out_[index_++] = kLenDistHeader | 127;
           puff_buf_out_[index_++] = static_cast<uint8_t>(pd.length - 3 - 127);
@@ -124,14 +115,12 @@
 
     case PuffData::Type::kBlockMetadata:
       DVLOG(2) << "Write block metadata length: " << pd.length;
-      TEST_AND_RETURN_FALSE(FlushLiterals(error));
-      TEST_AND_RETURN_FALSE_SET_ERROR(
-          pd.length <= sizeof(pd.block_metadata) && pd.length > 0,
-          Error::kInvalidInput);
+      TEST_AND_RETURN_FALSE(FlushLiterals());
+      TEST_AND_RETURN_FALSE(pd.length <= sizeof(pd.block_metadata) &&
+                            pd.length > 0);
       if (puff_buf_out_ != nullptr) {
         // Boundary check
-        TEST_AND_RETURN_FALSE_SET_ERROR(index_ + pd.length + 2 <= puff_size_,
-                                        Error::kInsufficientOutput);
+        TEST_AND_RETURN_FALSE(index_ + pd.length + 2 <= puff_size_);
 
         WriteUint16ToByteArray(pd.length - 1, &puff_buf_out_[index_]);
       }
@@ -147,11 +136,10 @@
 
     case PuffData::Type::kEndOfBlock:
       DVLOG(2) << "Write end of block";
-      TEST_AND_RETURN_FALSE(FlushLiterals(error));
+      TEST_AND_RETURN_FALSE(FlushLiterals());
       if (puff_buf_out_ != nullptr) {
         // Boundary check
-        TEST_AND_RETURN_FALSE_SET_ERROR(index_ + 2 <= puff_size_,
-                                        Error::kInsufficientOutput);
+        TEST_AND_RETURN_FALSE(index_ + 2 <= puff_size_);
 
         puff_buf_out_[index_++] = kLenDistHeader | 127;
         puff_buf_out_[index_++] = static_cast<uint8_t>(259 - 3 - 127);
@@ -165,22 +153,18 @@
 
     default:
       LOG(ERROR) << "Invalid PuffData::Type";
-      *error = Error::kInvalidInput;
       return false;
   }
-  *error = Error::kSuccess;
   return true;
 }
 
-bool BufferPuffWriter::FlushLiterals(Error* error) {
+bool BufferPuffWriter::FlushLiterals() {
   if (cur_literals_length_ == 0) {
     return true;
   }
   switch (state_) {
     case State::kWritingSmallLiteral:
-      TEST_AND_RETURN_FALSE_SET_ERROR(
-          cur_literals_length_ == (index_ - len_index_ - 1),
-          Error::kInvalidInput);
+      TEST_AND_RETURN_FALSE(cur_literals_length_ == (index_ - len_index_ - 1));
       if (puff_buf_out_ != nullptr) {
         puff_buf_out_[len_index_] =
             kLiteralsHeader | static_cast<uint8_t>(cur_literals_length_ - 1);
@@ -191,9 +175,7 @@
       break;
 
     case State::kWritingLargeLiteral:
-      TEST_AND_RETURN_FALSE_SET_ERROR(
-          cur_literals_length_ == (index_ - len_index_ - 3),
-          Error::kInvalidInput);
+      TEST_AND_RETURN_FALSE(cur_literals_length_ == (index_ - len_index_ - 3));
       if (puff_buf_out_ != nullptr) {
         puff_buf_out_[len_index_++] = kLiteralsHeader | 127;
         WriteUint16ToByteArray(
@@ -212,15 +194,14 @@
 
     default:
       LOG(ERROR) << "Invalid State";
-      *error = Error::kInvalidInput;
       return false;
   }
   cur_literals_length_ = 0;
   return true;
 }
 
-bool BufferPuffWriter::Flush(Error* error) {
-  TEST_AND_RETURN_FALSE(FlushLiterals(error));
+bool BufferPuffWriter::Flush() {
+  TEST_AND_RETURN_FALSE(FlushLiterals());
   return true;
 }
 
diff --git a/src/puff_writer.h b/src/puff_writer.h
index 416823b..8556583 100644
--- a/src/puff_writer.h
+++ b/src/puff_writer.h
@@ -9,7 +9,6 @@
 #include <cstdint>
 
 #include "puffin/src/include/puffin/common.h"
-#include "puffin/src/include/puffin/errors.h"
 #include "puffin/src/puff_data.h"
 
 namespace puffin {
@@ -26,13 +25,12 @@
   //
   // |pd|          IN   The data to put into the puffed buffer. |pd.type|
   //                    defines the type of the data.
-  // |error|       OUT  The error code.
   // Returns false if it fails.
-  virtual bool Insert(const PuffData& pd, Error* error) = 0;
+  virtual bool Insert(const PuffData& pd) = 0;
 
   // Fluesh any buffer or internal state to the output.
   // Returns false if it fails.
-  virtual bool Flush(Error* error) = 0;
+  virtual bool Flush() = 0;
 
   // Returns the number of bytes processed and written into the puff buffer.
   virtual size_t Size() = 0;
@@ -55,13 +53,13 @@
 
   ~BufferPuffWriter() override = default;
 
-  bool Insert(const PuffData& pd, Error* error) override;
-  bool Flush(Error* error) override;
+  bool Insert(const PuffData& pd) override;
+  bool Flush() override;
   size_t Size() override;
 
  private:
   // Flushes the literals into the output and resets the state.
-  bool FlushLiterals(Error* error);
+  bool FlushLiterals();
 
   // The pointer to the puffed stream. This should not be deallocated.
   uint8_t* puff_buf_out_;
diff --git a/src/puffdiff.cc b/src/puffdiff.cc
index 7d02085..ac2458b 100644
--- a/src/puffdiff.cc
+++ b/src/puffdiff.cc
@@ -12,23 +12,25 @@
 #include <vector>
 
 #include "bsdiff/bsdiff.h"
+#include "bsdiff/patch_writer_factory.h"
 
+#include "puffin/src/file_stream.h"
 #include "puffin/src/include/puffin/common.h"
 #include "puffin/src/include/puffin/puffer.h"
 #include "puffin/src/include/puffin/puffpatch.h"
 #include "puffin/src/include/puffin/utils.h"
-#include "puffin/src/file_stream.h"
+#include "puffin/src/logging.h"
 #include "puffin/src/memory_stream.h"
 #include "puffin/src/puffin.pb.h"
 #include "puffin/src/puffin_stream.h"
-#include "puffin/src/set_errors.h"
-
-namespace puffin {
 
 using std::string;
 using std::vector;
 
+namespace puffin {
+
 namespace {
+const int kBrotliCompressionQuality = 11;
 
 template <typename T>
 void CopyVectorToRpf(
@@ -98,6 +100,7 @@
               UniqueStreamPtr dst,
               const vector<BitExtent>& src_deflates,
               const vector<BitExtent>& dst_deflates,
+              const std::vector<bsdiff::CompressorType>& compressors,
               const string& tmp_filepath,
               Buffer* patch) {
   auto puffer = std::make_shared<Puffer>();
@@ -125,10 +128,13 @@
   TEST_AND_RETURN_FALSE(puff_deflate_stream(std::move(dst), dst_deflates,
                                             &dst_puff_buffer, &dst_puffs));
 
+  auto bsdiff_patch_writer = bsdiff::CreateBSDF2PatchWriter(
+      tmp_filepath, compressors, kBrotliCompressionQuality);
+
   TEST_AND_RETURN_FALSE(
       0 == bsdiff::bsdiff(src_puff_buffer.data(), src_puff_buffer.size(),
                           dst_puff_buffer.data(), dst_puff_buffer.size(),
-                          tmp_filepath.c_str(), nullptr));
+                          bsdiff_patch_writer.get(), nullptr));
 
   auto bsdiff_patch = FileStream::Open(tmp_filepath, true, false);
   TEST_AND_RETURN_FALSE(bsdiff_patch);
@@ -147,13 +153,26 @@
 
 bool PuffDiff(const Buffer& src,
               const Buffer& dst,
+              const std::vector<BitExtent>& src_deflates,
+              const std::vector<BitExtent>& dst_deflates,
+              const std::vector<bsdiff::CompressorType>& compressors,
+              const std::string& tmp_filepath,
+              Buffer* patch) {
+  return PuffDiff(MemoryStream::CreateForRead(src),
+                  MemoryStream::CreateForRead(dst), src_deflates, dst_deflates,
+                  compressors, tmp_filepath, patch);
+}
+
+bool PuffDiff(const Buffer& src,
+              const Buffer& dst,
               const vector<BitExtent>& src_deflates,
               const vector<BitExtent>& dst_deflates,
               const string& tmp_filepath,
               Buffer* patch) {
-  return PuffDiff(MemoryStream::CreateForRead(src),
-                  MemoryStream::CreateForRead(dst), src_deflates, dst_deflates,
-                  tmp_filepath, patch);
+  return PuffDiff(
+      src, dst, src_deflates, dst_deflates,
+      {bsdiff::CompressorType::kBZ2, bsdiff::CompressorType::kBrotli},
+      tmp_filepath, patch);
 }
 
 }  // namespace puffin
diff --git a/src/puffer.cc b/src/puffer.cc
index 7d8a2f2..a514968 100644
--- a/src/puffer.cc
+++ b/src/puffer.cc
@@ -14,34 +14,32 @@
 #include "puffin/src/huffman_table.h"
 #include "puffin/src/include/puffin/common.h"
 #include "puffin/src/include/puffin/stream.h"
+#include "puffin/src/logging.h"
 #include "puffin/src/puff_data.h"
 #include "puffin/src/puff_writer.h"
-#include "puffin/src/set_errors.h"
+
+using std::string;
+using std::vector;
 
 namespace puffin {
 
-using std::vector;
-using std::string;
-
 Puffer::Puffer() : dyn_ht_(new HuffmanTable()), fix_ht_(new HuffmanTable()) {}
 
 Puffer::~Puffer() {}
 
 bool Puffer::PuffDeflate(BitReaderInterface* br,
                          PuffWriterInterface* pw,
-                         vector<BitExtent>* deflates,
-                         Error* error) const {
-  *error = Error::kSuccess;
+                         vector<BitExtent>* deflates) const {
   PuffData pd;
   HuffmanTable* cur_ht;
+  bool end_loop = false;
   // No bits left to read, return. We try to cache at least eight bits because
   // the minimum length of a deflate bit stream is 8: (fixed huffman table) 3
   // bits header + 5 bits just one len/dist symbol.
-  while (br->CacheBits(8)) {
+  while (!end_loop && br->CacheBits(8)) {
     auto start_bit_offset = br->OffsetInBits();
 
-    TEST_AND_RETURN_FALSE_SET_ERROR(br->CacheBits(3),
-                                    Error::kInsufficientInput);
+    TEST_AND_RETURN_FALSE(br->CacheBits(3));
     uint8_t final_bit = br->ReadBits(1);  // BFINAL
     br->DropBits(1);
     uint8_t type = br->ReadBits(2);  // BTYPE
@@ -49,6 +47,12 @@
     DVLOG(2) << "Read block type: "
              << BlockTypeToString(static_cast<BlockType>(type));
 
+    // If it is the final block and we are just looking for deflate locations,
+    // we consider this the end of the search.
+    if (deflates != nullptr && final_bit) {
+      end_loop = true;
+    }
+
     // Header structure
     // +-+-+-+-+-+-+-+-+
     // |F| TP|   SKIP  |
@@ -61,8 +65,7 @@
       case BlockType::kUncompressed: {
         auto skipped_bits = br->ReadBoundaryBits();
         br->SkipBoundaryBits();
-        TEST_AND_RETURN_FALSE_SET_ERROR(br->CacheBits(32),
-                                        Error::kInsufficientInput);
+        TEST_AND_RETURN_FALSE(br->CacheBits(32));
         auto len = br->ReadBits(16);  // LEN
         br->DropBits(16);
         auto nlen = br->ReadBits(16);  // NLEN
@@ -71,7 +74,6 @@
         if ((len ^ nlen) != 0xFFFF) {
           LOG(ERROR) << "Length of uncompressed data is invalid;"
                      << " LEN(" << len << ") NLEN(" << nlen << ")";
-          *error = Error::kInvalidInput;
           return false;
         }
 
@@ -82,23 +84,20 @@
         pd.type = PuffData::Type::kBlockMetadata;
         pd.block_metadata[0] = block_header;
         pd.length = 1;
-        TEST_AND_RETURN_FALSE(pw->Insert(pd, error));
+        TEST_AND_RETURN_FALSE(pw->Insert(pd));
 
         // Insert all the raw literals.
         pd.type = PuffData::Type::kLiterals;
         pd.length = len;
-        TEST_AND_RETURN_FALSE_SET_ERROR(
-            br->GetByteReaderFn(pd.length, &pd.read_fn),
-            Error::kInsufficientInput);
-        TEST_AND_RETURN_FALSE(pw->Insert(pd, error));
+        TEST_AND_RETURN_FALSE(br->GetByteReaderFn(pd.length, &pd.read_fn));
+        TEST_AND_RETURN_FALSE(pw->Insert(pd));
 
         pd.type = PuffData::Type::kEndOfBlock;
-        TEST_AND_RETURN_FALSE(pw->Insert(pd, error));
+        TEST_AND_RETURN_FALSE(pw->Insert(pd));
 
-        if (deflates != nullptr) {
-          deflates->emplace_back(start_bit_offset,
-                                 br->OffsetInBits() - start_bit_offset);
-        }
+        // There is no need to insert the location of uncompressed deflates
+        // because we do not want the uncompressed blocks when trying to find
+        // the bit-addressed location of deflates. They better be ignored.
 
         // continue the loop. Do not read any literal/length/distance.
         continue;
@@ -110,7 +109,7 @@
         pd.type = PuffData::Type::kBlockMetadata;
         pd.block_metadata[0] = block_header;
         pd.length = 1;
-        TEST_AND_RETURN_FALSE(pw->Insert(pd, error));
+        TEST_AND_RETURN_FALSE(pw->Insert(pd));
         break;
 
       case BlockType::kDynamic:
@@ -118,16 +117,15 @@
         pd.block_metadata[0] = block_header;
         pd.length = sizeof(pd.block_metadata) - 1;
         TEST_AND_RETURN_FALSE(dyn_ht_->BuildDynamicHuffmanTable(
-            br, &pd.block_metadata[1], &pd.length, error));
+            br, &pd.block_metadata[1], &pd.length));
         pd.length += 1;  // For the header.
-        TEST_AND_RETURN_FALSE(pw->Insert(pd, error));
+        TEST_AND_RETURN_FALSE(pw->Insert(pd));
         cur_ht = dyn_ht_.get();
         break;
 
       default:
         LOG(ERROR) << "Invalid block compression type: "
                    << static_cast<int>(type);
-        *error = Error::kInvalidInput;
         return false;
     }
 
@@ -137,63 +135,54 @@
         // It could be the end of buffer and the bit length of the end_of_block
         // symbol has less than maximum bit length of current Huffman table. So
         // only asking for the size of end of block symbol (256).
-        TEST_AND_RETURN_FALSE_SET_ERROR(cur_ht->EndOfBlockBitLength(&max_bits),
-                                        Error::kInvalidInput);
+        TEST_AND_RETURN_FALSE(cur_ht->EndOfBlockBitLength(&max_bits));
       }
-      TEST_AND_RETURN_FALSE_SET_ERROR(br->CacheBits(max_bits),
-                                      Error::kInsufficientInput);
+      TEST_AND_RETURN_FALSE(br->CacheBits(max_bits));
       auto bits = br->ReadBits(max_bits);
       uint16_t lit_len_alphabet;
       size_t nbits;
-      TEST_AND_RETURN_FALSE_SET_ERROR(
-          cur_ht->LitLenAlphabet(bits, &lit_len_alphabet, &nbits),
-          Error::kInvalidInput);
+      TEST_AND_RETURN_FALSE(
+          cur_ht->LitLenAlphabet(bits, &lit_len_alphabet, &nbits));
       br->DropBits(nbits);
       if (lit_len_alphabet < 256) {
         pd.type = PuffData::Type::kLiteral;
         pd.byte = lit_len_alphabet;
-        TEST_AND_RETURN_FALSE(pw->Insert(pd, error));
+        TEST_AND_RETURN_FALSE(pw->Insert(pd));
 
       } else if (256 == lit_len_alphabet) {
         pd.type = PuffData::Type::kEndOfBlock;
-        TEST_AND_RETURN_FALSE(pw->Insert(pd, error));
+        TEST_AND_RETURN_FALSE(pw->Insert(pd));
         if (deflates != nullptr) {
           deflates->emplace_back(start_bit_offset,
                                  br->OffsetInBits() - start_bit_offset);
         }
         break;  // Breaks the loop.
       } else {
-        TEST_AND_RETURN_FALSE_SET_ERROR(lit_len_alphabet <= 285,
-                                        Error::kInvalidInput);
+        TEST_AND_RETURN_FALSE(lit_len_alphabet <= 285);
         // Reading length.
         auto len_code_start = lit_len_alphabet - 257;
         auto extra_bits_len = kLengthExtraBits[len_code_start];
         uint16_t extra_bits_value = 0;
         if (extra_bits_len) {
-          TEST_AND_RETURN_FALSE_SET_ERROR(br->CacheBits(extra_bits_len),
-                                          Error::kInsufficientInput);
+          TEST_AND_RETURN_FALSE(br->CacheBits(extra_bits_len));
           extra_bits_value = br->ReadBits(extra_bits_len);
           br->DropBits(extra_bits_len);
         }
         auto length = kLengthBases[len_code_start] + extra_bits_value;
 
-        TEST_AND_RETURN_FALSE_SET_ERROR(
-            br->CacheBits(cur_ht->DistanceMaxBits()),
-            Error::kInsufficientInput);
+        TEST_AND_RETURN_FALSE(br->CacheBits(cur_ht->DistanceMaxBits()));
         auto bits = br->ReadBits(cur_ht->DistanceMaxBits());
         uint16_t distance_alphabet;
         size_t nbits;
-        TEST_AND_RETURN_FALSE_SET_ERROR(
-            cur_ht->DistanceAlphabet(bits, &distance_alphabet, &nbits),
-            Error::kInvalidInput);
+        TEST_AND_RETURN_FALSE(
+            cur_ht->DistanceAlphabet(bits, &distance_alphabet, &nbits));
         br->DropBits(nbits);
 
         // Reading distance.
         extra_bits_len = kDistanceExtraBits[distance_alphabet];
         extra_bits_value = 0;
         if (extra_bits_len) {
-          TEST_AND_RETURN_FALSE_SET_ERROR(br->CacheBits(extra_bits_len),
-                                          Error::kInsufficientInput);
+          TEST_AND_RETURN_FALSE(br->CacheBits(extra_bits_len));
           extra_bits_value = br->ReadBits(extra_bits_len);
           br->DropBits(extra_bits_len);
         }
@@ -201,11 +190,11 @@
         pd.type = PuffData::Type::kLenDist;
         pd.length = length;
         pd.distance = kDistanceBases[distance_alphabet] + extra_bits_value;
-        TEST_AND_RETURN_FALSE(pw->Insert(pd, error));
+        TEST_AND_RETURN_FALSE(pw->Insert(pd));
       }
     }
   }
-  TEST_AND_RETURN_FALSE(pw->Flush(error));
+  TEST_AND_RETURN_FALSE(pw->Flush());
   return true;
 }
 
diff --git a/src/puffin_stream.cc b/src/puffin_stream.cc
index 05dd7f6..91d0dd7 100644
--- a/src/puffin_stream.cc
+++ b/src/puffin_stream.cc
@@ -16,16 +16,16 @@
 #include "puffin/src/include/puffin/huffer.h"
 #include "puffin/src/include/puffin/puffer.h"
 #include "puffin/src/include/puffin/stream.h"
+#include "puffin/src/logging.h"
 #include "puffin/src/puff_reader.h"
 #include "puffin/src/puff_writer.h"
-#include "puffin/src/set_errors.h"
+
+using std::shared_ptr;
+using std::unique_ptr;
+using std::vector;
 
 namespace puffin {
 
-using std::vector;
-using std::unique_ptr;
-using std::shared_ptr;
-
 namespace {
 
 bool CheckArgsIntegrity(uint64_t puff_size,
@@ -288,9 +288,8 @@
         TEST_AND_RETURN_FALSE(bit_reader.CacheBits(extra_bits_len));
         bit_reader.DropBits(extra_bits_len);
 
-        Error error;
         TEST_AND_RETURN_FALSE(
-            puffer_->PuffDeflate(&bit_reader, &puff_writer, nullptr, &error));
+            puffer_->PuffDeflate(&bit_reader, &puff_writer, nullptr));
         TEST_AND_RETURN_FALSE(bytes_to_read == bit_reader.Offset());
         TEST_AND_RETURN_FALSE(cur_puff_->length == puff_writer.Size());
       } else {
@@ -385,9 +384,7 @@
             bit_writer.WriteBits(cur_deflate_->offset & 7, last_byte_));
         last_byte_ = 0;
 
-        Error error;
-        TEST_AND_RETURN_FALSE(
-            huffer_->HuffDeflate(&puff_reader, &bit_writer, &error));
+        TEST_AND_RETURN_FALSE(huffer_->HuffDeflate(&puff_reader, &bit_writer));
         TEST_AND_RETURN_FALSE(bit_writer.Size() == bytes_to_write);
         TEST_AND_RETURN_FALSE(puff_reader.BytesLeft() == 0);
 
diff --git a/src/puffin_unittest.cc b/src/puffin_unittest.cc
index fd035bc..2ccf23f 100644
--- a/src/puffin_unittest.cc
+++ b/src/puffin_unittest.cc
@@ -14,18 +14,27 @@
 #include "puffin/src/include/puffin/huffer.h"
 #include "puffin/src/include/puffin/puffer.h"
 #include "puffin/src/include/puffin/utils.h"
+#include "puffin/src/logging.h"
 #include "puffin/src/memory_stream.h"
 #include "puffin/src/puff_reader.h"
 #include "puffin/src/puff_writer.h"
 #include "puffin/src/puffin_stream.h"
-#include "puffin/src/sample_generator.h"
-#include "puffin/src/set_errors.h"
 #include "puffin/src/unittest_common.h"
 
+using std::string;
+using std::vector;
+
 namespace puffin {
 
-using std::vector;
-using std::string;
+namespace {
+
+// Uncompressed deflate block.
+const Buffer kRawEmpty = {};
+const Buffer kRaw1 = {0x01};
+const Buffer kRaw2 = {0x01, 0x01};
+const Buffer kRaw5 = {0x01, 0x02, 0x03, 0x04, 0x05};
+
+}  // namespace
 
 class PuffinTest : public ::testing::Test {
  public:
@@ -39,13 +48,13 @@
     auto start = static_cast<uint8_t*>(out_buf);
 
     PuffData pd;
-    Error error;
     while (puff_reader.BytesLeft() != 0) {
-      TEST_AND_RETURN_FALSE(puff_reader.GetNext(&pd, &error));
+      TEST_AND_RETURN_FALSE(puff_reader.GetNext(&pd));
       switch (pd.type) {
         case PuffData::Type::kLiteral:
           *start = pd.byte;
           start++;
+          FALLTHROUGH_INTENDED;
 
         case PuffData::Type::kLiterals:
           pd.read_fn(start, pd.length);
@@ -79,34 +88,27 @@
   bool PuffDeflate(const uint8_t* comp_buf,
                    size_t comp_size,
                    uint8_t* puff_buf,
-                   size_t puff_size,
-                   Error* error) const {
+                   size_t puff_size) const {
     BufferBitReader bit_reader(comp_buf, comp_size);
     BufferPuffWriter puff_writer(puff_buf, puff_size);
 
     TEST_AND_RETURN_FALSE(
-        puffer_.PuffDeflate(&bit_reader, &puff_writer, nullptr, error));
-    TEST_AND_RETURN_FALSE_SET_ERROR(comp_size == bit_reader.Offset(),
-                                    Error::kInvalidInput);
-    TEST_AND_RETURN_FALSE_SET_ERROR(puff_size == puff_writer.Size(),
-                                    Error::kInvalidInput);
+        puffer_.PuffDeflate(&bit_reader, &puff_writer, nullptr));
+    TEST_AND_RETURN_FALSE(comp_size == bit_reader.Offset());
+    TEST_AND_RETURN_FALSE(puff_size == puff_writer.Size());
     return true;
   }
 
   bool HuffDeflate(const uint8_t* puff_buf,
                    size_t puff_size,
                    uint8_t* comp_buf,
-                   size_t comp_size,
-                   Error* error) const {
+                   size_t comp_size) const {
     BufferPuffReader puff_reader(puff_buf, puff_size);
     BufferBitWriter bit_writer(comp_buf, comp_size);
 
-    TEST_AND_RETURN_FALSE(
-        huffer_.HuffDeflate(&puff_reader, &bit_writer, error));
-    TEST_AND_RETURN_FALSE_SET_ERROR(comp_size == bit_writer.Size(),
-                                    Error::kInvalidInput);
-    TEST_AND_RETURN_FALSE_SET_ERROR(puff_reader.BytesLeft() == 0,
-                                    Error::kInvalidInput);
+    TEST_AND_RETURN_FALSE(huffer_.HuffDeflate(&puff_reader, &bit_writer));
+    TEST_AND_RETURN_FALSE(comp_size == bit_writer.Size());
+    TEST_AND_RETURN_FALSE(puff_reader.BytesLeft() == 0);
     return true;
   }
 
@@ -118,25 +120,20 @@
     out_puff->resize(expected_puff.size());
     auto comp_size = compressed.size();
     auto puff_size = out_puff->size();
-    Error error;
-    ASSERT_TRUE(PuffDeflate(compressed.data(), comp_size, out_puff->data(),
-                            puff_size, &error));
+    ASSERT_TRUE(
+        PuffDeflate(compressed.data(), comp_size, out_puff->data(), puff_size));
     ASSERT_EQ(puff_size, expected_puff.size());
     out_puff->resize(puff_size);
     ASSERT_EQ(expected_puff, *out_puff);
   }
 
   // Should fail when trying to puff |compressed|.
-  void FailPuffDeflate(const Buffer& compressed,
-                       Error expected_error,
-                       Buffer* out_puff) {
+  void FailPuffDeflate(const Buffer& compressed, Buffer* out_puff) {
     out_puff->resize(compressed.size() * 2 + 10);
     auto comp_size = compressed.size();
     auto puff_size = out_puff->size();
-    Error error;
-    ASSERT_FALSE(PuffDeflate(compressed.data(), comp_size, out_puff->data(),
-                             puff_size, &error));
-    ASSERT_EQ(error, expected_error);
+    ASSERT_FALSE(
+        PuffDeflate(compressed.data(), comp_size, out_puff->data(), puff_size));
   }
 
   // Huffs |puffed| into |out_huff| and checks its equality with
@@ -147,23 +144,18 @@
     out_huff->resize(expected_huff.size());
     auto huff_size = out_huff->size();
     auto puffed_size = puffed.size();
-    Error error;
-    ASSERT_TRUE(HuffDeflate(puffed.data(), puffed_size, out_huff->data(),
-                            huff_size, &error));
+    ASSERT_TRUE(
+        HuffDeflate(puffed.data(), puffed_size, out_huff->data(), huff_size));
     ASSERT_EQ(expected_huff, *out_huff);
   }
 
   // Should fail while huffing |puffed|
-  void FailHuffDeflate(const Buffer& puffed,
-                       Error expected_error,
-                       Buffer* out_compress) {
+  void FailHuffDeflate(const Buffer& puffed, Buffer* out_compress) {
     out_compress->resize(puffed.size());
     auto comp_size = out_compress->size();
     auto puff_size = puffed.size();
-    Error error;
-    ASSERT_TRUE(HuffDeflate(puffed.data(), puff_size, out_compress->data(),
-                            comp_size, &error));
-    ASSERT_EQ(error, expected_error);
+    ASSERT_TRUE(
+        HuffDeflate(puffed.data(), puff_size, out_compress->data(), comp_size));
   }
 
   // Decompresses from |puffed| into |uncompress| and checks its equality with
@@ -174,8 +166,8 @@
     uncompress->resize(original.size());
     auto uncomp_size = uncompress->size();
     auto puffed_size = puffed.size();
-    ASSERT_TRUE(DecompressPuff(
-        puffed.data(), &puffed_size, uncompress->data(), &uncomp_size));
+    ASSERT_TRUE(DecompressPuff(puffed.data(), &puffed_size, uncompress->data(),
+                               &uncomp_size));
     ASSERT_EQ(puffed_size, puffed.size());
     ASSERT_EQ(uncomp_size, original.size());
     uncompress->resize(uncomp_size);
@@ -234,76 +226,352 @@
 
 // Tests a simple buffer with uncompressed deflate block.
 TEST_F(PuffinTest, UncompressedTest) {
-  CheckSample(kRaw1, kDeflate1, kPuff1);
+  const Buffer kDeflate = {0x01, 0x05, 0x00, 0xFA, 0xFF,
+                           0x01, 0x02, 0x03, 0x04, 0x05};
+  const Buffer kPuff = {0x00, 0x00, 0x80, 0x04, 0x01, 0x02,
+                        0x03, 0x04, 0x05, 0xFF, 0x81};
+  CheckSample(kRaw5, kDeflate, kPuff);
 }
 
 // Tests a simple buffer with uncompressed deflate block with length zero.
 TEST_F(PuffinTest, ZeroLengthUncompressedTest) {
-  CheckSample(kRaw1_1, kDeflate1_1, kPuff1_1);
+  const Buffer kDeflate = {0x01, 0x00, 0x00, 0xFF, 0xFF};
+  const Buffer kPuff = {0x00, 0x00, 0x80, 0xFF, 0x81};
+  CheckSample(kRawEmpty, kDeflate, kPuff);
 }
 
-// Tests a dynamically compressed buffer with only one literal.
-TEST_F(PuffinTest, CompressedOneTest) {
-  CheckSample(kRaw2, kDeflate2, kPuff2);
+// Tests a Fixed Huffman table compressed buffer with only one literal.
+TEST_F(PuffinTest, OneLiteralFixedHuffmanTableTest) {
+  const Buffer kDeflate = {0x63, 0x04, 0x00};
+  const Buffer kPuff = {0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81};
+  CheckSample(kRaw1, kDeflate, kPuff);
 }
 
 // Tests deflate of an empty buffer.
 TEST_F(PuffinTest, EmptyTest) {
-  CheckSample(kRaw3, kDeflate3, kPuff3);
+  const Buffer kDeflate = {0x03, 0x00};
+  const Buffer kPuff = {0x00, 0x00, 0xA0, 0xFF, 0x81};
+  CheckSample(kRawEmpty, kDeflate, kPuff);
 }
 
 // Tests a simple buffer with compress deflate block using fixed Huffman table.
-TEST_F(PuffinTest, FixedCompressedTest) {
-  CheckSample(kRaw4, kDeflate4, kPuff4);
+TEST_F(PuffinTest, FixedHuffmanTableCompressedTest) {
+  const Buffer kDeflate = {0x63, 0x64, 0x62, 0x66, 0x61, 0x05, 0x00};
+  const Buffer kPuff = {0x00, 0x00, 0xA0, 0x04, 0x01, 0x02,
+                        0x03, 0x04, 0x05, 0xFF, 0x81};
+  CheckSample(kRaw5, kDeflate, kPuff);
 }
 
+// Tests that uncompressed deflate blocks are not ignored when the output
+// deflate location pointer is null.
+TEST_F(PuffinTest, NoIgnoreUncompressedBlocksTest) {
+  const Buffer kDeflate = {0x01, 0x05, 0x00, 0xFA, 0xFF,
+                           0x01, 0x02, 0x03, 0x04, 0x05};
+  BufferBitReader bit_reader(kDeflate.data(), kDeflate.size());
+  Buffer puff_buffer(11);  // Same size as |uncomp_puff| below.
+  BufferPuffWriter puff_writer(puff_buffer.data(), puff_buffer.size());
+  vector<BitExtent> deflates;
+  EXPECT_TRUE(puffer_.PuffDeflate(&bit_reader, &puff_writer, nullptr));
+  const Buffer kPuff = {0x00, 0x00, 0x80, 0x04, 0x01, 0x02,
+                        0x03, 0x04, 0x05, 0xFF, 0x81};
+  EXPECT_EQ(puff_writer.Size(), kPuff.size());
+  EXPECT_EQ(puff_buffer, kPuff);
+}
+
+// Tests that uncompressed deflate blocks are ignored when the output
+// deflate location pointer is valid.
+TEST_F(PuffinTest, IgnoreUncompressedBlocksTest) {
+  const Buffer kDeflate = {0x01, 0x05, 0x00, 0xFA, 0xFF,
+                           0x01, 0x02, 0x03, 0x04, 0x05};
+  BufferBitReader bit_reader(kDeflate.data(), kDeflate.size());
+  BufferPuffWriter puff_writer(nullptr, 0);
+  vector<BitExtent> deflates;
+  EXPECT_TRUE(puffer_.PuffDeflate(&bit_reader, &puff_writer, &deflates));
+  EXPECT_TRUE(deflates.empty());
+}
+
+namespace {
+// It is actuall the content of the copyright header.
+const Buffer kDynamicHTRaw = {
+    0x0A, 0x2F, 0x2F, 0x0A, 0x2F, 0x2F, 0x20, 0x43, 0x6F, 0x70, 0x79, 0x72,
+    0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, 0x32, 0x30, 0x31,
+    0x37, 0x20, 0x54, 0x68, 0x65, 0x20, 0x41, 0x6E, 0x64, 0x72, 0x6F, 0x69,
+    0x64, 0x20, 0x4F, 0x70, 0x65, 0x6E, 0x20, 0x53, 0x6F, 0x75, 0x72, 0x63,
+    0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x0A, 0x2F, 0x2F,
+    0x0A, 0x2F, 0x2F, 0x20, 0x4C, 0x69, 0x63, 0x65, 0x6E, 0x73, 0x65, 0x64,
+    0x20, 0x75, 0x6E, 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x41,
+    0x70, 0x61, 0x63, 0x68, 0x65, 0x20, 0x4C, 0x69, 0x63, 0x65, 0x6E, 0x73,
+    0x65, 0x2C, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x32,
+    0x2E, 0x30, 0x20, 0x28, 0x74, 0x68, 0x65, 0x20, 0x22, 0x4C, 0x69, 0x63,
+    0x65, 0x6E, 0x73, 0x65, 0x22, 0x29, 0x3B, 0x0A, 0x2F, 0x2F, 0x20, 0x79,
+    0x6F, 0x75, 0x20, 0x6D, 0x61, 0x79, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x75,
+    0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6C, 0x65,
+    0x20, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x20, 0x69, 0x6E, 0x20, 0x63,
+    0x6F, 0x6D, 0x70, 0x6C, 0x69, 0x61, 0x6E, 0x63, 0x65, 0x20, 0x77, 0x69,
+    0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4C, 0x69, 0x63, 0x65, 0x6E,
+    0x73, 0x65, 0x2E, 0x0A, 0x2F, 0x2F, 0x20, 0x59, 0x6F, 0x75, 0x20, 0x6D,
+    0x61, 0x79, 0x20, 0x6F, 0x62, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x61, 0x20,
+    0x63, 0x6F, 0x70, 0x79, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20,
+    0x4C, 0x69, 0x63, 0x65, 0x6E, 0x73, 0x65, 0x20, 0x61, 0x74, 0x0A, 0x2F,
+    0x2F, 0x0A, 0x2F, 0x2F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x74,
+    0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x61, 0x70, 0x61,
+    0x63, 0x68, 0x65, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x6C, 0x69, 0x63, 0x65,
+    0x6E, 0x73, 0x65, 0x73, 0x2F, 0x4C, 0x49, 0x43, 0x45, 0x4E, 0x53, 0x45,
+    0x2D, 0x32, 0x2E, 0x30, 0x0A, 0x2F, 0x2F, 0x0A, 0x2F, 0x2F, 0x20, 0x55,
+    0x6E, 0x6C, 0x65, 0x73, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,
+    0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63,
+    0x61, 0x62, 0x6C, 0x65, 0x20, 0x6C, 0x61, 0x77, 0x20, 0x6F, 0x72, 0x20,
+    0x61, 0x67, 0x72, 0x65, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x69, 0x6E,
+    0x20, 0x77, 0x72, 0x69, 0x74, 0x69, 0x6E, 0x67, 0x2C, 0x20, 0x73, 0x6F,
+    0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0A, 0x2F, 0x2F, 0x20, 0x64, 0x69,
+    0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x20, 0x75, 0x6E,
+    0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4C, 0x69, 0x63, 0x65,
+    0x6E, 0x73, 0x65, 0x20, 0x69, 0x73, 0x20, 0x64, 0x69, 0x73, 0x74, 0x72,
+    0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x20, 0x6F, 0x6E, 0x20, 0x61, 0x6E,
+    0x20, 0x22, 0x41, 0x53, 0x20, 0x49, 0x53, 0x22, 0x20, 0x42, 0x41, 0x53,
+    0x49, 0x53, 0x2C, 0x0A, 0x2F, 0x2F, 0x20, 0x57, 0x49, 0x54, 0x48, 0x4F,
+    0x55, 0x54, 0x20, 0x57, 0x41, 0x52, 0x52, 0x41, 0x4E, 0x54, 0x49, 0x45,
+    0x53, 0x20, 0x4F, 0x52, 0x20, 0x43, 0x4F, 0x4E, 0x44, 0x49, 0x54, 0x49,
+    0x4F, 0x4E, 0x53, 0x20, 0x4F, 0x46, 0x20, 0x41, 0x4E, 0x59, 0x20, 0x4B,
+    0x49, 0x4E, 0x44, 0x2C, 0x20, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20,
+    0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x6F, 0x72, 0x20, 0x69,
+    0x6D, 0x70, 0x6C, 0x69, 0x65, 0x64, 0x2E, 0x0A, 0x2F, 0x2F, 0x20, 0x53,
+    0x65, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4C, 0x69, 0x63, 0x65, 0x6E,
+    0x73, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
+    0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x6C, 0x61, 0x6E, 0x67,
+    0x75, 0x61, 0x67, 0x65, 0x20, 0x67, 0x6F, 0x76, 0x65, 0x72, 0x6E, 0x69,
+    0x6E, 0x67, 0x20, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F,
+    0x6E, 0x73, 0x20, 0x61, 0x6E, 0x64, 0x0A, 0x2F, 0x2F, 0x20, 0x6C, 0x69,
+    0x6D, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x75, 0x6E,
+    0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4C, 0x69, 0x63, 0x65,
+    0x6E, 0x73, 0x65, 0x2E, 0x0A};
+
+// Dynamic huffman compressed deflate.
+const Buffer kDynamicHTDeflate = {
+    0x65, 0x91, 0x41, 0x6F, 0x9C, 0x30, 0x10, 0x85, 0xEF, 0xFB, 0x2B, 0x9E,
+    0xF6, 0x94, 0x48, 0x5B, 0x48, 0x73, 0xA9, 0xD4, 0x9E, 0xE8, 0x66, 0xAB,
+    0xA0, 0x46, 0x50, 0x2D, 0xA4, 0x51, 0x8E, 0x5E, 0x18, 0xD8, 0x89, 0x58,
+    0xDB, 0xB5, 0x4D, 0xC9, 0xFE, 0xFB, 0x8E, 0x59, 0x22, 0x25, 0xAA, 0x2F,
+    0xC8, 0xCC, 0xCC, 0x9B, 0xEF, 0x3D, 0xAF, 0xD2, 0x74, 0x95, 0xA6, 0xD8,
+    0x1A, 0x7B, 0x76, 0xDC, 0x1F, 0x03, 0xAE, 0xB6, 0xD7, 0xB8, 0xBD, 0xF9,
+    0xFC, 0x05, 0xF5, 0x91, 0x90, 0xE9, 0xD6, 0x19, 0x6E, 0x51, 0x5A, 0xD2,
+    0xA8, 0xCC, 0xE8, 0x1A, 0xC2, 0x2F, 0x67, 0x5E, 0xA8, 0x09, 0xAB, 0xCB,
+    0xE0, 0x03, 0x37, 0xA4, 0x3D, 0xB5, 0x18, 0x75, 0x4B, 0x0E, 0x21, 0x0E,
+    0x59, 0xD5, 0xC8, 0x67, 0xA9, 0x6C, 0xF0, 0x9B, 0x9C, 0x67, 0xA3, 0x71,
+    0x9B, 0xDC, 0xE0, 0x2A, 0x36, 0xAC, 0x97, 0xD2, 0xFA, 0xFA, 0x5B, 0x94,
+    0x38, 0x9B, 0x11, 0x27, 0x75, 0x86, 0x36, 0x01, 0xA3, 0x27, 0xD1, 0x60,
+    0x8F, 0x8E, 0x07, 0x02, 0xBD, 0x36, 0x64, 0x03, 0x58, 0xA3, 0x31, 0x27,
+    0x3B, 0xB0, 0xD2, 0xB2, 0x7F, 0xE2, 0x70, 0x9C, 0xF7, 0x2C, 0x2A, 0x49,
+    0xD4, 0x78, 0x5E, 0x34, 0xCC, 0x21, 0x28, 0x69, 0x57, 0x32, 0x60, 0xE5,
+    0xD6, 0xBD, 0x6F, 0x84, 0x7A, 0x83, 0x9E, 0xCF, 0x31, 0x04, 0xFB, 0x35,
+    0x4D, 0xA7, 0x69, 0x4A, 0xD4, 0x4C, 0x9C, 0x18, 0xD7, 0xA7, 0xC3, 0xA5,
+    0xD7, 0xA7, 0x0F, 0xF9, 0x76, 0x57, 0x54, 0xBB, 0x4F, 0x42, 0xBD, 0x4C,
+    0x3D, 0xEA, 0x81, 0xBC, 0x87, 0xA3, 0x3F, 0x23, 0x3B, 0x71, 0x7C, 0x38,
+    0x43, 0x59, 0xA1, 0x6A, 0xD4, 0x41, 0x58, 0x07, 0x35, 0xC1, 0x38, 0xA8,
+    0xDE, 0x91, 0xD4, 0x82, 0x89, 0xD4, 0x93, 0xE3, 0xC0, 0xBA, 0xDF, 0xC0,
+    0x9B, 0x2E, 0x4C, 0xCA, 0x51, 0x94, 0x69, 0xD9, 0x07, 0xC7, 0x87, 0x31,
+    0x7C, 0x08, 0xED, 0x8D, 0x51, 0xAC, 0xBF, 0x6F, 0x90, 0xD8, 0x94, 0xC6,
+    0x3A, 0xAB, 0x90, 0x57, 0x6B, 0x7C, 0xCF, 0xAA, 0xBC, 0xDA, 0x44, 0x91,
+    0xA7, 0xBC, 0xBE, 0x2F, 0x1F, 0x6B, 0x3C, 0x65, 0xFB, 0x7D, 0x56, 0xD4,
+    0xF9, 0xAE, 0x42, 0xB9, 0xC7, 0xB6, 0x2C, 0xEE, 0xF2, 0x3A, 0x2F, 0x0B,
+    0xB9, 0xFD, 0x40, 0x56, 0x3C, 0xE3, 0x67, 0x5E, 0xDC, 0x6D, 0x40, 0x12,
+    0x99, 0xEC, 0xA1, 0x57, 0xEB, 0xA2, 0x03, 0xC1, 0xE4, 0x18, 0x27, 0xB5,
+    0x73, 0x76, 0x15, 0xD1, 0x07, 0x84, 0xCE, 0x5C, 0x90, 0xBC, 0xA5, 0x86,
+    0x3B, 0x6E, 0xC4, 0x9A, 0xEE, 0x47, 0xD5, 0x13, 0x7A, 0xF3, 0x97, 0x9C,
+    0x16, 0x47, 0xB0, 0xE4, 0x4E, 0xEC, 0xE3, 0xB3, 0x7A, 0x01, 0x6C, 0xA3,
+    0xCC, 0xC0, 0x27, 0x0E, 0x2A, 0xCC, 0xBF, 0xFE, 0xF3, 0x95, 0xAC, 0xFE,
+    0x01};
+
+const Buffer kDynamicHTPuff = {
+    0x00, 0x74, 0xC0, 0x0C, 0x11, 0x0C, 0x04, 0x63, 0x34, 0x32, 0x03, 0x04,
+    0x05, 0x06, 0x1B, 0x07, 0x26, 0x03, 0x00, 0x07, 0x16, 0x08, 0x08, 0x00,
+    0x00, 0x07, 0x09, 0x06, 0x06, 0x08, 0x09, 0x08, 0x15, 0x09, 0x00, 0x00,
+    0x09, 0x09, 0x16, 0x06, 0x09, 0x07, 0x08, 0x07, 0x09, 0x00, 0x08, 0x06,
+    0x00, 0x09, 0x08, 0x00, 0x06, 0x06, 0x09, 0x00, 0x07, 0x06, 0x06, 0x08,
+    0x09, 0x08, 0x00, 0x08, 0x18, 0x05, 0x07, 0x06, 0x06, 0x04, 0x06, 0x06,
+    0x07, 0x04, 0x08, 0x00, 0x06, 0x07, 0x05, 0x05, 0x05, 0x09, 0x05, 0x05,
+    0x05, 0x06, 0x09, 0x06, 0x08, 0x07, 0x97, 0x09, 0x04, 0x05, 0x06, 0x07,
+    0x06, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x09, 0x05, 0x15, 0x06, 0x00,
+    0x05, 0x06, 0x04, 0x04, 0x04, 0x03, 0x04, 0x02, 0x03, 0x03, 0x05, 0x39,
+    0x0A, 0x2F, 0x2F, 0x0A, 0x2F, 0x2F, 0x20, 0x43, 0x6F, 0x70, 0x79, 0x72,
+    0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, 0x32, 0x30, 0x31,
+    0x37, 0x20, 0x54, 0x68, 0x65, 0x20, 0x41, 0x6E, 0x64, 0x72, 0x6F, 0x69,
+    0x64, 0x20, 0x4F, 0x70, 0x65, 0x6E, 0x20, 0x53, 0x6F, 0x75, 0x72, 0x63,
+    0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x0A, 0x83, 0x00,
+    0x38, 0x0F, 0x4C, 0x69, 0x63, 0x65, 0x6E, 0x73, 0x65, 0x64, 0x20, 0x75,
+    0x6E, 0x64, 0x65, 0x72, 0x20, 0x74, 0x81, 0x00, 0x34, 0x02, 0x70, 0x61,
+    0x63, 0x80, 0x00, 0x06, 0x84, 0x00, 0x19, 0x0E, 0x2C, 0x20, 0x56, 0x65,
+    0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x32, 0x2E, 0x30, 0x20, 0x28, 0x81,
+    0x00, 0x20, 0x00, 0x22, 0x84, 0x00, 0x1A, 0x02, 0x22, 0x29, 0x3B, 0x81,
+    0x00, 0x42, 0x0E, 0x79, 0x6F, 0x75, 0x20, 0x6D, 0x61, 0x79, 0x20, 0x6E,
+    0x6F, 0x74, 0x20, 0x75, 0x73, 0x65, 0x80, 0x00, 0x43, 0x19, 0x69, 0x73,
+    0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74,
+    0x20, 0x69, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x70, 0x6C, 0x69, 0x61, 0x6E,
+    0x80, 0x00, 0x7F, 0x03, 0x77, 0x69, 0x74, 0x68, 0x82, 0x00, 0x67, 0x84,
+    0x00, 0x45, 0x00, 0x2E, 0x81, 0x00, 0x43, 0x00, 0x59, 0x84, 0x00, 0x43,
+    0x03, 0x6F, 0x62, 0x74, 0x61, 0x80, 0x00, 0x2E, 0x00, 0x61, 0x80, 0x00,
+    0x30, 0x00, 0x70, 0x80, 0x00, 0x0D, 0x00, 0x66, 0x89, 0x00, 0x28, 0x01,
+    0x20, 0x61, 0x85, 0x00, 0xB4, 0x82, 0x00, 0x00, 0x0B, 0x68, 0x74, 0x74,
+    0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x61, 0x82, 0x00, 0xB1,
+    0x05, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x6C, 0x83, 0x00, 0x2B, 0x09, 0x73,
+    0x2F, 0x4C, 0x49, 0x43, 0x45, 0x4E, 0x53, 0x45, 0x2D, 0x80, 0x00, 0xB5,
+    0x84, 0x00, 0x35, 0x0C, 0x55, 0x6E, 0x6C, 0x65, 0x73, 0x73, 0x20, 0x72,
+    0x65, 0x71, 0x75, 0x69, 0x72, 0x80, 0x00, 0xF1, 0x04, 0x62, 0x79, 0x20,
+    0x61, 0x70, 0x80, 0x00, 0x95, 0x02, 0x63, 0x61, 0x62, 0x80, 0x00, 0xAB,
+    0x0A, 0x6C, 0x61, 0x77, 0x20, 0x6F, 0x72, 0x20, 0x61, 0x67, 0x72, 0x65,
+    0x80, 0x00, 0x1B, 0x01, 0x74, 0x6F, 0x81, 0x00, 0xB5, 0x10, 0x77, 0x72,
+    0x69, 0x74, 0x69, 0x6E, 0x67, 0x2C, 0x20, 0x73, 0x6F, 0x66, 0x74, 0x77,
+    0x61, 0x72, 0x65, 0x81, 0x00, 0x46, 0x08, 0x64, 0x69, 0x73, 0x74, 0x72,
+    0x69, 0x62, 0x75, 0x74, 0x8A, 0x01, 0x34, 0x85, 0x00, 0xA3, 0x80, 0x00,
+    0xFA, 0x89, 0x00, 0x20, 0x80, 0x01, 0x36, 0x10, 0x61, 0x6E, 0x20, 0x22,
+    0x41, 0x53, 0x20, 0x49, 0x53, 0x22, 0x20, 0x42, 0x41, 0x53, 0x49, 0x53,
+    0x2C, 0x81, 0x00, 0x44, 0x1E, 0x57, 0x49, 0x54, 0x48, 0x4F, 0x55, 0x54,
+    0x20, 0x57, 0x41, 0x52, 0x52, 0x41, 0x4E, 0x54, 0x49, 0x45, 0x53, 0x20,
+    0x4F, 0x52, 0x20, 0x43, 0x4F, 0x4E, 0x44, 0x49, 0x54, 0x49, 0x4F, 0x4E,
+    0x80, 0x00, 0x0D, 0x0C, 0x46, 0x20, 0x41, 0x4E, 0x59, 0x20, 0x4B, 0x49,
+    0x4E, 0x44, 0x2C, 0x20, 0x65, 0x80, 0x01, 0x32, 0x80, 0x00, 0x67, 0x03,
+    0x65, 0x78, 0x70, 0x72, 0x81, 0x00, 0xC1, 0x80, 0x00, 0xA6, 0x00, 0x69,
+    0x81, 0x01, 0x4E, 0x01, 0x65, 0x64, 0x82, 0x01, 0x3B, 0x02, 0x53, 0x65,
+    0x65, 0x8A, 0x00, 0x82, 0x01, 0x66, 0x6F, 0x83, 0x00, 0x92, 0x07, 0x73,
+    0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x80, 0x00, 0xDA, 0x0C, 0x6E,
+    0x67, 0x75, 0x61, 0x67, 0x65, 0x20, 0x67, 0x6F, 0x76, 0x65, 0x72, 0x6E,
+    0x80, 0x00, 0xD1, 0x06, 0x20, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x81,
+    0x01, 0xD6, 0x00, 0x73, 0x80, 0x00, 0xA0, 0x00, 0x64, 0x81, 0x00, 0x46,
+    0x06, 0x6C, 0x69, 0x6D, 0x69, 0x74, 0x61, 0x74, 0x82, 0x00, 0x12, 0x8E,
+    0x00, 0xD7, 0x01, 0x2E, 0x0A, 0xFF, 0x81};
+}  // namespace
+
 // Tests a compressed deflate block using dynamic Huffman table.
-TEST_F(PuffinTest, DynamicHuffmanTest) {
-  CheckSample(kRaw10, kDeflate10, kPuff10);
+TEST_F(PuffinTest, DynamicHuffmanTableTest) {
+  CheckSample(kDynamicHTRaw, kDynamicHTDeflate, kDynamicHTPuff);
 }
 
 // Tests an uncompressed deflate block with invalid LEN/NLEN.
-TEST_F(PuffinTest, PuffDeflateFailedTest) {
+TEST_F(PuffinTest, PuffInvalidUncompressedLengthDeflateTest) {
+  const Buffer kDeflate = {0x01, 0x05, 0x00, 0xFF, 0xFF,
+                           0x01, 0x02, 0x03, 0x04, 0x05};
   Buffer puffed;
-  FailPuffDeflate(kDeflate5, Error::kInvalidInput, &puffed);
+  FailPuffDeflate(kDeflate, &puffed);
 }
 
 // Tests puffing a block with invalid block header.
-TEST_F(PuffinTest, PuffDeflateHeaderFailedTest) {
+TEST_F(PuffinTest, PuffInvalidBlockHeaderDeflateTest) {
+  const Buffer kDeflate = {0x07};
   Buffer puffed;
-  FailPuffDeflate(kDeflate6, Error::kInvalidInput, &puffed);
+  FailPuffDeflate(kDeflate, &puffed);
 }
 
-// Tests puffing a block with final block bit unset so it returns
-// Error::kInsufficientInput.
+// Tests puffing a block with final block bit unset so it returns false.
 TEST_F(PuffinTest, PuffDeflateNoFinalBlockBitTest) {
-  CheckSample(kRaw7, kDeflate7, kPuff7);
+  const Buffer kDeflate = {0x62, 0x04, 0x00};
+  const Buffer kPuff = {0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81};
+  CheckSample(kRaw1, kDeflate, kPuff);
 }
 
+// Tests two deflate buffers concatenated, neither have their final bit set.  It
+// is a valid deflate and puff buffer.
 TEST_F(PuffinTest, MultipleDeflateBufferNoFinabBitsTest) {
-  CheckSample(kRaw7_2, kDeflate7_2, kPuff7_2);
+  const Buffer kDeflate = {0x62, 0x04, 0x88, 0x11, 0x00};
+  const Buffer kPuff = {0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,
+                        0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81};
+  CheckSample(kRaw2, kDeflate, kPuff);
 }
 
+// Tests two deflate buffers concatenated, the first one has final bit set,
+// second one not. It is a valid deflate and puff buffer.
 TEST_F(PuffinTest, MultipleDeflateBufferOneFinalBitTest) {
-  CheckSample(kRaw7_3, kDeflate7_3, kPuff7_3);
+  const Buffer kDeflate = {0x63, 0x04, 0x88, 0x11, 0x00};
+  const Buffer kPuff = {0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81,
+                        0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81};
+  CheckSample(kRaw2, kDeflate, kPuff);
 }
 
+// Tests two deflate buffers concatenated, both have final bits set. It is a
+// valid deflate and puff buffer.
 TEST_F(PuffinTest, MultipleDeflateBufferBothFinalBitTest) {
-  CheckSample(kRaw7_4, kDeflate7_4, kPuff7_4);
+  const Buffer kDeflate = {0x63, 0x04, 0x8C, 0x11, 0x00};
+  const Buffer kPuff = {0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81,
+                        0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81};
+  CheckSample(kRaw2, kDeflate, kPuff);
+}
+
+// When locating deflates, the puffer has to end when it hit a final block. Test
+// that with two deflate buffers concatenated and both have final bits set.
+TEST_F(PuffinTest, EndOnFinalBitTest) {
+  const Buffer kDeflate = {0x63, 0x04, 0x8C, 0x11, 0x00};
+  BufferBitReader bit_reader(kDeflate.data(), kDeflate.size());
+  BufferPuffWriter puff_writer(nullptr, 0);
+  vector<BitExtent> deflates;
+  EXPECT_TRUE(puffer_.PuffDeflate(&bit_reader, &puff_writer, &deflates));
+  const vector<BitExtent> kExpectedDeflates = {{0, 18}};
+  EXPECT_EQ(deflates, kExpectedDeflates);
+  EXPECT_EQ(bit_reader.Offset(), 3);
 }
 
 // TODO(ahassani): Add unittests for Failhuff too.
 
+namespace {
+// The following is a sequence of bits starting from the top right and ends in
+// bottom left. It represents the bits in |kGapDeflates|. Bits inside the
+// brackets (including bits exactly under brackets) represent a deflate stream.
+//
+//       }   {                  } {                  }{                  }
+// 11000101 10000000 10001100 01010000 00010001 10001000 00000100 01100010
+//   0xC5     0x80     0x8C     0x50     0x11     0x88     0x04     0x62
+//
+//      }         {                  } {                  }   {
+// 10001011 11111100 00000100 01100010 00000001 00011000 10111000 00001000
+//   0x8B     0xFC     0x04     0x62     0x01     0x18     0xB8     0x08
+//
+//      }   {                  }         {                  }{
+// 10001011 00000001 00011000 10111111 11000000 01000110 00100000 00010001
+//   0x8B     0x01     0x18     0xBF     0xC0     0x46     0x20     0x11
+//
+//       {                  }          {                  }  {
+// 11111100 00000100 01100010 11111111 00000001 00011000 10110000 00010001
+//   0xFC     0x04     0x62     0xFF     0x01     0x18     0xB0     0x11
+//
+const Buffer kGapDeflates = {0x62, 0x04, 0x88, 0x11, 0x50, 0x8C, 0x80, 0xC5,
+                             0x08, 0xB8, 0x18, 0x01, 0x62, 0x04, 0xFC, 0x8B,
+                             0x11, 0x20, 0x46, 0xC0, 0xBF, 0x18, 0x01, 0x8B,
+                             0x11, 0xB0, 0x18, 0x01, 0xFF, 0x62, 0x04, 0xFC};
+
+const Buffer kGapPuffs = {0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,  // puff  0
+                          0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,  // puff  7
+                          0x01,                                      // raw   14
+                          0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,  // puff  15
+                          0x01, 0x01,                                // raw   22
+                          0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,  // puff  24
+                          0x07,                                      // raw   31
+                          0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,  // puff  32
+                          0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,  // puff  39
+                          0x3F, 0x03,                                // raw   46
+                          0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,  // puff  48
+                          0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,  // puff  55
+                          0x03, 0x3F,                                // raw   62
+                          0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,  // puff  64
+                          0x03,                                      // raw   71
+                          0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,  // puff  72
+                          0x03,                                      // raw   79
+                          0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,  // puff  80
+                          0xFF,                                      // raw   87
+                          0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,  // puff  88
+                          0x3F};                                     // raw   95
+
+// The fifth deflate (and its puff in kGapPuffExtents) is for zero length
+// deflate corner case.
+const std::vector<BitExtent> kGapSubblockDeflateExtents = {
+    {0, 18},   {18, 18},  {37, 18},  {57, 18},  {75, 0},   {78, 18}, {96, 18},
+    {122, 18}, {140, 18}, {166, 18}, {186, 18}, {206, 18}, {232, 18}};
+
+const std::vector<ByteExtent> kGapPuffExtents = {
+    {0, 7},  {7, 7},  {15, 7}, {24, 7}, {31, 0}, {32, 7}, {39, 7},
+    {48, 7}, {55, 7}, {64, 7}, {72, 7}, {80, 7}, {88, 7}};
+}  // namespace
+
 TEST_F(PuffinTest, BitExtentPuffAndHuffTest) {
-  CheckBitExtentsPuffAndHuff(kDeflate11, kSubblockDeflateExtents11, kPuff11,
-                             kPuffExtents11);
+  CheckBitExtentsPuffAndHuff(kGapDeflates, kGapSubblockDeflateExtents,
+                             kGapPuffs, kGapPuffExtents);
 }
 
-// TODO(ahassani): add tests for:
-//   TestPatchingEmptyTo9
-//   TestPatchingNoDeflateTo9
-
-// TODO(ahassani): Change tests data if you decided to compress the header of
-// the patch.
-
 }  // namespace puffin
diff --git a/src/puffpatch.cc b/src/puffpatch.cc
index 185b1dd..2dd3a29 100644
--- a/src/puffpatch.cc
+++ b/src/puffpatch.cc
@@ -19,15 +19,15 @@
 #include "puffin/src/include/puffin/huffer.h"
 #include "puffin/src/include/puffin/puffer.h"
 #include "puffin/src/include/puffin/stream.h"
+#include "puffin/src/logging.h"
 #include "puffin/src/puffin.pb.h"
 #include "puffin/src/puffin_stream.h"
-#include "puffin/src/set_errors.h"
-
-namespace puffin {
 
 using std::string;
 using std::vector;
 
+namespace puffin {
+
 const char kMagic[] = "PUF1";
 const size_t kMagicLength = 4;
 
@@ -44,6 +44,55 @@
   }
 }
 
+class BsdiffStream : public bsdiff::FileInterface {
+ public:
+  ~BsdiffStream() override = default;
+
+  static std::unique_ptr<bsdiff::FileInterface> Create(UniqueStreamPtr stream) {
+    TEST_AND_RETURN_VALUE(stream, nullptr);
+    return std::unique_ptr<bsdiff::FileInterface>(
+        new BsdiffStream(std::move(stream)));
+  }
+
+  bool Read(void* buf, size_t count, size_t* bytes_read) override {
+    *bytes_read = 0;
+    if (stream_->Read(buf, count)) {
+      *bytes_read = count;
+      return true;
+    }
+    return false;
+  }
+
+  bool Write(const void* buf, size_t count, size_t* bytes_written) override {
+    *bytes_written = 0;
+    if (stream_->Write(buf, count)) {
+      *bytes_written = count;
+      return true;
+    }
+    return false;
+  }
+
+  bool Seek(off_t pos) override { return stream_->Seek(pos); }
+
+  bool Close() override { return stream_->Close(); }
+
+  bool GetSize(uint64_t* size) override {
+    uint64_t my_size;
+    TEST_AND_RETURN_FALSE(stream_->GetSize(&my_size));
+    *size = my_size;
+    return true;
+  }
+
+ private:
+  explicit BsdiffStream(UniqueStreamPtr stream) : stream_(std::move(stream)) {}
+
+  UniqueStreamPtr stream_;
+
+  DISALLOW_COPY_AND_ASSIGN(BsdiffStream);
+};
+
+}  // namespace
+
 bool DecodePatch(const uint8_t* patch,
                  size_t patch_length,
                  size_t* bsdiff_patch_offset,
@@ -88,48 +137,6 @@
   return true;
 }
 
-class BsdiffStream : public bsdiff::FileInterface {
- public:
-  explicit BsdiffStream(UniqueStreamPtr stream) : stream_(std::move(stream)) {}
-  ~BsdiffStream() override = default;
-
-  bool Read(void* buf, size_t count, size_t* bytes_read) override {
-    *bytes_read = 0;
-    if (stream_->Read(buf, count)) {
-      *bytes_read = count;
-      return true;
-    }
-    return false;
-  }
-
-  bool Write(const void* buf, size_t count, size_t* bytes_written) override {
-    *bytes_written = 0;
-    if (stream_->Write(buf, count)) {
-      *bytes_written = count;
-      return true;
-    }
-    return false;
-  }
-
-  bool Seek(off_t pos) override { return stream_->Seek(pos); }
-
-  bool Close() override { return stream_->Close(); }
-
-  bool GetSize(uint64_t* size) override {
-    uint64_t my_size;
-    TEST_AND_RETURN_FALSE(stream_->GetSize(&my_size));
-    *size = my_size;
-    return true;
-  }
-
- private:
-  UniqueStreamPtr stream_;
-
-  DISALLOW_COPY_AND_ASSIGN(BsdiffStream);
-};
-
-}  // namespace
-
 bool PuffPatch(UniqueStreamPtr src,
                UniqueStreamPtr dst,
                const uint8_t* patch,
@@ -150,19 +157,20 @@
   auto huffer = std::make_shared<Huffer>();
 
   // For reading from source.
-  std::unique_ptr<bsdiff::FileInterface> reader(new BsdiffStream(
+  auto reader = BsdiffStream::Create(
       PuffinStream::CreateForPuff(std::move(src), puffer, src_puff_size,
-                                  src_deflates, src_puffs, max_cache_size)));
+                                  src_deflates, src_puffs, max_cache_size));
+  TEST_AND_RETURN_FALSE(reader);
 
   // For writing into destination.
-  std::unique_ptr<bsdiff::FileInterface> writer(
-      new BsdiffStream(PuffinStream::CreateForHuff(
-          std::move(dst), huffer, dst_puff_size, dst_deflates, dst_puffs)));
+  auto writer = BsdiffStream::Create(PuffinStream::CreateForHuff(
+      std::move(dst), huffer, dst_puff_size, dst_deflates, dst_puffs));
+  TEST_AND_RETURN_FALSE(writer);
 
   // Running bspatch itself.
-  TEST_AND_RETURN_FALSE(
-      0 ==
-      bspatch(reader, writer, &patch[bsdiff_patch_offset], bsdiff_patch_size));
+  TEST_AND_RETURN_FALSE(0 == bspatch(reader, writer,
+                                     &patch[bsdiff_patch_offset],
+                                     bsdiff_patch_size));
   return true;
 }
 
diff --git a/src/sample_generator.cc b/src/sample_generator.cc
deleted file mode 100644
index a2bc7e2..0000000
--- a/src/sample_generator.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2017 The Chromium OS 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 "puffin/src/sample_generator.h"
-
-#include <malloc.h>
-#include <zlib.h>
-
-#include <fstream>
-#include <iomanip>
-#include <iostream>
-#include <string>
-
-#include "puffin/src/bit_reader.h"
-#include "puffin/src/puff_writer.h"
-#include "puffin/src/set_errors.h"
-
-namespace puffin {
-namespace sample_generator {
-
-using std::cerr;
-using std::cout;
-using std::endl;
-using std::string;
-
-bool CompressToDeflate(const Buffer& uncomp,
-                      Buffer* comp,
-                      int compression,
-                      int strategy) {
-  z_stream stream;
-  stream.next_in = (z_const Bytef*)uncomp.data();
-  stream.avail_in = static_cast<unsigned int>(uncomp.size());
-  stream.next_out = comp->data();
-  stream.avail_out = comp->size();
-
-  stream.zalloc = nullptr;
-  stream.zfree = nullptr;
-  stream.opaque = nullptr;
-
-  TEST_AND_RETURN_FALSE(
-      Z_OK == deflateInit2(&stream, compression, Z_DEFLATED, -15, 8, strategy));
-  // If there was not enough output available return error.
-  TEST_AND_RETURN_FALSE(Z_STREAM_END == deflate(&stream, Z_FINISH));
-  TEST_AND_RETURN_FALSE(Z_OK == deflateEnd(&stream));
-  comp->resize(stream.total_out);
-  return true;
-}
-
-// Print an array into hex-format to the output. This can be used to create
-// static arrays for unit testing of the puffer/huffer.
-void PrintArray(const string& name, const Buffer& array) {
-  cout << "const Buffer " << name << " = {" << endl << " ";
-  for (size_t idx = 0; idx < array.size(); idx++) {
-    cout << " 0x" << std::hex << std::uppercase << std::setfill('0')
-         << std::setw(2) << uint(array[idx]);
-    if (idx == array.size() - 1) {
-      cout << std::dec << "};" << endl;
-      return;
-    }
-    cout << ",";
-    if ((idx + 1) % 12 == 0) {
-      cout << endl << " ";
-    }
-  }
-}
-
-bool PrintSample(Puffer* puffer,
-                 int compression,
-                 int strategy,
-                 const Buffer& original) {
-  PrintArray("original", original);
-
-  Buffer comp(original.size() * 4 + 10);
-  TEST_AND_RETURN_FALSE(
-      CompressToDeflate(original, &comp, compression, strategy));
-  PrintArray("compressed", comp);
-
-  Buffer puff(original.size() * 3 + 10);
-  puffin::Error error;
-
-  BufferBitReader bit_reader(comp.data(), comp.size());
-  BufferPuffWriter puff_writer(puff.data(), puff.size());
-  TEST_AND_RETURN_FALSE(
-      puffer->PuffDeflate(&bit_reader, &puff_writer, nullptr, &error));
-  TEST_AND_RETURN_FALSE(comp.size() == bit_reader.Offset());
-
-  puff.resize(puff_writer.Size());
-  PrintArray("puffed", puff);
-  return true;
-}
-
-}  // namespace sample_generator
-}  // namespace puffin
diff --git a/src/sample_generator.h b/src/sample_generator.h
deleted file mode 100644
index 1029d83..0000000
--- a/src/sample_generator.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2017 The Chromium OS 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 SRC_SAMPLE_GENERATOR_H_
-#define SRC_SAMPLE_GENERATOR_H_
-
-#include <string>
-#include <vector>
-
-#include "puffin/src/include/puffin/puffer.h"
-
-namespace puffin {
-namespace sample_generator {
-
-void PrintArray(const std::string& name, const Buffer& array);
-
-// Creates and prints a sample for for adding to the list of unit tests for
-// puffer/huffer.
-//
-// Example:
-//   Buffer orig = {1, 2, 3, 4, 5};
-//   Puffer puffer;
-//   sample_generator::PrintSample(
-//     &puffer, Z_DEFAULT_COMPRESSION, Z_FIXED, orig);
-bool PrintSample(Puffer* puffer,
-                 int compression,
-                 int strategy,
-                 const Buffer& original);
-
-}  // namespace sample_generator
-}  // namespace puffin
-
-#endif  // SRC_SAMPLE_GENERATOR_H_
diff --git a/src/set_errors.h b/src/set_errors.h
deleted file mode 100644
index 2cbd665..0000000
--- a/src/set_errors.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2017 The Chromium OS 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 SRC_SET_ERRORS_H_
-#define SRC_SET_ERRORS_H_
-
-#ifdef USE_BRILLO
-#include "base/logging.h"
-#else
-#include "glog/logging.h"
-#endif
-
-namespace puffin {
-
-#define TEST_AND_RETURN_FALSE(_x)   \
-  do {                              \
-    if (!(_x)) {                    \
-      LOG(ERROR) << #_x " failed."; \
-      return false;                 \
-    }                               \
-  } while (0)
-
-#define TEST_AND_RETURN_VALUE(_x, _v) \
-  do {                                \
-    if (!(_x)) {                      \
-      LOG(ERROR) << #_x " failed.";   \
-      return (_v);                    \
-    }                                 \
-  } while (0)
-
-#define TEST_AND_RETURN_FALSE_SET_ERROR(_x, _error) \
-  do {                                              \
-    if (!(_x)) {                                    \
-      (*error) = (_error);                          \
-      LOG(ERROR) << #_x " failed.";                 \
-      return false;                                 \
-    }                                               \
-  } while (0)
-
-}  // namespace puffin
-
-#endif  // SRC_SET_ERRORS_H_
diff --git a/src/stream_unittest.cc b/src/stream_unittest.cc
index 0a7c7b3..76fe34b 100644
--- a/src/stream_unittest.cc
+++ b/src/stream_unittest.cc
@@ -6,20 +6,20 @@
 
 #include "gtest/gtest.h"
 
-#include "puffin/src/include/puffin/huffer.h"
-#include "puffin/src/include/puffin/puffer.h"
 #include "puffin/src/extent_stream.h"
 #include "puffin/src/file_stream.h"
+#include "puffin/src/include/puffin/huffer.h"
+#include "puffin/src/include/puffin/puffer.h"
 #include "puffin/src/memory_stream.h"
 #include "puffin/src/puffin_stream.h"
 #include "puffin/src/unittest_common.h"
 
-namespace puffin {
-
-using std::string;
 using std::shared_ptr;
+using std::string;
 using std::vector;
 
+namespace puffin {
+
 class StreamTest : public ::testing::Test {
  public:
   // |data| is the content of stream as a buffer.
@@ -175,7 +175,8 @@
 }
 
 TEST_F(StreamTest, FileStreamTest) {
-  string filepath("/tmp/test_filepath");
+  string filepath;
+  ASSERT_TRUE(MakeTempFile(&filepath, nullptr));
   ScopedPathUnlinker scoped_unlinker(filepath);
   ASSERT_FALSE(FileStream::Open(filepath, false, false));
 
@@ -197,47 +198,49 @@
 TEST_F(StreamTest, PuffinStreamTest) {
   shared_ptr<Puffer> puffer(new Puffer());
   auto read_stream = PuffinStream::CreateForPuff(
-      MemoryStream::CreateForRead(kDeflates8), puffer, kPuffs8.size(),
-      kSubblockDeflateExtents8, kPuffExtents8);
-  TestRead(read_stream.get(), kPuffs8);
+      MemoryStream::CreateForRead(kDeflatesSample1), puffer,
+      kPuffsSample1.size(), kSubblockDeflateExtentsSample1,
+      kPuffExtentsSample1);
+  TestRead(read_stream.get(), kPuffsSample1);
   TestSeek(read_stream.get(), false);
   TestClose(read_stream.get());
 
   // Test the stream with puff cache.
   read_stream = PuffinStream::CreateForPuff(
-      MemoryStream::CreateForRead(kDeflates8), puffer, kPuffs8.size(),
-      kSubblockDeflateExtents8, kPuffExtents8, 8 /* max_cache_size */);
-  TestRead(read_stream.get(), kPuffs8);
+      MemoryStream::CreateForRead(kDeflatesSample1), puffer,
+      kPuffsSample1.size(), kSubblockDeflateExtentsSample1, kPuffExtentsSample1,
+      8 /* max_cache_size */);
+  TestRead(read_stream.get(), kPuffsSample1);
   TestSeek(read_stream.get(), false);
   TestClose(read_stream.get());
 
-  Buffer buf(kDeflates8.size());
+  Buffer buf(kDeflatesSample1.size());
   shared_ptr<Huffer> huffer(new Huffer());
   auto write_stream = PuffinStream::CreateForHuff(
-      MemoryStream::CreateForWrite(&buf), huffer, kPuffs8.size(),
-      kSubblockDeflateExtents8, kPuffExtents8);
+      MemoryStream::CreateForWrite(&buf), huffer, kPuffsSample1.size(),
+      kSubblockDeflateExtentsSample1, kPuffExtentsSample1);
 
   ASSERT_TRUE(write_stream->Seek(0));
-  for (size_t idx = 0; idx < kPuffs8.size(); idx++) {
-    ASSERT_TRUE(write_stream->Write(&kPuffs8[idx], 1));
+  for (size_t idx = 0; idx < kPuffsSample1.size(); idx++) {
+    ASSERT_TRUE(write_stream->Write(&kPuffsSample1[idx], 1));
   }
   // Make sure the write works
-  ASSERT_EQ(buf, kDeflates8);
+  ASSERT_EQ(buf, kDeflatesSample1);
 
   std::fill(buf.begin(), buf.end(), 0);
   ASSERT_TRUE(write_stream->Seek(0));
-  ASSERT_TRUE(write_stream->Write(kPuffs8.data(), kPuffs8.size()));
+  ASSERT_TRUE(write_stream->Write(kPuffsSample1.data(), kPuffsSample1.size()));
   // Check its correctness.
-  ASSERT_EQ(buf, kDeflates8);
+  ASSERT_EQ(buf, kDeflatesSample1);
 
   // Write entire buffer one byte at a time. (all zeros).
   std::fill(buf.begin(), buf.end(), 0);
   ASSERT_TRUE(write_stream->Seek(0));
-  for (const auto& byte : kPuffs8) {
+  for (const auto& byte : kPuffsSample1) {
     ASSERT_TRUE(write_stream->Write(&byte, 1));
   }
   // Check its correctness.
-  ASSERT_EQ(buf, kDeflates8);
+  ASSERT_EQ(buf, kDeflatesSample1);
 
   // No TestSeek is needed as PuffinStream is not supposed to seek to anywhere
   // except 0.
diff --git a/src/unittest_common.cc b/src/unittest_common.cc
index b542740..7b16011 100644
--- a/src/unittest_common.cc
+++ b/src/unittest_common.cc
@@ -4,12 +4,16 @@
 
 #include "puffin/src/unittest_common.h"
 
-namespace puffin {
-
 using std::string;
 
+namespace puffin {
+
 bool MakeTempFile(string* filename, int* fd) {
+#ifdef __ANDROID__
+  char tmp_template[] = "/data/local/tmp/puffin-XXXXXX";
+#else
   char tmp_template[] = "/tmp/puffin-XXXXXX";
+#endif  // __ANDROID__
   int mkstemp_fd = mkstemp(tmp_template);
   TEST_AND_RETURN_FALSE(mkstemp_fd >= 0);
   if (filename) {
@@ -23,4 +27,53 @@
   return true;
 }
 
+// clang-format off
+const Buffer kDeflatesSample1 = {
+    /* raw   0 */ 0x11, 0x22,
+    /* def   2 */ 0x63, 0x64, 0x62, 0x66, 0x61, 0x05, 0x00,
+    /* raw   9 */ 0x33,
+    /* def  10 */ 0x03, 0x00,
+    /* raw  12 */
+    /* def  12 */ 0x63, 0x04, 0x00,
+    /* raw  15 */ 0x44, 0x55
+};
+const Buffer kPuffsSample1 = {
+    /* raw   0 */ 0x11, 0x22,
+    /* puff  2 */ 0x00, 0x00, 0xA0, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05, 0xFF,
+                  0x81,
+    /* raw  13 */ 0x00, 0x33,
+    /* puff 15 */ 0x00, 0x00, 0xA0, 0xFF, 0x81,
+    /* raw  20 */ 0x00,
+    /* puff 21 */ 0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81,
+    /* raw  28 */ 0x00, 0x44, 0x55
+};
+const std::vector<ByteExtent> kDeflateExtentsSample1 = {
+  {2, 7}, {10, 2}, {12, 3}};
+const std::vector<BitExtent> kSubblockDeflateExtentsSample1 = {
+  {16, 50}, {80, 10}, {96, 18}};
+const std::vector<ByteExtent> kPuffExtentsSample1 = {{2, 11}, {15, 5}, {21, 7}};
+
+const Buffer kDeflatesSample2 = {
+    /* def  0  */ 0x63, 0x64, 0x62, 0x66, 0x61, 0x05, 0x00,
+    /* raw  7  */ 0x33, 0x66,
+    /* def  9  */ 0x01, 0x05, 0x00, 0xFA, 0xFF, 0x01, 0x02, 0x03, 0x04, 0x05,
+    /* def  19 */ 0x63, 0x04, 0x00
+};
+const Buffer kPuffsSample2 = {
+    /* puff  0 */ 0x00, 0x00, 0xA0, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05, 0xFF,
+                  0x81,
+    /* raw  11 */ 0x00, 0x33, 0x66,
+    /* puff 14 */ 0x00, 0x00, 0x80, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05, 0xFF,
+                  0x81,
+    /* puff 25 */ 0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81,
+    /* raw  32 */ 0x00,
+};
+const std::vector<ByteExtent> kDeflateExtentsSample2 = {
+  {0, 7}, {9, 10}, {19, 3}};
+const std::vector<BitExtent> kSubblockDeflateExtentsSample2 = {
+  {0, 50}, {72, 80}, {152, 18}};
+const std::vector<ByteExtent> kPuffExtentsSample2 = {
+  {0, 11}, {14, 11}, {25, 7}};
+// clang-format on
+
 }  // namespace puffin
diff --git a/src/unittest_common.h b/src/unittest_common.h
index c03aea4..c73d9b3 100644
--- a/src/unittest_common.h
+++ b/src/unittest_common.h
@@ -9,7 +9,7 @@
 #include <vector>
 
 #include "puffin/src/include/puffin/common.h"
-#include "puffin/src/set_errors.h"
+#include "puffin/src/logging.h"
 
 namespace puffin {
 
@@ -34,408 +34,17 @@
 // values.
 bool MakeTempFile(std::string* filename, int* fd);
 
-// clang-format off
-// Uncompressed deflate block.
-const Buffer kRaw1 = {0x01, 0x02, 0x03, 0x04, 0x05};
-const Buffer kDeflate1 = {
-  0x01, 0x05, 0x00, 0xFA, 0xFF, 0x01, 0x02, 0x03, 0x04, 0x05};
-const Buffer kPuff1 = {
-  0x00, 0x00, 0x80, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05, 0xFF, 0x81};
+extern const Buffer kDeflatesSample1;
+extern const Buffer kPuffsSample1;
+extern const std::vector<ByteExtent> kDeflateExtentsSample1;
+extern const std::vector<BitExtent> kSubblockDeflateExtentsSample1;
+extern const std::vector<ByteExtent> kPuffExtentsSample1;
 
-// Uncompressed deflate block with zero length.
-const Buffer kRaw1_1 = {};
-const Buffer kDeflate1_1 = {0x01, 0x00, 0x00, 0xFF, 0xFF};
-const Buffer kPuff1_1 = {0x00, 0x00, 0x80, 0xFF, 0x81};
-
-// Fixed huffman table compressed deflate.
-const Buffer kRaw2 = {0x01};
-const Buffer kDeflate2 = {0x63, 0x04, 0x00};
-const Buffer kPuff2 = {0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81};
-
-// Deflate of an empty buffer.
-const Buffer kRaw3 = {};
-const Buffer kDeflate3 = {0x03, 0x00};
-const Buffer kPuff3 = {0x00, 0x00, 0xA0, 0xFF, 0x81};
-
-// Deflate with fixed Huffman table.
-const Buffer kRaw4 = {0x01, 0x02, 0x03, 0x04, 0x05};
-const Buffer kDeflate4 = {0x63, 0x64, 0x62, 0x66, 0x61, 0x05, 0x00};
-const Buffer kPuff4 = {
-  0x00, 0x00, 0xA0, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05, 0xFF, 0x81};
-
-// Invalid LEN/NLEN for uncompressed deflate block.
-const Buffer kDeflate5 = {
-  0x01, 0x05, 0x00, 0xFF, 0xFF, 0x01, 0x02, 0x03, 0x04, 0x05};
-
-// Deflate with invalid block header.
-const Buffer kDeflate6 = {0x07};
-
-// Deflate with final block bit unset.
-const Buffer kRaw7 = {0x01};
-const Buffer kDeflate7 = {0x62, 0x04, 0x00};
-const Buffer kPuff7 = {0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81};
-
-// Two deflate buffers concatenated, neither have their final bit set.  It is a
-// valid deflate and puff buffer.
-const Buffer kRaw7_2 = {0x01, 0x01};
-const Buffer kDeflate7_2 = {0x62, 0x04, 0x88, 0x11, 0x00};
-const Buffer kPuff7_2 = {
-  0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,
-  0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81};
-
-// Two deflate buffers concatenated, the first one has final bit set, second one
-// not. It is a valid deflate and puff buffer.
-const Buffer kRaw7_3 = {0x01, 0x01};
-const Buffer kDeflate7_3 = {0x63, 0x04, 0x88, 0x11, 0x00};
-const Buffer kPuff7_3 = {
-  0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81,
-  0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81};
-
-// Two deflate buffers concatenated, both have final bits set. It is a valid
-// deflate and puff buffer.
-const Buffer kRaw7_4 = {0x01, 0x01};
-const Buffer kDeflate7_4 = {0x63, 0x04, 0x8C, 0x11, 0x00};
-const Buffer kPuff7_4 = {
-  0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81,
-  0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81};
-
-const Buffer kDeflates8 = {
-  /* raw      0  */ 0x11, 0x22,
-  /* deflate  2  */ 0x63, 0x64, 0x62, 0x66, 0x61, 0x05, 0x00,
-  /* raw      9  */ 0x33,
-  /* deflate  10 */ 0x03, 0x00,
-  /* raw      12 */
-  /* deflate  12 */ 0x63, 0x04, 0x00,
-  /* raw      15 */ 0x44, 0x55
-};
-
-const Buffer kPuffs8 = {
-  /* raw      0  */ 0x11, 0x22,
-  /* puff     2  */ 0x00, 0x00, 0xA0, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05, 0xFF,
-                    0x81,
-  /* raw      13 */ 0x00, 0x33,
-  /* puff     15 */ 0x00, 0x00, 0xA0, 0xFF, 0x81,
-  /* raw      20 */ 0x00,
-  /* puff     21 */ 0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81,
-  /* raw      28 */ 0x00, 0x44, 0x55
-};
-
-const std::vector<ByteExtent> kDeflateExtents8 = {{2, 7}, {10, 2}, {12, 3}};
-const std::vector<BitExtent> kSubblockDeflateExtents8 = {
-  {16, 50}, {80, 10}, {96, 18}};
-const std::vector<ByteExtent> kPuffExtents8 = {{2, 11}, {15, 5}, {21, 7}};
-
-const Buffer kDeflates9 = {
-  /* deflate  0  */ 0x63, 0x64, 0x62, 0x66, 0x61, 0x05, 0x00,
-  /* raw      7  */ 0x33, 0x66,
-  /* deflate  9  */ 0x01, 0x05, 0x00, 0xFA, 0xFF, 0x01, 0x02, 0x03, 0x04, 0x05,
-  /* deflate  19 */ 0x63, 0x04, 0x00
-};
-
-const Buffer kPuffs9 = {
-  /* puff      0 */ 0x00, 0x00, 0xA0, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05, 0xFF,
-                    0x81,
-  /* raw      11 */ 0x00, 0x33, 0x66,
-  /* puff     14 */ 0x00, 0x00, 0x80, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05, 0xFF,
-                    0x81,
-  /* puff     25 */ 0x00, 0x00, 0xA0, 0x00, 0x01, 0xFF, 0x81,
-  /* raw      32 */ 0x00,
-};
-
-const std::vector<ByteExtent> kDeflateExtents9 = {{0, 7}, {9, 10}, {19, 3}};
-const std::vector<BitExtent> kSubblockDeflateExtents9 = {
-  {0, 50}, {72, 80}, {152, 18}};
-const std::vector<ByteExtent> kPuffExtents9 = {{0, 11}, {14, 11}, {25, 7}};
-
-const Buffer kPatch8To9 = {
-  0x50, 0x55, 0x46, 0x31, 0x00, 0x00, 0x00, 0x51, 0x08, 0x01, 0x12, 0x27,
-  0x0A, 0x04, 0x08, 0x10, 0x10, 0x32, 0x0A, 0x04, 0x08, 0x50, 0x10, 0x0A,
-  0x0A, 0x04, 0x08, 0x60, 0x10, 0x12, 0x12, 0x04, 0x08, 0x10, 0x10, 0x58,
-  0x12, 0x04, 0x08, 0x78, 0x10, 0x28, 0x12, 0x05, 0x08, 0xA8, 0x01, 0x10,
-  0x38, 0x18, 0x1F, 0x1A, 0x24, 0x0A, 0x02, 0x10, 0x32, 0x0A, 0x04, 0x08,
-  0x48, 0x10, 0x50, 0x0A, 0x05, 0x08, 0x98, 0x01, 0x10, 0x12, 0x12, 0x02,
-  0x10, 0x58, 0x12, 0x04, 0x08, 0x70, 0x10, 0x58, 0x12, 0x05, 0x08, 0xC8,
-  0x01, 0x10, 0x38, 0x18, 0x21, 0x42, 0x53, 0x44, 0x49, 0x46, 0x46, 0x34,
-  0x30, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x42, 0x5A, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xD1,
-  0x20, 0xBB, 0x7E, 0x00, 0x00, 0x03, 0x60, 0x40, 0x78, 0x0E, 0x08, 0x00,
-  0x40, 0x00, 0x20, 0x00, 0x31, 0x06, 0x4C, 0x40, 0x92, 0x8F, 0x46, 0xA7,
-  0xA8, 0xE0, 0xF3, 0xD6, 0x21, 0x12, 0xF4, 0xBC, 0x43, 0x32, 0x1F, 0x17,
-  0x72, 0x45, 0x38, 0x50, 0x90, 0xD1, 0x20, 0xBB, 0x7E, 0x42, 0x5A, 0x68,
-  0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xF1, 0x20, 0x5F, 0x0D, 0x00,
-  0x00, 0x02, 0x41, 0x15, 0x42, 0x08, 0x20, 0x00, 0x40, 0x00, 0x00, 0x02,
-  0x40, 0x00, 0x20, 0x00, 0x22, 0x3D, 0x23, 0x10, 0x86, 0x03, 0x96, 0x54,
-  0x11, 0x16, 0x5F, 0x17, 0x72, 0x45, 0x38, 0x50, 0x90, 0xF1, 0x20, 0x5F,
-  0x0D, 0x42, 0x5A, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0x07,
-  0xD4, 0xCB, 0x6E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x20, 0x00,
-  0x21, 0x18, 0x46, 0x82, 0xEE, 0x48, 0xA7, 0x0A, 0x12, 0x00, 0xFA, 0x99,
-  0x6D, 0xC0};
-
-const Buffer kPatch9To8 = {
-  0x50, 0x55, 0x46, 0x31, 0x00, 0x00, 0x00, 0x51, 0x08, 0x01, 0x12, 0x24,
-  0x0A, 0x02, 0x10, 0x32, 0x0A, 0x04, 0x08, 0x48, 0x10, 0x50, 0x0A, 0x05,
-  0x08, 0x98, 0x01, 0x10, 0x12, 0x12, 0x02, 0x10, 0x58, 0x12, 0x04, 0x08,
-  0x70, 0x10, 0x58, 0x12, 0x05, 0x08, 0xC8, 0x01, 0x10, 0x38, 0x18, 0x21,
-  0x1A, 0x27, 0x0A, 0x04, 0x08, 0x10, 0x10, 0x32, 0x0A, 0x04, 0x08, 0x50,
-  0x10, 0x0A, 0x0A, 0x04, 0x08, 0x60, 0x10, 0x12, 0x12, 0x04, 0x08, 0x10,
-  0x10, 0x58, 0x12, 0x04, 0x08, 0x78, 0x10, 0x28, 0x12, 0x05, 0x08, 0xA8,
-  0x01, 0x10, 0x38, 0x18, 0x1F, 0x42, 0x53, 0x44, 0x49, 0x46, 0x46, 0x34,
-  0x30, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x42, 0x5A, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0x3D,
-  0xBD, 0x08, 0x91, 0x00, 0x00, 0x01, 0xE0, 0x40, 0x5C, 0x0A, 0x40, 0x00,
-  0x40, 0x00, 0x20, 0x00, 0x31, 0x0C, 0x08, 0x23, 0xD2, 0x34, 0xD1, 0xB1,
-  0x73, 0x60, 0x44, 0x54, 0xE4, 0xFC, 0x5D, 0xC9, 0x14, 0xE1, 0x42, 0x40,
-  0xF6, 0xF4, 0x22, 0x44, 0x42, 0x5A, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26,
-  0x53, 0x59, 0x41, 0x62, 0x2E, 0xF0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40,
-  0x20, 0x20, 0x00, 0x21, 0x00, 0x82, 0x83, 0x17, 0x72, 0x45, 0x38, 0x50,
-  0x90, 0x41, 0x62, 0x2E, 0xF0, 0x42, 0x5A, 0x68, 0x39, 0x31, 0x41, 0x59,
-  0x26, 0x53, 0x59, 0xE0, 0x20, 0x04, 0x57, 0x00, 0x00, 0x04, 0x76, 0x50,
-  0xE0, 0x00, 0x20, 0x00, 0x10, 0x00, 0x04, 0x00, 0x02, 0x00, 0x20, 0x00,
-  0x40, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x21, 0xA1, 0xA3, 0x10, 0x83, 0x26,
-  0x21, 0x5E, 0xB2, 0x69, 0xAC, 0x70, 0x60, 0x53, 0xC5, 0xDC, 0x91, 0x4E,
-  0x14, 0x24, 0x38, 0x08, 0x01, 0x15, 0xC0};
-
-const Buffer kPatch8ToEmpty = {
-  0x50, 0x55, 0x46, 0x31, 0x00, 0x00, 0x00, 0x2D, 0x08, 0x01, 0x12, 0x27,
-  0x0A, 0x04, 0x08, 0x10, 0x10, 0x32, 0x0A, 0x04, 0x08, 0x50, 0x10, 0x0A,
-  0x0A, 0x04, 0x08, 0x60, 0x10, 0x12, 0x12, 0x04, 0x08, 0x10, 0x10, 0x58,
-  0x12, 0x04, 0x08, 0x78, 0x10, 0x28, 0x12, 0x05, 0x08, 0xA8, 0x01, 0x10,
-  0x38, 0x18, 0x1F, 0x1A, 0x00, 0x42, 0x53, 0x44, 0x49, 0x46, 0x46, 0x34,
-  0x30, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x42, 0x5A, 0x68, 0x39, 0x17, 0x72, 0x45, 0x38, 0x50, 0x90, 0x00,
-  0x00, 0x00, 0x00, 0x42, 0x5A, 0x68, 0x39, 0x17, 0x72, 0x45, 0x38, 0x50,
-  0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x5A, 0x68, 0x39, 0x17, 0x72, 0x45,
-  0x38, 0x50, 0x90, 0x00, 0x00, 0x00, 0x00};
-
-const Buffer kPatch8ToNoDeflate = {
-  0x50, 0x55, 0x46, 0x31, 0x00, 0x00, 0x00, 0x2F, 0x08, 0x01, 0x12, 0x27,
-  0x0A, 0x04, 0x08, 0x10, 0x10, 0x32, 0x0A, 0x04, 0x08, 0x50, 0x10, 0x0A,
-  0x0A, 0x04, 0x08, 0x60, 0x10, 0x12, 0x12, 0x04, 0x08, 0x10, 0x10, 0x58,
-  0x12, 0x04, 0x08, 0x78, 0x10, 0x28, 0x12, 0x05, 0x08, 0xA8, 0x01, 0x10,
-  0x38, 0x18, 0x1F, 0x1A, 0x02, 0x18, 0x04, 0x42, 0x53, 0x44, 0x49, 0x46,
-  0x46, 0x34, 0x30, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x42, 0x5A, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53,
-  0x59, 0xBA, 0x8D, 0x7F, 0x2D, 0x00, 0x00, 0x00, 0x40, 0x00, 0x44, 0x08,
-  0x20, 0x00, 0x30, 0xCC, 0x09, 0x32, 0x54, 0x65, 0x38, 0xBB, 0x92, 0x29,
-  0xC2, 0x84, 0x85, 0xD4, 0x6B, 0xF9, 0x68, 0x42, 0x5A, 0x68, 0x39, 0x17,
-  0x72, 0x45, 0x38, 0x50, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x5A, 0x68,
-  0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xE7, 0xAA, 0xF1, 0xFC, 0x00,
-  0x00, 0x00, 0x70, 0x00, 0x00, 0x08, 0x01, 0x00, 0x20, 0x04, 0x20, 0x00,
-  0x21, 0x9A, 0x68, 0x33, 0x4D, 0x13, 0x3C, 0x5D, 0xC9, 0x14, 0xE1, 0x42,
-  0x43, 0x9E, 0xAB, 0xC7, 0xF0};
-
-// It is actuall the content of the copyright header.
-const Buffer kRaw10 = {
-  0x0A, 0x2F, 0x2F, 0x0A, 0x2F, 0x2F, 0x20, 0x43, 0x6F, 0x70, 0x79, 0x72,
-  0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, 0x32, 0x30, 0x31,
-  0x37, 0x20, 0x54, 0x68, 0x65, 0x20, 0x41, 0x6E, 0x64, 0x72, 0x6F, 0x69,
-  0x64, 0x20, 0x4F, 0x70, 0x65, 0x6E, 0x20, 0x53, 0x6F, 0x75, 0x72, 0x63,
-  0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x0A, 0x2F, 0x2F,
-  0x0A, 0x2F, 0x2F, 0x20, 0x4C, 0x69, 0x63, 0x65, 0x6E, 0x73, 0x65, 0x64,
-  0x20, 0x75, 0x6E, 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x41,
-  0x70, 0x61, 0x63, 0x68, 0x65, 0x20, 0x4C, 0x69, 0x63, 0x65, 0x6E, 0x73,
-  0x65, 0x2C, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x32,
-  0x2E, 0x30, 0x20, 0x28, 0x74, 0x68, 0x65, 0x20, 0x22, 0x4C, 0x69, 0x63,
-  0x65, 0x6E, 0x73, 0x65, 0x22, 0x29, 0x3B, 0x0A, 0x2F, 0x2F, 0x20, 0x79,
-  0x6F, 0x75, 0x20, 0x6D, 0x61, 0x79, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x75,
-  0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x66, 0x69, 0x6C, 0x65,
-  0x20, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x20, 0x69, 0x6E, 0x20, 0x63,
-  0x6F, 0x6D, 0x70, 0x6C, 0x69, 0x61, 0x6E, 0x63, 0x65, 0x20, 0x77, 0x69,
-  0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4C, 0x69, 0x63, 0x65, 0x6E,
-  0x73, 0x65, 0x2E, 0x0A, 0x2F, 0x2F, 0x20, 0x59, 0x6F, 0x75, 0x20, 0x6D,
-  0x61, 0x79, 0x20, 0x6F, 0x62, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x61, 0x20,
-  0x63, 0x6F, 0x70, 0x79, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20,
-  0x4C, 0x69, 0x63, 0x65, 0x6E, 0x73, 0x65, 0x20, 0x61, 0x74, 0x0A, 0x2F,
-  0x2F, 0x0A, 0x2F, 0x2F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x74,
-  0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x61, 0x70, 0x61,
-  0x63, 0x68, 0x65, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x6C, 0x69, 0x63, 0x65,
-  0x6E, 0x73, 0x65, 0x73, 0x2F, 0x4C, 0x49, 0x43, 0x45, 0x4E, 0x53, 0x45,
-  0x2D, 0x32, 0x2E, 0x30, 0x0A, 0x2F, 0x2F, 0x0A, 0x2F, 0x2F, 0x20, 0x55,
-  0x6E, 0x6C, 0x65, 0x73, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,
-  0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63,
-  0x61, 0x62, 0x6C, 0x65, 0x20, 0x6C, 0x61, 0x77, 0x20, 0x6F, 0x72, 0x20,
-  0x61, 0x67, 0x72, 0x65, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x69, 0x6E,
-  0x20, 0x77, 0x72, 0x69, 0x74, 0x69, 0x6E, 0x67, 0x2C, 0x20, 0x73, 0x6F,
-  0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0A, 0x2F, 0x2F, 0x20, 0x64, 0x69,
-  0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x20, 0x75, 0x6E,
-  0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4C, 0x69, 0x63, 0x65,
-  0x6E, 0x73, 0x65, 0x20, 0x69, 0x73, 0x20, 0x64, 0x69, 0x73, 0x74, 0x72,
-  0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x20, 0x6F, 0x6E, 0x20, 0x61, 0x6E,
-  0x20, 0x22, 0x41, 0x53, 0x20, 0x49, 0x53, 0x22, 0x20, 0x42, 0x41, 0x53,
-  0x49, 0x53, 0x2C, 0x0A, 0x2F, 0x2F, 0x20, 0x57, 0x49, 0x54, 0x48, 0x4F,
-  0x55, 0x54, 0x20, 0x57, 0x41, 0x52, 0x52, 0x41, 0x4E, 0x54, 0x49, 0x45,
-  0x53, 0x20, 0x4F, 0x52, 0x20, 0x43, 0x4F, 0x4E, 0x44, 0x49, 0x54, 0x49,
-  0x4F, 0x4E, 0x53, 0x20, 0x4F, 0x46, 0x20, 0x41, 0x4E, 0x59, 0x20, 0x4B,
-  0x49, 0x4E, 0x44, 0x2C, 0x20, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20,
-  0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x6F, 0x72, 0x20, 0x69,
-  0x6D, 0x70, 0x6C, 0x69, 0x65, 0x64, 0x2E, 0x0A, 0x2F, 0x2F, 0x20, 0x53,
-  0x65, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4C, 0x69, 0x63, 0x65, 0x6E,
-  0x73, 0x65, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
-  0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x6C, 0x61, 0x6E, 0x67,
-  0x75, 0x61, 0x67, 0x65, 0x20, 0x67, 0x6F, 0x76, 0x65, 0x72, 0x6E, 0x69,
-  0x6E, 0x67, 0x20, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x73, 0x69, 0x6F,
-  0x6E, 0x73, 0x20, 0x61, 0x6E, 0x64, 0x0A, 0x2F, 0x2F, 0x20, 0x6C, 0x69,
-  0x6D, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x20, 0x75, 0x6E,
-  0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4C, 0x69, 0x63, 0x65,
-  0x6E, 0x73, 0x65, 0x2E, 0x0A};
-
-// Dynamic huffman compressed deflate.
-const Buffer kDeflate10 = {
-  0x65, 0x91, 0x41, 0x6F, 0x9C, 0x30, 0x10, 0x85, 0xEF, 0xFB, 0x2B, 0x9E,
-  0xF6, 0x94, 0x48, 0x5B, 0x48, 0x73, 0xA9, 0xD4, 0x9E, 0xE8, 0x66, 0xAB,
-  0xA0, 0x46, 0x50, 0x2D, 0xA4, 0x51, 0x8E, 0x5E, 0x18, 0xD8, 0x89, 0x58,
-  0xDB, 0xB5, 0x4D, 0xC9, 0xFE, 0xFB, 0x8E, 0x59, 0x22, 0x25, 0xAA, 0x2F,
-  0xC8, 0xCC, 0xCC, 0x9B, 0xEF, 0x3D, 0xAF, 0xD2, 0x74, 0x95, 0xA6, 0xD8,
-  0x1A, 0x7B, 0x76, 0xDC, 0x1F, 0x03, 0xAE, 0xB6, 0xD7, 0xB8, 0xBD, 0xF9,
-  0xFC, 0x05, 0xF5, 0x91, 0x90, 0xE9, 0xD6, 0x19, 0x6E, 0x51, 0x5A, 0xD2,
-  0xA8, 0xCC, 0xE8, 0x1A, 0xC2, 0x2F, 0x67, 0x5E, 0xA8, 0x09, 0xAB, 0xCB,
-  0xE0, 0x03, 0x37, 0xA4, 0x3D, 0xB5, 0x18, 0x75, 0x4B, 0x0E, 0x21, 0x0E,
-  0x59, 0xD5, 0xC8, 0x67, 0xA9, 0x6C, 0xF0, 0x9B, 0x9C, 0x67, 0xA3, 0x71,
-  0x9B, 0xDC, 0xE0, 0x2A, 0x36, 0xAC, 0x97, 0xD2, 0xFA, 0xFA, 0x5B, 0x94,
-  0x38, 0x9B, 0x11, 0x27, 0x75, 0x86, 0x36, 0x01, 0xA3, 0x27, 0xD1, 0x60,
-  0x8F, 0x8E, 0x07, 0x02, 0xBD, 0x36, 0x64, 0x03, 0x58, 0xA3, 0x31, 0x27,
-  0x3B, 0xB0, 0xD2, 0xB2, 0x7F, 0xE2, 0x70, 0x9C, 0xF7, 0x2C, 0x2A, 0x49,
-  0xD4, 0x78, 0x5E, 0x34, 0xCC, 0x21, 0x28, 0x69, 0x57, 0x32, 0x60, 0xE5,
-  0xD6, 0xBD, 0x6F, 0x84, 0x7A, 0x83, 0x9E, 0xCF, 0x31, 0x04, 0xFB, 0x35,
-  0x4D, 0xA7, 0x69, 0x4A, 0xD4, 0x4C, 0x9C, 0x18, 0xD7, 0xA7, 0xC3, 0xA5,
-  0xD7, 0xA7, 0x0F, 0xF9, 0x76, 0x57, 0x54, 0xBB, 0x4F, 0x42, 0xBD, 0x4C,
-  0x3D, 0xEA, 0x81, 0xBC, 0x87, 0xA3, 0x3F, 0x23, 0x3B, 0x71, 0x7C, 0x38,
-  0x43, 0x59, 0xA1, 0x6A, 0xD4, 0x41, 0x58, 0x07, 0x35, 0xC1, 0x38, 0xA8,
-  0xDE, 0x91, 0xD4, 0x82, 0x89, 0xD4, 0x93, 0xE3, 0xC0, 0xBA, 0xDF, 0xC0,
-  0x9B, 0x2E, 0x4C, 0xCA, 0x51, 0x94, 0x69, 0xD9, 0x07, 0xC7, 0x87, 0x31,
-  0x7C, 0x08, 0xED, 0x8D, 0x51, 0xAC, 0xBF, 0x6F, 0x90, 0xD8, 0x94, 0xC6,
-  0x3A, 0xAB, 0x90, 0x57, 0x6B, 0x7C, 0xCF, 0xAA, 0xBC, 0xDA, 0x44, 0x91,
-  0xA7, 0xBC, 0xBE, 0x2F, 0x1F, 0x6B, 0x3C, 0x65, 0xFB, 0x7D, 0x56, 0xD4,
-  0xF9, 0xAE, 0x42, 0xB9, 0xC7, 0xB6, 0x2C, 0xEE, 0xF2, 0x3A, 0x2F, 0x0B,
-  0xB9, 0xFD, 0x40, 0x56, 0x3C, 0xE3, 0x67, 0x5E, 0xDC, 0x6D, 0x40, 0x12,
-  0x99, 0xEC, 0xA1, 0x57, 0xEB, 0xA2, 0x03, 0xC1, 0xE4, 0x18, 0x27, 0xB5,
-  0x73, 0x76, 0x15, 0xD1, 0x07, 0x84, 0xCE, 0x5C, 0x90, 0xBC, 0xA5, 0x86,
-  0x3B, 0x6E, 0xC4, 0x9A, 0xEE, 0x47, 0xD5, 0x13, 0x7A, 0xF3, 0x97, 0x9C,
-  0x16, 0x47, 0xB0, 0xE4, 0x4E, 0xEC, 0xE3, 0xB3, 0x7A, 0x01, 0x6C, 0xA3,
-  0xCC, 0xC0, 0x27, 0x0E, 0x2A, 0xCC, 0xBF, 0xFE, 0xF3, 0x95, 0xAC, 0xFE,
-  0x01};
-
-const Buffer kPuff10 = {
-  0x00, 0x74, 0xC0, 0x0C, 0x11, 0x0C, 0x04, 0x63, 0x34, 0x32, 0x03, 0x04,
-  0x05, 0x06, 0x1B, 0x07, 0x26, 0x03, 0x00, 0x07, 0x16, 0x08, 0x08, 0x00,
-  0x00, 0x07, 0x09, 0x06, 0x06, 0x08, 0x09, 0x08, 0x15, 0x09, 0x00, 0x00,
-  0x09, 0x09, 0x16, 0x06, 0x09, 0x07, 0x08, 0x07, 0x09, 0x00, 0x08, 0x06,
-  0x00, 0x09, 0x08, 0x00, 0x06, 0x06, 0x09, 0x00, 0x07, 0x06, 0x06, 0x08,
-  0x09, 0x08, 0x00, 0x08, 0x18, 0x05, 0x07, 0x06, 0x06, 0x04, 0x06, 0x06,
-  0x07, 0x04, 0x08, 0x00, 0x06, 0x07, 0x05, 0x05, 0x05, 0x09, 0x05, 0x05,
-  0x05, 0x06, 0x09, 0x06, 0x08, 0x07, 0x97, 0x09, 0x04, 0x05, 0x06, 0x07,
-  0x06, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x09, 0x05, 0x15, 0x06, 0x00,
-  0x05, 0x06, 0x04, 0x04, 0x04, 0x03, 0x04, 0x02, 0x03, 0x03, 0x05, 0x39,
-  0x0A, 0x2F, 0x2F, 0x0A, 0x2F, 0x2F, 0x20, 0x43, 0x6F, 0x70, 0x79, 0x72,
-  0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, 0x32, 0x30, 0x31,
-  0x37, 0x20, 0x54, 0x68, 0x65, 0x20, 0x41, 0x6E, 0x64, 0x72, 0x6F, 0x69,
-  0x64, 0x20, 0x4F, 0x70, 0x65, 0x6E, 0x20, 0x53, 0x6F, 0x75, 0x72, 0x63,
-  0x65, 0x20, 0x50, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x0A, 0x83, 0x00,
-  0x38, 0x0F, 0x4C, 0x69, 0x63, 0x65, 0x6E, 0x73, 0x65, 0x64, 0x20, 0x75,
-  0x6E, 0x64, 0x65, 0x72, 0x20, 0x74, 0x81, 0x00, 0x34, 0x02, 0x70, 0x61,
-  0x63, 0x80, 0x00, 0x06, 0x84, 0x00, 0x19, 0x0E, 0x2C, 0x20, 0x56, 0x65,
-  0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x32, 0x2E, 0x30, 0x20, 0x28, 0x81,
-  0x00, 0x20, 0x00, 0x22, 0x84, 0x00, 0x1A, 0x02, 0x22, 0x29, 0x3B, 0x81,
-  0x00, 0x42, 0x0E, 0x79, 0x6F, 0x75, 0x20, 0x6D, 0x61, 0x79, 0x20, 0x6E,
-  0x6F, 0x74, 0x20, 0x75, 0x73, 0x65, 0x80, 0x00, 0x43, 0x19, 0x69, 0x73,
-  0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74,
-  0x20, 0x69, 0x6E, 0x20, 0x63, 0x6F, 0x6D, 0x70, 0x6C, 0x69, 0x61, 0x6E,
-  0x80, 0x00, 0x7F, 0x03, 0x77, 0x69, 0x74, 0x68, 0x82, 0x00, 0x67, 0x84,
-  0x00, 0x45, 0x00, 0x2E, 0x81, 0x00, 0x43, 0x00, 0x59, 0x84, 0x00, 0x43,
-  0x03, 0x6F, 0x62, 0x74, 0x61, 0x80, 0x00, 0x2E, 0x00, 0x61, 0x80, 0x00,
-  0x30, 0x00, 0x70, 0x80, 0x00, 0x0D, 0x00, 0x66, 0x89, 0x00, 0x28, 0x01,
-  0x20, 0x61, 0x85, 0x00, 0xB4, 0x82, 0x00, 0x00, 0x0B, 0x68, 0x74, 0x74,
-  0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x61, 0x82, 0x00, 0xB1,
-  0x05, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x6C, 0x83, 0x00, 0x2B, 0x09, 0x73,
-  0x2F, 0x4C, 0x49, 0x43, 0x45, 0x4E, 0x53, 0x45, 0x2D, 0x80, 0x00, 0xB5,
-  0x84, 0x00, 0x35, 0x0C, 0x55, 0x6E, 0x6C, 0x65, 0x73, 0x73, 0x20, 0x72,
-  0x65, 0x71, 0x75, 0x69, 0x72, 0x80, 0x00, 0xF1, 0x04, 0x62, 0x79, 0x20,
-  0x61, 0x70, 0x80, 0x00, 0x95, 0x02, 0x63, 0x61, 0x62, 0x80, 0x00, 0xAB,
-  0x0A, 0x6C, 0x61, 0x77, 0x20, 0x6F, 0x72, 0x20, 0x61, 0x67, 0x72, 0x65,
-  0x80, 0x00, 0x1B, 0x01, 0x74, 0x6F, 0x81, 0x00, 0xB5, 0x10, 0x77, 0x72,
-  0x69, 0x74, 0x69, 0x6E, 0x67, 0x2C, 0x20, 0x73, 0x6F, 0x66, 0x74, 0x77,
-  0x61, 0x72, 0x65, 0x81, 0x00, 0x46, 0x08, 0x64, 0x69, 0x73, 0x74, 0x72,
-  0x69, 0x62, 0x75, 0x74, 0x8A, 0x01, 0x34, 0x85, 0x00, 0xA3, 0x80, 0x00,
-  0xFA, 0x89, 0x00, 0x20, 0x80, 0x01, 0x36, 0x10, 0x61, 0x6E, 0x20, 0x22,
-  0x41, 0x53, 0x20, 0x49, 0x53, 0x22, 0x20, 0x42, 0x41, 0x53, 0x49, 0x53,
-  0x2C, 0x81, 0x00, 0x44, 0x1E, 0x57, 0x49, 0x54, 0x48, 0x4F, 0x55, 0x54,
-  0x20, 0x57, 0x41, 0x52, 0x52, 0x41, 0x4E, 0x54, 0x49, 0x45, 0x53, 0x20,
-  0x4F, 0x52, 0x20, 0x43, 0x4F, 0x4E, 0x44, 0x49, 0x54, 0x49, 0x4F, 0x4E,
-  0x80, 0x00, 0x0D, 0x0C, 0x46, 0x20, 0x41, 0x4E, 0x59, 0x20, 0x4B, 0x49,
-  0x4E, 0x44, 0x2C, 0x20, 0x65, 0x80, 0x01, 0x32, 0x80, 0x00, 0x67, 0x03,
-  0x65, 0x78, 0x70, 0x72, 0x81, 0x00, 0xC1, 0x80, 0x00, 0xA6, 0x00, 0x69,
-  0x81, 0x01, 0x4E, 0x01, 0x65, 0x64, 0x82, 0x01, 0x3B, 0x02, 0x53, 0x65,
-  0x65, 0x8A, 0x00, 0x82, 0x01, 0x66, 0x6F, 0x83, 0x00, 0x92, 0x07, 0x73,
-  0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x80, 0x00, 0xDA, 0x0C, 0x6E,
-  0x67, 0x75, 0x61, 0x67, 0x65, 0x20, 0x67, 0x6F, 0x76, 0x65, 0x72, 0x6E,
-  0x80, 0x00, 0xD1, 0x06, 0x20, 0x70, 0x65, 0x72, 0x6D, 0x69, 0x73, 0x81,
-  0x01, 0xD6, 0x00, 0x73, 0x80, 0x00, 0xA0, 0x00, 0x64, 0x81, 0x00, 0x46,
-  0x06, 0x6C, 0x69, 0x6D, 0x69, 0x74, 0x61, 0x74, 0x82, 0x00, 0x12, 0x8E,
-  0x00, 0xD7, 0x01, 0x2E, 0x0A, 0xFF, 0x81};
-
-// The following is a sequence of bits starting from the top right and ends in
-// bottom left. It represents the bits in |kDeflate11|. Bits inside the brackets
-// (including bits exactly under brackets) represent a deflate stream.
-//
-//       }   {                  } {                  }{                  }
-// 11000101 10000000 10001100 01010000 00010001 10001000 00000100 01100010
-//   0xC5     0x80     0x8C     0x50     0x11     0x88     0x04     0x62
-//
-//      }         {                  } {                  }   {
-// 10001011 11111100 00000100 01100010 00000001 00011000 10111000 00001000
-//   0x8B     0xFC     0x04     0x62     0x01     0x18     0xB8     0x08
-//
-//      }   {                  }         {                  }{
-// 10001011 00000001 00011000 10111111 11000000 01000110 00100000 00010001
-//   0x8B     0x01     0x18     0xBF     0xC0     0x46     0x20     0x11
-//
-//       {                  }          {                  }  {
-// 11111100 00000100 01100010 11111111 00000001 00011000 10110000 00010001
-//   0xFC     0x04     0x62     0xFF     0x01     0x18     0xB0     0x11
-//
-const Buffer kDeflate11 = {
-  0x62, 0x04, 0x88, 0x11, 0x50, 0x8C, 0x80, 0xC5, 0x08, 0xB8, 0x18, 0x01,
-  0x62, 0x04, 0xFC, 0x8B, 0x11, 0x20, 0x46, 0xC0, 0xBF, 0x18, 0x01, 0x8B,
-  0x11, 0xB0, 0x18, 0x01, 0xFF, 0x62, 0x04, 0xFC};
-
-const Buffer kPuff11 = {
-  /* puff  0  */ 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,
-  /* puff  7  */ 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,
-  /* raw   14 */ 0x01,
-  /* puff  15 */ 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,
-  /* raw   22 */ 0x01, 0x01,
-  /* puff  24 */ 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,
-  /* raw   31 */ 0x07,
-  /* puff  32 */ 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,
-  /* puff  39 */ 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,
-  /* raw   46 */ 0x3F, 0x03,
-  /* puff  48 */ 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,
-  /* puff  55 */ 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,
-  /* raw   62 */ 0x03, 0x3F,
-  /* puff  64 */ 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,
-  /* raw   71 */ 0x03,
-  /* puff  72 */ 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,
-  /* raw   79 */ 0x03,
-  /* puff  80 */ 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,
-  /* raw   87 */ 0xFF,
-  /* puff  88 */ 0x00, 0x00, 0x20, 0x00, 0x01, 0xFF, 0x81,
-  /* raw   95 */ 0x3F};
-
-// The fifth deflate (and its puff in kPuffExtents11) is for zero length deflate
-// corner case.
-const std::vector<BitExtent> kSubblockDeflateExtents11 = {
-  {0, 18}, {18, 18}, {37, 18}, {57, 18}, {75, 0}, {78, 18}, {96, 18}, {122, 18},
-  {140, 18}, {166, 18}, {186, 18}, {206, 18}, {232, 18}};
-
-const std::vector<ByteExtent> kPuffExtents11 = {
-  {0, 7}, {7, 7}, {15, 7}, {24, 7}, {31, 0}, {32, 7}, {39, 7}, {48, 7}, {55, 7},
-  {64, 7}, {72, 7}, {80, 7}, {88, 7}};
-
-// clang-format on
+extern const Buffer kDeflatesSample2;
+extern const Buffer kPuffsSample2;
+extern const std::vector<ByteExtent> kDeflateExtentsSample2;
+extern const std::vector<BitExtent> kSubblockDeflateExtentsSample2;
+extern const std::vector<ByteExtent> kPuffExtentsSample2;
 
 }  // namespace puffin
 
diff --git a/src/utils.cc b/src/utils.cc
index 5019d0b..668ec3f 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -6,19 +6,22 @@
 
 #include <inttypes.h>
 
+#include <algorithm>
+#include <set>
 #include <string>
 #include <vector>
 
-#include <zlib.h>
-
 #include "puffin/src/bit_reader.h"
 #include "puffin/src/file_stream.h"
 #include "puffin/src/include/puffin/common.h"
-#include "puffin/src/include/puffin/errors.h"
 #include "puffin/src/include/puffin/puffer.h"
+#include "puffin/src/logging.h"
 #include "puffin/src/memory_stream.h"
 #include "puffin/src/puff_writer.h"
-#include "puffin/src/set_errors.h"
+
+using std::set;
+using std::string;
+using std::vector;
 
 namespace {
 // Use memcpy to access the unaligned data of type |T|.
@@ -29,62 +32,62 @@
   return result;
 }
 
-// Calculate both the compressed size and uncompressed size of the deflate
-// block that starts from the offset |start| of buffer |data|.
-bool CalculateSizeOfDeflateBlock(const puffin::Buffer& data,
-                                 uint64_t start,
-                                 uint64_t* compressed_size,
-                                 uint64_t* uncompressed_size) {
-  TEST_AND_RETURN_FALSE(compressed_size != nullptr &&
-                        uncompressed_size != nullptr);
+struct ExtentData {
+  puffin::BitExtent extent;
+  uint64_t byte_offset;
+  uint64_t byte_length;
+  const puffin::Buffer& data;
 
-  TEST_AND_RETURN_FALSE(start < data.size());
-
-  z_stream strm = {};
-  strm.avail_in = data.size() - start;
-  strm.next_in = data.data() + start;
-
-  // -15 means we are decoding a 'raw' stream without zlib headers.
-  if (inflateInit2(&strm, -15)) {
-    LOG(ERROR) << "Failed to initialize inflate: " << strm.msg;
-    return false;
+  ExtentData(const puffin::BitExtent& in_extent, const puffin::Buffer& in_data)
+      : extent(in_extent), data(in_data) {
+    // Round start offset up and end offset down to exclude bits not in this
+    // extent. We simply ignore the bits at start and end that's not on byte
+    // boundary because as long as the majority of the bytes are the same,
+    // bsdiff will be able to reference it.
+    byte_offset = (extent.offset + 7) / 8;
+    uint64_t byte_end_offset = (extent.offset + extent.length) / 8;
+    CHECK(byte_end_offset <= data.size());
+    if (byte_end_offset > byte_offset) {
+      byte_length = byte_end_offset - byte_offset;
+    } else {
+      byte_length = 0;
+    }
   }
 
-  const unsigned int kBufferSize = 32768;
-  std::vector<uint8_t> uncompressed_data(kBufferSize);
-  *uncompressed_size = 0;
-  int status = Z_OK;
-  do {
-    // Overwrite the same buffer since we don't need the uncompressed data.
-    strm.avail_out = kBufferSize;
-    strm.next_out = uncompressed_data.data();
-    status = inflate(&strm, Z_NO_FLUSH);
-    if (status < 0) {
-      LOG(ERROR) << "Inflate failed: " << strm.msg << ", has decompressed "
-                 << *uncompressed_size << " bytes.";
-      return false;
+  int Compare(const ExtentData& other) const {
+    if (extent.length != other.extent.length) {
+      return extent.length < other.extent.length ? -1 : 1;
     }
-    *uncompressed_size += kBufferSize - strm.avail_out;
-  } while (status != Z_STREAM_END);
-
-  *compressed_size = data.size() - start - strm.avail_in;
-  TEST_AND_RETURN_FALSE(inflateEnd(&strm) == Z_OK);
-  return true;
-}
+    return memcmp(data.data() + byte_offset,
+                  other.data.data() + other.byte_offset,
+                  std::min(byte_length, other.byte_length));
+  }
+  bool operator<(const ExtentData& other) const { return Compare(other) < 0; }
+  bool operator==(const ExtentData& other) const { return Compare(other) == 0; }
+};
 
 }  // namespace
 
 namespace puffin {
 
-using std::string;
-using std::vector;
-
-uint64_t BytesInByteExtents(const vector<ByteExtent>& extents) {
-  uint64_t bytes = 0;
-  for (const auto& extent : extents) {
-    bytes += extent.length;
+bool LocateDeflatesInDeflateStream(const uint8_t* data,
+                                   uint64_t size,
+                                   uint64_t virtual_offset,
+                                   vector<BitExtent>* deflates,
+                                   uint64_t* compressed_size) {
+  Puffer puffer;
+  BufferBitReader bit_reader(data, size);
+  BufferPuffWriter puff_writer(nullptr, 0);
+  vector<BitExtent> sub_deflates;
+  TEST_AND_RETURN_FALSE(
+      puffer.PuffDeflate(&bit_reader, &puff_writer, &sub_deflates));
+  for (const auto& deflate : sub_deflates) {
+    deflates->emplace_back(deflate.offset + virtual_offset * 8, deflate.length);
   }
-  return bytes;
+  if (compressed_size) {
+    *compressed_size = bit_reader.Offset();
+  }
+  return true;
 }
 
 // This function uses RFC1950 (https://www.ietf.org/rfc/rfc1950.txt) for the
@@ -93,7 +96,7 @@
 // stream should be known before hand. Otherwise we need to parse the stream and
 // find the location of compressed blocks using CalculateSizeOfDeflateBlock().
 bool LocateDeflatesInZlib(const Buffer& data,
-                          std::vector<ByteExtent>* deflate_blocks) {
+                          std::vector<BitExtent>* deflates) {
   // A zlib stream has the following format:
   // 0           1     compression method and flag
   // 1           1     flag
@@ -119,7 +122,9 @@
   }
 
   // 4 is for ADLER32.
-  deflate_blocks->emplace_back(header_len, data.size() - header_len - 4);
+  TEST_AND_RETURN_FALSE(LocateDeflatesInDeflateStream(
+      data.data() + header_len, data.size() - header_len - 4, header_len,
+      deflates, nullptr));
   return true;
 }
 
@@ -136,11 +141,13 @@
 
     // Find all the subblocks.
     BufferBitReader bit_reader(deflate_buffer.data(), deflate.length);
+    // The uncompressed blocks will be ignored since we are passing a null
+    // buffered puff writer and a valid deflate locations output array. This
+    // should not happen in the puffdiff or anywhere else by default.
     BufferPuffWriter puff_writer(nullptr, 0);
-    Error error;
     vector<BitExtent> subblocks;
     TEST_AND_RETURN_FALSE(
-        puffer.PuffDeflate(&bit_reader, &puff_writer, &subblocks, &error));
+        puffer.PuffDeflate(&bit_reader, &puff_writer, &subblocks));
     TEST_AND_RETURN_FALSE(deflate.length == bit_reader.Offset());
     for (const auto& subblock : subblocks) {
       subblock_deflates->emplace_back(subblock.offset + deflate.offset * 8,
@@ -157,22 +164,14 @@
   TEST_AND_RETURN_FALSE(src);
 
   Buffer buffer;
-  for (auto& zlib : zlibs) {
+  for (const auto& zlib : zlibs) {
     buffer.resize(zlib.length);
     TEST_AND_RETURN_FALSE(src->Seek(zlib.offset));
     TEST_AND_RETURN_FALSE(src->Read(buffer.data(), buffer.size()));
-
-    vector<ByteExtent> deflate_blocks;
-    TEST_AND_RETURN_FALSE(LocateDeflatesInZlib(buffer, &deflate_blocks));
-
-    vector<BitExtent> deflate_subblocks;
-    auto zlib_blc_src = MemoryStream::CreateForRead(buffer);
-    TEST_AND_RETURN_FALSE(
-        FindDeflateSubBlocks(zlib_blc_src, deflate_blocks, &deflate_subblocks));
-
-    // Relocated based on the offset of the zlib.
-    for (const auto& def : deflate_subblocks) {
-      deflates->emplace_back(zlib.offset * 8 + def.offset, def.length);
+    vector<BitExtent> tmp_deflates;
+    TEST_AND_RETURN_FALSE(LocateDeflatesInZlib(buffer, &tmp_deflates));
+    for (const auto& deflate : tmp_deflates) {
+      deflates->emplace_back(deflate.offset + zlib.offset * 8, deflate.length);
     }
   }
   return true;
@@ -180,8 +179,7 @@
 
 // For more information about gzip format, refer to RFC 1952 located at:
 // https://www.ietf.org/rfc/rfc1952.txt
-bool LocateDeflatesInGzip(const Buffer& data,
-                          vector<ByteExtent>* deflate_blocks) {
+bool LocateDeflatesInGzip(const Buffer& data, vector<BitExtent>* deflates) {
   uint64_t member_start = 0;
   while (member_start < data.size()) {
     // Each member entry has the following format
@@ -230,21 +228,15 @@
       offset += 2;
     }
 
-    uint64_t compressed_size, uncompressed_size;
-    TEST_AND_RETURN_FALSE(CalculateSizeOfDeflateBlock(
-        data, offset, &compressed_size, &uncompressed_size));
-    TEST_AND_RETURN_FALSE(offset + compressed_size <= data.size());
-    deflate_blocks->push_back(ByteExtent(offset, compressed_size));
+    uint64_t compressed_size = 0;
+    TEST_AND_RETURN_FALSE(LocateDeflatesInDeflateStream(
+        data.data() + offset, data.size() - offset, offset, deflates,
+        &compressed_size));
     offset += compressed_size;
 
-    // Ignore CRC32;
+    // Ignore CRC32 and uncompressed size.
     TEST_AND_RETURN_FALSE(offset + 8 <= data.size());
-    offset += 4;
-    uint32_t u_size = 0;
-    for (size_t i = 0; i < 4; i++) {
-      u_size |= static_cast<uint32_t>(data[offset++]) << (i * 8);
-    }
-    TEST_AND_RETURN_FALSE(uncompressed_size % (1 << 31) == u_size);
+    offset += 8;
     member_start = offset;
   }
   return true;
@@ -253,7 +245,7 @@
 // For more information about the zip format, refer to
 // https://support.pkware.com/display/PKZIP/APPNOTE
 bool LocateDeflatesInZipArchive(const Buffer& data,
-                                vector<ByteExtent>* deflate_blocks) {
+                                vector<BitExtent>* deflates) {
   uint64_t pos = 0;
   while (pos <= data.size() - 30) {
     // TODO(xunchang) add support for big endian system when searching for
@@ -283,7 +275,6 @@
     }
 
     auto compressed_size = get_unaligned<uint32_t>(data.data() + pos + 18);
-    auto uncompressed_size = get_unaligned<uint32_t>(data.data() + pos + 22);
     auto file_name_length = get_unaligned<uint16_t>(data.data() + pos + 26);
     auto extra_field_length = get_unaligned<uint16_t>(data.data() + pos + 28);
     uint64_t header_size = 30 + file_name_length + extra_field_length;
@@ -295,33 +286,26 @@
       continue;
     }
 
-    uint64_t calculated_compressed_size;
-    uint64_t calculated_uncompressed_size;
-    if (!CalculateSizeOfDeflateBlock(data, pos + header_size,
-                                     &calculated_compressed_size,
-                                     &calculated_uncompressed_size)) {
+    vector<BitExtent> tmp_deflates;
+    uint64_t offset = pos + header_size;
+    uint64_t calculated_compressed_size = 0;
+    if (!LocateDeflatesInDeflateStream(
+            data.data() + offset, data.size() - offset, offset, &tmp_deflates,
+            &calculated_compressed_size)) {
       LOG(ERROR) << "Failed to decompress the zip entry starting from: " << pos
                  << ", skip adding deflates for this entry.";
       pos += 4;
       continue;
     }
 
-    // Double check the compressed size and uncompressed size if they are
-    // available in the file header.
+    // Double check the compressed size if it is available in the file header.
     if (compressed_size > 0 && compressed_size != calculated_compressed_size) {
       LOG(WARNING) << "Compressed size in the file header: " << compressed_size
                    << " doesn't equal the real size: "
                    << calculated_compressed_size;
     }
 
-    if (uncompressed_size > 0 &&
-        uncompressed_size != calculated_uncompressed_size) {
-      LOG(WARNING) << "Uncompressed size in the file header: "
-                   << uncompressed_size << " doesn't equal the real size: "
-                   << calculated_uncompressed_size;
-    }
-
-    deflate_blocks->emplace_back(pos + header_size, calculated_compressed_size);
+    deflates->insert(deflates->end(), tmp_deflates.begin(), tmp_deflates.end());
     pos += header_size + calculated_compressed_size;
   }
 
@@ -330,13 +314,7 @@
 
 bool LocateDeflateSubBlocksInZipArchive(const Buffer& data,
                                         vector<BitExtent>* deflates) {
-  vector<ByteExtent> deflate_blocks;
-  if (!LocateDeflatesInZipArchive(data, &deflate_blocks)) {
-    return false;
-  }
-
-  auto src = MemoryStream::CreateForRead(data);
-  return FindDeflateSubBlocks(src, deflate_blocks, deflates);
+  return LocateDeflatesInZipArchive(data, deflates);
 }
 
 bool FindPuffLocations(const UniqueStreamPtr& src,
@@ -366,9 +344,8 @@
     bit_reader.DropBits(bits_to_skip);
 
     BufferPuffWriter puff_writer(nullptr, 0);
-    Error error;
     TEST_AND_RETURN_FALSE(
-        puffer.PuffDeflate(&bit_reader, &puff_writer, nullptr, &error));
+        puffer.PuffDeflate(&bit_reader, &puff_writer, nullptr));
     TEST_AND_RETURN_FALSE(deflate_buffer.size() == bit_reader.Offset());
 
     // 1 if a deflate ends at the same byte that the next deflate starts and
@@ -409,4 +386,31 @@
   return true;
 }
 
+void RemoveEqualBitExtents(const Buffer& data1,
+                           const Buffer& data2,
+                           std::vector<BitExtent>* extents1,
+                           std::vector<BitExtent>* extents2) {
+  set<ExtentData> extent1_set, equal_extents;
+  for (const BitExtent& ext : *extents1) {
+    extent1_set.emplace(ext, data1);
+  }
+
+  auto new_extents2_end = extents2->begin();
+  for (const BitExtent& ext : *extents2) {
+    ExtentData extent_data(ext, data2);
+    if (extent1_set.find(extent_data) != extent1_set.end()) {
+      equal_extents.insert(extent_data);
+    } else {
+      *new_extents2_end++ = ext;
+    }
+  }
+  extents2->erase(new_extents2_end, extents2->end());
+  extents1->erase(
+      std::remove_if(extents1->begin(), extents1->end(),
+                     [&equal_extents, &data1](const BitExtent& ext) {
+                       return equal_extents.find(ExtentData(ext, data1)) !=
+                              equal_extents.end();
+                     }),
+      extents1->end());
+}
 }  // namespace puffin
diff --git a/src/utils_unittest.cc b/src/utils_unittest.cc
index e1fbb25..737b765 100644
--- a/src/utils_unittest.cc
+++ b/src/utils_unittest.cc
@@ -14,11 +14,11 @@
 #include "puffin/src/memory_stream.h"
 #include "puffin/src/unittest_common.h"
 
-namespace puffin {
-
 using std::string;
 using std::vector;
 
+namespace puffin {
+
 namespace {
 const uint8_t kZipEntries[] = {
     0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0xfc, 0x88,
@@ -79,9 +79,9 @@
 
 // echo "0123456789" | zlib-flate -compress |
 // hexdump -v -e '12/1 "0x%02x, " "\n"'
-const uint8_t kZlibEntry[] = {
-    0x78, 0x9c, 0x33, 0x30, 0x34, 0x32, 0x36, 0x31, 0x35, 0x33, 0xb7, 0xb0,
-    0xe4, 0x02, 0x00, 0x0d, 0x17, 0x02, 0x18};
+const uint8_t kZlibEntry[] = {0x78, 0x9c, 0x33, 0x30, 0x34, 0x32, 0x36,
+                              0x31, 0x35, 0x33, 0xb7, 0xb0, 0xe4, 0x02,
+                              0x00, 0x0d, 0x17, 0x02, 0x18};
 
 void FindDeflatesInZlibBlocks(const Buffer& src,
                               const vector<ByteExtent>& zlibs,
@@ -114,21 +114,21 @@
 
 // Test Simple Puffing of the source.
 TEST(UtilsTest, FindPuffLocations1Test) {
-  CheckFindPuffLocation(kDeflates8, kSubblockDeflateExtents8, kPuffExtents8,
-                        kPuffs8.size());
+  CheckFindPuffLocation(kDeflatesSample1, kSubblockDeflateExtentsSample1,
+                        kPuffExtentsSample1, kPuffsSample1.size());
 }
 
 TEST(UtilsTest, FindPuffLocations2Test) {
-  CheckFindPuffLocation(kDeflates9, kSubblockDeflateExtents9, kPuffExtents9,
-                        kPuffs9.size());
+  CheckFindPuffLocation(kDeflatesSample2, kSubblockDeflateExtentsSample2,
+                        kPuffExtentsSample2, kPuffsSample2.size());
 }
 
 TEST(UtilsTest, LocateDeflatesInZlib) {
   Buffer zlib_data(kZlibEntry, std::end(kZlibEntry));
-  vector<ByteExtent> deflates;
+  vector<BitExtent> deflates;
+  vector<BitExtent> expected_deflates = {{16, 98}};
   EXPECT_TRUE(LocateDeflatesInZlib(zlib_data, &deflates));
-  EXPECT_EQ(static_cast<size_t>(1), deflates.size());
-  EXPECT_EQ(ByteExtent(2, 13), deflates[0]);
+  EXPECT_EQ(deflates, expected_deflates);
 }
 
 TEST(UtilsTest, LocateDeflatesInEmptyZlib) {
@@ -143,7 +143,7 @@
   auto cmf = zlib_data[0];
   auto flag = zlib_data[1];
 
-  vector<ByteExtent> deflates;
+  vector<BitExtent> deflates;
   zlib_data[0] = cmf & 0xF0;
   EXPECT_FALSE(LocateDeflatesInZlib(zlib_data, &deflates));
   zlib_data[0] = cmf | (8 << 4);
@@ -156,55 +156,72 @@
 
 TEST(UtilsTest, LocateDeflatesInZipArchiveSmoke) {
   Buffer zip_entries(kZipEntries, std::end(kZipEntries));
-  vector<ByteExtent> deflates;
+  vector<BitExtent> deflates;
+  vector<BitExtent> expected_deflates = {{472, 46}, {992, 46}};
   EXPECT_TRUE(LocateDeflatesInZipArchive(zip_entries, &deflates));
-  EXPECT_EQ(static_cast<size_t>(2), deflates.size());
-  EXPECT_EQ(ByteExtent(59, 6), deflates[0]);
-  EXPECT_EQ(ByteExtent(124, 6), deflates[1]);
+  EXPECT_EQ(deflates, expected_deflates);
 }
 
 TEST(UtilsTest, LocateDeflatesInZipArchiveWithDataDescriptor) {
   Buffer zip_entries(kZipEntryWithDataDescriptor,
                      std::end(kZipEntryWithDataDescriptor));
-  vector<ByteExtent> deflates;
+  vector<BitExtent> deflates;
+  vector<BitExtent> expected_deflates = {{472, 46}, {1120, 46}};
   EXPECT_TRUE(LocateDeflatesInZipArchive(zip_entries, &deflates));
-  EXPECT_EQ(static_cast<size_t>(2), deflates.size());
-  EXPECT_EQ(ByteExtent(59, 6), deflates[0]);
-  EXPECT_EQ(ByteExtent(140, 6), deflates[1]);
+  EXPECT_EQ(deflates, expected_deflates);
 }
 
 TEST(UtilsTest, LocateDeflatesInZipArchiveErrorChecks) {
   Buffer zip_entries(kZipEntries, std::end(kZipEntries));
   // Construct a invalid zip entry whose size overflows.
   zip_entries[29] = 0xff;
-  vector<ByteExtent> deflates_overflow;
+  vector<BitExtent> deflates_overflow;
+  vector<BitExtent> expected_deflates = {{992, 46}};
   EXPECT_TRUE(LocateDeflatesInZipArchive(zip_entries, &deflates_overflow));
-  EXPECT_EQ(static_cast<size_t>(1), deflates_overflow.size());
-  EXPECT_EQ(ByteExtent(124, 6), deflates_overflow[0]);
+  EXPECT_EQ(deflates_overflow, expected_deflates);
 
   zip_entries.resize(128);
-  vector<ByteExtent> deflates_incomplete;
+  vector<BitExtent> deflates_incomplete;
   EXPECT_TRUE(LocateDeflatesInZipArchive(zip_entries, &deflates_incomplete));
-  EXPECT_EQ(static_cast<size_t>(0), deflates_incomplete.size());
+  EXPECT_TRUE(deflates_incomplete.empty());
 }
 
 TEST(UtilsTest, LocateDeflatesInGzip) {
   Buffer gzip_data(kGzipEntryWithMultipleMembers,
                    std::end(kGzipEntryWithMultipleMembers));
-  vector<ByteExtent> deflates;
+  vector<BitExtent> deflates;
+  vector<BitExtent> expected_deflates = {{160, 98}, {488, 98}};
   EXPECT_TRUE(LocateDeflatesInGzip(gzip_data, &deflates));
-  EXPECT_EQ(static_cast<size_t>(2), deflates.size());
-  EXPECT_EQ(ByteExtent(20, 13), deflates[0]);
-  EXPECT_EQ(ByteExtent(61, 13), deflates[1]);
+  EXPECT_EQ(deflates, expected_deflates);
 }
 
 TEST(UtilsTest, LocateDeflatesInGzipWithExtraField) {
   Buffer gzip_data(kGzipEntryWithExtraField,
                    std::end(kGzipEntryWithExtraField));
-  vector<ByteExtent> deflates;
+  vector<BitExtent> deflates;
+  vector<BitExtent> expected_deflates = {{256, 98}};
   EXPECT_TRUE(LocateDeflatesInGzip(gzip_data, &deflates));
-  EXPECT_EQ(static_cast<size_t>(1), deflates.size());
-  EXPECT_EQ(ByteExtent(32, 13), deflates[0]);
+  EXPECT_EQ(deflates, expected_deflates);
+}
+
+TEST(UtilsTest, RemoveEqualBitExtents) {
+  Buffer data1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+  Buffer data2 = {1, 2, 3, 4, 5, 5, 6, 7, 8, 9};
+  vector<BitExtent> ext1 = {{0, 10}, {10, 14}, {25, 15}, {40, 8}, {50, 23}};
+  vector<BitExtent> ext2 = {{0, 10}, {17, 15}, {32, 8}, {40, 8}, {50, 23}};
+  RemoveEqualBitExtents(data1, data2, &ext1, &ext2);
+  vector<BitExtent> expected_ext1 = {{0, 10}, {10, 14}};
+  EXPECT_EQ(expected_ext1, ext1);
+  vector<BitExtent> expected_ext2 = {{0, 10}};
+  EXPECT_EQ(expected_ext2, ext2);
+  RemoveEqualBitExtents(data1, data2, &ext1, &ext1);
+  EXPECT_EQ(expected_ext1, ext1);
+  RemoveEqualBitExtents(data1, data1, &ext1, &ext1);
+  EXPECT_TRUE(ext1.empty());
+  expected_ext1 = ext1 = {{0, 0}, {1, 1}, {2, 7}};
+  RemoveEqualBitExtents(data1, data2, &ext1, &ext2);
+  EXPECT_EQ(expected_ext1, ext1);
+  EXPECT_EQ(expected_ext2, ext2);
 }
 
 }  // namespace puffin